Added initial built-in matchers for NSString (ObjC)
diff --git a/include/internal/catch_capture.hpp b/include/internal/catch_capture.hpp
index 5cd4184..dbc1ffb 100644
--- a/include/internal/catch_capture.hpp
+++ b/include/internal/catch_capture.hpp
@@ -53,6 +53,32 @@
         return oss.str();
     }    
 
+    template<typename T>
+    inline std::string makeString
+    (
+        T* p
+    )
+    {
+        if( !p )
+            return INTERNAL_CATCH_STRINGIFY( NULL );
+        std::ostringstream oss;
+        oss << p;
+        return oss.str();
+    }    
+
+    template<typename T>
+    inline std::string makeString
+    (
+        const T* p
+    )
+    {
+        if( !p )
+            return INTERNAL_CATCH_STRINGIFY( NULL );
+        std::ostringstream oss;
+        oss << p;
+        return oss.str();
+    }    
+
 }// end namespace Detail
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -166,39 +192,6 @@
 {
     return value ? "true" : "false";
 }
-
-///////////////////////////////////////////////////////////////////////////////
-inline std::string toString
-(
-    void* p
-)
-{
-    if( !p )
-        return INTERNAL_CATCH_STRINGIFY( NULL );
-    std::ostringstream oss;
-    oss << p;
-    return oss.str();
-}
-    
-///////////////////////////////////////////////////////////////////////////////
-template<typename T>
-inline std::string toString
-(
-    T* p
-)
-{
-    return Catch::toString( static_cast<void*>( p ) );
-}
-    
-///////////////////////////////////////////////////////////////////////////////
-template<typename T>
-inline std::string toString
-(
-    const T* p
-)
-{
-    return Catch::toString( static_cast<void*>( const_cast<T*>( p ) ) );
-}
     
 struct TestFailureException
 {
diff --git a/include/internal/catch_objc.hpp b/include/internal/catch_objc.hpp
index a226178..a36d955 100644
--- a/include/internal/catch_objc.hpp
+++ b/include/internal/catch_objc.hpp
@@ -171,8 +171,93 @@
             }
         }
         return noTestMethods;
-    }  
-}
+    }
+    
+    template<>
+    inline std::string toString<NSString*>( NSString* const& nsstring )
+    {
+        return std::string( "@\"" ) + [nsstring UTF8String] + "\"";
+    }
+    
+    namespace Matchers
+    {
+        namespace Impl
+        {
+        namespace NSStringMatchers
+        {
+            struct StringHolder
+            {
+                StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
+                StringHolder()
+                {
+                    [m_substr release];
+                }
+                
+                NSString* m_substr;            
+            };
+            
+            struct Contains : StringHolder
+            {
+                Contains( NSString* substr ) : StringHolder( substr ){}
+                
+                bool operator()( NSString* str ) const
+                {
+                    return [str rangeOfString:m_substr].location != NSNotFound;
+                }
+                
+                friend std::ostream& operator<<( std::ostream& os, const Contains& matcher )
+                {
+                    os << "contains: " << Catch::toString( matcher.m_substr );
+                    return os;
+                }
+            };
+
+            struct StartsWith : StringHolder
+            {
+                StartsWith( NSString* substr ) : StringHolder( substr ){}
+                
+                bool operator()( NSString* str ) const
+                {
+                    return [str rangeOfString:m_substr].location == 0;
+                }
+                
+                friend std::ostream& operator<<( std::ostream& os, const StartsWith& matcher )
+                {
+                    os << "starts with: " << Catch::toString( matcher.m_substr );
+                    return os;
+                }
+            };
+            struct EndsWith : StringHolder
+            {
+                EndsWith( NSString* substr ) : StringHolder( substr ){}
+                
+                bool operator()( NSString* str ) const
+                {
+                    return [str rangeOfString:m_substr].location == [str length] - [m_substr length];
+                }
+                
+                friend std::ostream& operator<<( std::ostream& os, const EndsWith& matcher )
+                {
+                    os << "ends with: " << Catch::toString( matcher.m_substr );
+                    return os;
+                }
+            };
+            
+        } // namespace NSStringMatchers
+        } // namespace Impl
+        
+        inline Impl::NSStringMatchers::Contains
+            Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
+        inline Impl::NSStringMatchers::StartsWith
+            StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
+        inline Impl::NSStringMatchers::EndsWith
+            EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
+        
+    } // namespace Matchers
+    
+    using namespace Matchers;
+    
+} // namespace Catch
 
 ///////////////////////////////////////////////////////////////////////////////
 #define OC_TEST_CASE( name, desc )\