diff --git a/client/dbclient.h b/client/dbclient.h index dc81aa89195..30f842fe267 100644 --- a/client/dbclient.h +++ b/client/dbclient.h @@ -111,9 +111,7 @@ namespace mongo { Query& where(const char *jscode) { return where(jscode, BSONObj()); } string toString() const; - static string toString( void *o ) { - return ( (Query*) o )->toString(); - } + operator string() const { return toString(); } }; /** Typically one uses the QUERY(...) macro to construct a Query object. diff --git a/db/jsobj.h b/db/jsobj.h index 2b44d2c9737..23a95f3f1d8 100644 --- a/db/jsobj.h +++ b/db/jsobj.h @@ -502,9 +502,7 @@ namespace mongo { This is an abbreviated representation which might be used for logging. */ string toString() const; - static string toString( void *o ) { - return ( (BSONObj*) o )->toString(); - } + operator string() const { return toString(); } /** Properly formatted JSON string. */ string jsonString( JsonStringFormat format = Strict ) const; diff --git a/s/shard.h b/s/shard.h index 02b53d4ae9f..bffe6cdfc9c 100644 --- a/s/shard.h +++ b/s/shard.h @@ -53,9 +53,7 @@ namespace mongo { void split( const BSONObj& middle ); string toString() const; - static string toString( void *o ) { - return ( (Shard*) o )->toString(); - } + operator string() const { return toString(); } bool operator==(const Shard& s); @@ -106,9 +104,7 @@ namespace mongo { bool loadByName( const string& ns ); string toString() const; - static string toString( void *o ) { - return ( (ShardInfo*) o )->toString(); - } + operator string() const { return toString(); } private: DBConfig * _config; diff --git a/stdafx.h b/stdafx.h index 6b79f5287da..43d0e531886 100644 --- a/stdafx.h +++ b/stdafx.h @@ -70,12 +70,6 @@ using namespace std; namespace mongo { - class Stringable { - public: - virtual ~Stringable() throw() {} - virtual string toString() const = 0; - }; - /* these are manipulated outside of mutexes, so be careful */ struct Assertion { Assertion() { @@ -113,12 +107,13 @@ namespace mongo { /* last assert of diff types: regular, wassert, msgassert, uassert: */ extern Assertion lastAssert[4]; - class DBException : public exception, public Stringable { + class DBException : public exception { public: virtual const char* what() const throw() = 0; virtual string toString() const { return what(); } + operator string() const { return toString(); } }; class AssertionException : public DBException { diff --git a/util/log.h b/util/log.h index 34ce090a3ff..c5d722d044d 100644 --- a/util/log.h +++ b/util/log.h @@ -20,22 +20,33 @@ namespace mongo { - // If you don't want your class to inherit from Stringable (for example, if - // you don't want a virtual destructor) then add a function like the - // following to your class, which takes a pointer to an object of your class - // type: - // static string toString( void * ); class LazyString { public: - // LazyString is designed to be used in situations where the lifespan of - // a temporary object used to construct a LazyString completely includes - // the lifespan of the LazyString object itself. template< class T > - LazyString( const T &t ) : obj_( (void*)&t ), fun_( &T::toString ) {} - string val() const { return (*fun_)(obj_); } + LazyString( const T& t ) { + if ( sizeof( Stringifier< T > ) > ( sizeof( Stringifier< unsigned > ) * 2 ) ) { + stringifier_ = &stringifierError_; + } else { + stringifier_ = new ( stringifierBuf_ ) Stringifier< T >( t ); + } + } + string val() const { return stringifier_->val(); } private: - void *obj_; - string (*fun_) (void *); + struct StringifierBase { + virtual ~StringifierBase() {} + virtual string val() const = 0; + }; + template< class T > + struct Stringifier : public StringifierBase { + Stringifier( const T& t ) : t_( t ) {} + virtual string val() const { return string( t_ ); } + const T& t_; + }; + static struct StringifierError : public StringifierBase { + virtual string val() const { return "Error converting to string"; } + } stringifierError_; + StringifierBase *stringifier_; + char stringifierBuf_[ sizeof( Stringifier< unsigned > ) * 2 ]; }; class Nullstream { @@ -72,15 +83,9 @@ namespace mongo { virtual Nullstream& operator<<(unsigned long long) { return *this; } - virtual Nullstream& operator<<(const string&) { - return *this; - } virtual Nullstream& operator<<(const LazyString&) { return *this; } - virtual Nullstream& operator<<(const Stringable&) { - return *this; - } virtual Nullstream& operator<< (ostream& ( *endl )(ostream&)) { return *this; } @@ -109,17 +114,11 @@ namespace mongo { Logstream& operator<<(void *x) LOGIT Logstream& operator<<(long long x) LOGIT Logstream& operator<<(unsigned long long x) LOGIT - Logstream& operator<<(const string& x) LOGIT Logstream& operator<<(const LazyString& x) { boostlock lk(mutex); cout << x.val(); return *this; } - Logstream& operator<<(const Stringable& x) { - boostlock lk(mutex); - cout << x.toString(); - return *this; - } Logstream& operator<< (ostream& ( *_endl )(ostream&)) { boostlock lk(mutex); cout << _endl;