diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2012-03-02 12:34:54 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2012-03-02 12:34:54 +0200 |
commit | 8a9e1081c026a092c7dfb28fbd079b88850c7233 (patch) | |
tree | f44ba71ea18365b8d9c1a97c09b624a0c4d150dc | |
parent | 0f25b194dcbcfa95a80284069999dd92341ce36d (diff) |
Portability workarounds for incomplete C++11 support in VC++ and old GCC
-rw-r--r-- | odb/details/config-vc.h | 8 | ||||
-rw-r--r-- | odb/details/config.hxx | 18 | ||||
-rw-r--r-- | odb/details/transfer-ptr.hxx | 2 | ||||
-rw-r--r-- | odb/lazy-ptr.hxx | 63 | ||||
-rw-r--r-- | odb/lazy-ptr.ixx | 46 | ||||
-rw-r--r-- | odb/tr1/lazy-ptr.hxx | 6 | ||||
-rw-r--r-- | odb/tr1/pointer-traits.hxx | 9 | ||||
-rw-r--r-- | odb/tr1/wrapper-traits.hxx | 9 |
8 files changed, 133 insertions, 28 deletions
diff --git a/odb/details/config-vc.h b/odb/details/config-vc.h index 6b1da9e..56d69e7 100644 --- a/odb/details/config-vc.h +++ b/odb/details/config-vc.h @@ -11,10 +11,16 @@ #define ODB_THREADS_WIN32 #define ODB_THREADS_TLS_DECLSPEC -/* VC++10 has C++11 always enabled. +/* VC++10 and later have C++11 always enabled. */ #if _MSC_VER >= 1600 # define ODB_CXX11 +# define ODB_CXX11_NULLPTR +# if _MSC_VER >= 1800 +# define ODB_CXX11_DELETED_FUNCTION +# define ODB_CXX11_EXPLICIT_CONVERSION_OPERATOR +# define ODB_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGUMENT +# endif #endif #endif /* ODB_DETAILS_CONFIG_VC_H */ diff --git a/odb/details/config.hxx b/odb/details/config.hxx index ad0ec27..fc47ec7 100644 --- a/odb/details/config.hxx +++ b/odb/details/config.hxx @@ -14,9 +14,27 @@ # define LIBODB_STATIC_LIB # if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L # define ODB_CXX11 +# if __GNUC__ >= 4 && __GNUC_MINOR__ >= 6 +# define ODB_CXX_NULLPTR +# endif +# define ODB_CXX11_DELETED_FUNCTION +# define ODB_CXX11_EXPLICIT_CONVERSION_OPERATOR +# define ODB_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGUMENT # endif #else # include <odb/details/config.h> +# ifdef ODB_CXX11 +# ifdef __GNUC__ +# if __GNUC__ >= 4 && __GNUC_MINOR__ >= 6 +# define ODB_CXX_NULLPTR +# endif +# else +# define ODB_CXX_NULLPTR +# endif +# define ODB_CXX11_DELETED_FUNCTION +# define ODB_CXX11_EXPLICIT_CONVERSION_OPERATOR +# define ODB_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGUMENT +# endif #endif // no post diff --git a/odb/details/transfer-ptr.hxx b/odb/details/transfer-ptr.hxx index e7ad42c..5481252 100644 --- a/odb/details/transfer-ptr.hxx +++ b/odb/details/transfer-ptr.hxx @@ -27,7 +27,9 @@ namespace odb transfer_ptr (std::auto_ptr<T1> p): p_ (p.release ()) {} #ifdef ODB_CXX11 +#ifdef ODB_CXX11_NULLPTR transfer_ptr (std::nullptr_t): p_ (0) {} +#endif template <typename T1> transfer_ptr (std::unique_ptr<T1>&& p): p_ (p.release ()) {} diff --git a/odb/lazy-ptr.hxx b/odb/lazy-ptr.hxx index 0e44066..12acbb6 100644 --- a/odb/lazy-ptr.hxx +++ b/odb/lazy-ptr.hxx @@ -78,7 +78,7 @@ namespace odb template <class ID> void reset (database_type&, const ID&); template <class Y> void reset (database_type&, Y*); -#ifdef ODB_CXX11 +#ifdef ODB_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGUMENT template <class O = T> #else template <class O /* = T */> @@ -193,7 +193,7 @@ namespace odb void reset (database_type&, T*); template <class Y> void reset (database_type&, std::auto_ptr<Y>&); -#ifdef ODB_CXX11 +#ifdef ODB_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGUMENT template <class O = T> #else template <class O /* = T */> @@ -229,7 +229,9 @@ namespace odb typedef D deleter_type; /*constexpr*/ lazy_unique_ptr () /*noexcept*/; +#ifdef ODB_CXX11_NULLPTR /*constexpr*/ lazy_unique_ptr (std::nullptr_t) /*noexcept*/; +#endif explicit lazy_unique_ptr (pointer) /*noexcept*/; // For now assume D is non-reference. @@ -241,14 +243,24 @@ namespace odb template <class T1, class D1> lazy_unique_ptr (lazy_unique_ptr<T1, D1>&&) /*noexcept*/; template <class T1> lazy_unique_ptr (std::auto_ptr<T1>&&) /*noexcept*/; +#ifdef ODB_CXX11_NULLPTR lazy_unique_ptr& operator= (std::nullptr_t) /*noexcept*/; +#endif lazy_unique_ptr& operator= (lazy_unique_ptr&&) /*noexcept*/; template <class T1, class D1> lazy_unique_ptr& operator= (lazy_unique_ptr<T1, D1>&&) /*noexcept*/; T& operator* () const; pointer operator-> () const /*noexcept*/; pointer get () const /*noexcept*/; +#ifdef ODB_CXX11_EXPLICIT_CONVERSION_OPERATOR explicit operator bool() const /*noexcept*/; +#else + typedef std::unique_ptr<T, D> lazy_unique_ptr::*unspecified_bool_type; + operator unspecified_bool_type () const + { + return (p_ || i_) ? &lazy_unique_ptr::p_ : 0; + } +#endif pointer release () /*noexcept*/; void reset (pointer = pointer ()) /*noexcept*/; @@ -257,8 +269,14 @@ namespace odb deleter_type& get_deleter () /*noexcept*/; const deleter_type& get_deleter () const /*noexcept*/; +#ifdef ODB_CXX11_DELETED_FUNCTION lazy_unique_ptr (const lazy_unique_ptr&) = delete; lazy_unique_ptr& operator= (const lazy_unique_ptr&) = delete; +#else + private: + lazy_unique_ptr (const lazy_unique_ptr&); + lazy_unique_ptr& operator= (const lazy_unique_ptr&); +#endif // Initialization/assignment from unique_ptr. // @@ -299,7 +317,11 @@ namespace odb template <class T1, class D1> void reset (database_type&, std::unique_ptr<T1, D1>&&); template <class T1> void reset (database_type&, std::auto_ptr<T1>&&); +#ifdef ODB_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGUMENT template <class O = T> +#else + template <class O /*= T*/> +#endif typename object_traits<O>::id_type object_id () const; database_type& database () const; @@ -328,20 +350,22 @@ namespace odb template <class T1, class D1, class T2, class D2> bool operator== (const lazy_unique_ptr<T1, D1>&, const lazy_unique_ptr<T2, D2>&); + template <class T1, class D1, class T2, class D2> + bool operator!= (const lazy_unique_ptr<T1, D1>&, const lazy_unique_ptr<T2, D2>&); + +#ifdef ODB_CXX11_NULLPTR template <class T, class D> bool operator== (const lazy_unique_ptr<T, D>&, std::nullptr_t) /*noexcept*/; template <class T, class D> bool operator== (std::nullptr_t, const lazy_unique_ptr<T, D>&) /*noexcept*/; - template <class T1, class D1, class T2, class D2> - bool operator!= (const lazy_unique_ptr<T1, D1>&, const lazy_unique_ptr<T2, D2>&); - template <class T, class D> bool operator!= (const lazy_unique_ptr<T, D>&, std::nullptr_t) /*noexcept*/; template <class T, class D> bool operator!= (std::nullptr_t, const lazy_unique_ptr<T, D>&) /*noexcept*/; +#endif // C++11 std::shared_ptr lazy version. // @@ -357,12 +381,16 @@ namespace odb typedef T element_type; /*constexpr*/ lazy_shared_ptr () /*noexcept*/; +#ifdef ODB_CXX11_NULLPTR /*constexpr*/ lazy_shared_ptr (std::nullptr_t) /*noexcept*/; +#endif template <class Y> explicit lazy_shared_ptr (Y*); template <class Y, class D> lazy_shared_ptr (Y*, D); template <class Y, class D, class A> lazy_shared_ptr (Y*, D, A); +#ifdef ODB_CXX11_NULLPTR template <class D> lazy_shared_ptr (std::nullptr_t, D); template <class D, class A> lazy_shared_ptr (std::nullptr_t, D, A); +#endif template <class Y> lazy_shared_ptr (const lazy_shared_ptr<Y>&, T*) /*noexcept*/; lazy_shared_ptr (const lazy_shared_ptr&) /*noexcept*/; @@ -393,8 +421,15 @@ namespace odb T* operator-> () const /*noexcept*/; long use_count () const /*noexcept*/; bool unique () const /*noexcept*/; - +#ifdef ODB_CXX11_EXPLICIT_CONVERSION_OPERATOR explicit operator bool () const /*noexcept*/; +#else + typedef std::shared_ptr<T> lazy_shared_ptr::*unspecified_bool_type; + operator unspecified_bool_type () const + { + return (p_ || i_) ? &lazy_shared_ptr::p_ : 0; + } +#endif // owner_before () is not provded. @@ -446,7 +481,11 @@ namespace odb template <class Y> void reset (database_type&, const std::shared_ptr<Y>&); template <class Y> void reset (database_type&, std::shared_ptr<Y>&&); +#ifdef ODB_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGUMENT template <class O = T> +#else + template <class O /*= T*/> +#endif typename object_traits<O>::id_type object_id () const; database_type& database () const; @@ -474,20 +513,22 @@ namespace odb template <class T, class Y> bool operator== (const lazy_shared_ptr<T>&, const lazy_shared_ptr<Y>&) /*noexcept*/; + template <class T, class Y> + bool operator!= (const lazy_shared_ptr<T>&, const lazy_shared_ptr<Y>&) /*noexcept*/; + +#ifdef ODB_CXX11_NULLPTR template <class T> bool operator== (const lazy_shared_ptr<T>&, std::nullptr_t) /*noexcept*/; template <class T> bool operator== (std::nullptr_t, const lazy_shared_ptr<T>&) /*noexcept*/; - template <class T, class Y> - bool operator!= (const lazy_shared_ptr<T>&, const lazy_shared_ptr<Y>&) /*noexcept*/; - template <class T> bool operator!= (const lazy_shared_ptr<T>&, std::nullptr_t) /*noexcept*/; template <class T> bool operator!= (std::nullptr_t, const lazy_shared_ptr<T>&) /*noexcept*/; +#endif // C++11 std::weak_ptr lazy version. // @@ -563,7 +604,11 @@ namespace odb // The object_id() function can only be called when the object is // persistent, or: expired() XOR loaded() (can use != for XOR). // +#ifdef ODB_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGUMENT template <class O = T> +#else + template <class O /*= T*/> +#endif typename object_traits<O>::id_type object_id () const; database_type& database () const; diff --git a/odb/lazy-ptr.ixx b/odb/lazy-ptr.ixx index 5c67845..19150ef 100644 --- a/odb/lazy-ptr.ixx +++ b/odb/lazy-ptr.ixx @@ -480,9 +480,11 @@ namespace odb lazy_unique_ptr<T, D>:: lazy_unique_ptr () {} +#ifdef ODB_CXX11_NULLPTR template <class T, class D> lazy_unique_ptr<T, D>:: lazy_unique_ptr (std::nullptr_t) {} +#endif template <class T, class D> lazy_unique_ptr<T, D>:: @@ -512,6 +514,7 @@ namespace odb lazy_unique_ptr<T, D>:: lazy_unique_ptr (std::auto_ptr<T1>&& r): p_ (std::move (r)) {} +#ifdef ODB_CXX11_NULLPTR template <class T, class D> lazy_unique_ptr<T, D>& lazy_unique_ptr<T, D>:: operator= (std::nullptr_t) @@ -519,6 +522,7 @@ namespace odb reset (); return *this; } +#endif template <class T, class D> lazy_unique_ptr<T, D>& lazy_unique_ptr<T, D>:: @@ -560,12 +564,14 @@ namespace odb return p_.get (); } +#ifdef ODB_CXX11_EXPLICIT_CONVERSION_OPERATOR template <class T, class D> lazy_unique_ptr<T, D>:: operator bool() const { return p_ || i_; } +#endif template <class T, class D> typename lazy_unique_ptr<T, D>::pointer lazy_unique_ptr<T, D>:: @@ -787,6 +793,15 @@ namespace odb return a.equal (b); } + template <class T1, class D1, class T2, class D2> + inline bool + operator!= (const lazy_unique_ptr<T1, D1>& a, + const lazy_unique_ptr<T2, D2>& b) + { + return !a.equal (b); + } + +#ifdef ODB_CXX11_NULLPTR template <class T, class D> inline bool operator== (const lazy_unique_ptr<T, D>& a, std::nullptr_t) @@ -801,14 +816,6 @@ namespace odb return !b; } - template <class T1, class D1, class T2, class D2> - inline bool - operator!= (const lazy_unique_ptr<T1, D1>& a, - const lazy_unique_ptr<T2, D2>& b) - { - return !a.equal (b); - } - template <class T, class D> inline bool operator!= (const lazy_unique_ptr<T, D>& a, std::nullptr_t) @@ -822,6 +829,7 @@ namespace odb { return b; } +#endif // // lazy_shared_ptr @@ -831,9 +839,11 @@ namespace odb inline lazy_shared_ptr<T>:: lazy_shared_ptr () {} +#ifdef ODB_CXX11_NULLPTR template <class T> inline lazy_shared_ptr<T>:: lazy_shared_ptr (std::nullptr_t) {} +#endif template <class T> template <class Y> @@ -850,6 +860,7 @@ namespace odb inline lazy_shared_ptr<T>:: lazy_shared_ptr (Y* p, D d, A a): p_ (p, d, a) {} +#ifdef ODB_CXX11_NULLPTR template <class T> template <class D> inline lazy_shared_ptr<T>:: @@ -859,6 +870,7 @@ namespace odb template <class D, class A> inline lazy_shared_ptr<T>:: lazy_shared_ptr (std::nullptr_t p, D d, A a): p_ (p, d, a) {} +#endif template <class T> template <class Y> @@ -1050,12 +1062,14 @@ namespace odb return p_.use_count (); } +#ifdef ODB_CXX11_EXPLICIT_CONVERSION_OPERATOR template <class T> inline lazy_shared_ptr<T>:: operator bool () const { return p_ || i_; } +#endif template <class T> template <class Y> @@ -1311,25 +1325,26 @@ namespace odb return a.equal (b); } - template <class T> + template <class T, class Y> inline bool - operator== (const lazy_shared_ptr<T>& p, std::nullptr_t) + operator!= (const lazy_shared_ptr<T>& a, const lazy_shared_ptr<Y>& b) { - return !p; + return !a.equal (b); } +#ifdef ODB_CXX11_NULLPTR template <class T> inline bool - operator== (std::nullptr_t, const lazy_shared_ptr<T>& p) + operator== (const lazy_shared_ptr<T>& p, std::nullptr_t) { return !p; } - template <class T, class Y> + template <class T> inline bool - operator!= (const lazy_shared_ptr<T>& a, const lazy_shared_ptr<Y>& b) + operator== (std::nullptr_t, const lazy_shared_ptr<T>& p) { - return !a.equal (b); + return !p; } template <class T> @@ -1345,6 +1360,7 @@ namespace odb { return p; } +#endif template <class T> inline void diff --git a/odb/tr1/lazy-ptr.hxx b/odb/tr1/lazy-ptr.hxx index ad6e283..01a7b36 100644 --- a/odb/tr1/lazy-ptr.hxx +++ b/odb/tr1/lazy-ptr.hxx @@ -111,10 +111,10 @@ namespace odb template <class Y> void reset (database_type&, std::auto_ptr<Y>&); template <class Y> void reset (database_type&, const std::tr1::shared_ptr<Y>&); -#ifdef ODB_CXX11 +#ifdef ODB_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGUMENT template <class O = T> #else - template <class O /* = T */> + template <class O /*= T*/> #endif typename object_traits<O>::id_type object_id () const; @@ -218,7 +218,7 @@ namespace odb // The object_id() function can only be called when the object is // persistent, or: expired() XOR loaded() (can use != for XOR). // -#ifdef ODB_CXX11 +#ifdef ODB_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGUMENT template <class O = T> #else template <class O /* = T */> diff --git a/odb/tr1/pointer-traits.hxx b/odb/tr1/pointer-traits.hxx index 5ba1b93..12e1164 100644 --- a/odb/tr1/pointer-traits.hxx +++ b/odb/tr1/pointer-traits.hxx @@ -7,6 +7,13 @@ #include <odb/pre.hxx> +#include <odb/details/config.hxx> // ODB_CXX11 + +// In VC++ std::shared_ptr and std::tr1::shared_ptr is the same class +// template. One is just a using-declaration for the other. +// +#if !(defined(ODB_CXX11) && defined(_MSC_VER)) + // // This header assumes that the necessary TR1 header has already // been included. @@ -94,6 +101,8 @@ namespace odb }; } +#endif // !(ODB_CXX11 && _MSC_VER) + #include <odb/post.hxx> #endif // ODB_TR1_POINTER_TRAITS_HXX diff --git a/odb/tr1/wrapper-traits.hxx b/odb/tr1/wrapper-traits.hxx index ebc41bc..7d159d4 100644 --- a/odb/tr1/wrapper-traits.hxx +++ b/odb/tr1/wrapper-traits.hxx @@ -7,6 +7,13 @@ #include <odb/pre.hxx> +#include <odb/details/config.hxx> // ODB_CXX11 + +// In VC++ std::shared_ptr and std::tr1::shared_ptr is the same class +// template. One is just a using-declaration for the other. +// +#if !(defined(ODB_CXX11) && defined(_MSC_VER)) + // // This header assumes that the necessary TR1 header has already // been included. @@ -63,6 +70,8 @@ namespace odb }; } +#endif // !(ODB_CXX11 && _MSC_VER) + #include <odb/post.hxx> #endif // ODB_TR1_WRAPPER_TRAITS_HXX |