From 8a9e1081c026a092c7dfb28fbd079b88850c7233 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 2 Mar 2012 12:34:54 +0200 Subject: Portability workarounds for incomplete C++11 support in VC++ and old GCC --- odb/details/config-vc.h | 8 +++++- odb/details/config.hxx | 18 +++++++++++++ odb/details/transfer-ptr.hxx | 2 ++ odb/lazy-ptr.hxx | 63 +++++++++++++++++++++++++++++++++++++------- odb/lazy-ptr.ixx | 46 +++++++++++++++++++++----------- odb/tr1/lazy-ptr.hxx | 6 ++--- odb/tr1/pointer-traits.hxx | 9 +++++++ 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 +# 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 p): p_ (p.release ()) {} #ifdef ODB_CXX11 +#ifdef ODB_CXX11_NULLPTR transfer_ptr (std::nullptr_t): p_ (0) {} +#endif template transfer_ptr (std::unique_ptr&& 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 void reset (database_type&, const ID&); template void reset (database_type&, Y*); -#ifdef ODB_CXX11 +#ifdef ODB_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGUMENT template #else template @@ -193,7 +193,7 @@ namespace odb void reset (database_type&, T*); template void reset (database_type&, std::auto_ptr&); -#ifdef ODB_CXX11 +#ifdef ODB_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGUMENT template #else template @@ -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 lazy_unique_ptr (lazy_unique_ptr&&) /*noexcept*/; template lazy_unique_ptr (std::auto_ptr&&) /*noexcept*/; +#ifdef ODB_CXX11_NULLPTR lazy_unique_ptr& operator= (std::nullptr_t) /*noexcept*/; +#endif lazy_unique_ptr& operator= (lazy_unique_ptr&&) /*noexcept*/; template lazy_unique_ptr& operator= (lazy_unique_ptr&&) /*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 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 void reset (database_type&, std::unique_ptr&&); template void reset (database_type&, std::auto_ptr&&); +#ifdef ODB_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGUMENT template +#else + template +#endif typename object_traits::id_type object_id () const; database_type& database () const; @@ -328,20 +350,22 @@ namespace odb template bool operator== (const lazy_unique_ptr&, const lazy_unique_ptr&); + template + bool operator!= (const lazy_unique_ptr&, const lazy_unique_ptr&); + +#ifdef ODB_CXX11_NULLPTR template bool operator== (const lazy_unique_ptr&, std::nullptr_t) /*noexcept*/; template bool operator== (std::nullptr_t, const lazy_unique_ptr&) /*noexcept*/; - template - bool operator!= (const lazy_unique_ptr&, const lazy_unique_ptr&); - template bool operator!= (const lazy_unique_ptr&, std::nullptr_t) /*noexcept*/; template bool operator!= (std::nullptr_t, const lazy_unique_ptr&) /*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 explicit lazy_shared_ptr (Y*); template lazy_shared_ptr (Y*, D); template lazy_shared_ptr (Y*, D, A); +#ifdef ODB_CXX11_NULLPTR template lazy_shared_ptr (std::nullptr_t, D); template lazy_shared_ptr (std::nullptr_t, D, A); +#endif template lazy_shared_ptr (const lazy_shared_ptr&, 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 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 void reset (database_type&, const std::shared_ptr&); template void reset (database_type&, std::shared_ptr&&); +#ifdef ODB_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGUMENT template +#else + template +#endif typename object_traits::id_type object_id () const; database_type& database () const; @@ -474,20 +513,22 @@ namespace odb template bool operator== (const lazy_shared_ptr&, const lazy_shared_ptr&) /*noexcept*/; + template + bool operator!= (const lazy_shared_ptr&, const lazy_shared_ptr&) /*noexcept*/; + +#ifdef ODB_CXX11_NULLPTR template bool operator== (const lazy_shared_ptr&, std::nullptr_t) /*noexcept*/; template bool operator== (std::nullptr_t, const lazy_shared_ptr&) /*noexcept*/; - template - bool operator!= (const lazy_shared_ptr&, const lazy_shared_ptr&) /*noexcept*/; - template bool operator!= (const lazy_shared_ptr&, std::nullptr_t) /*noexcept*/; template bool operator!= (std::nullptr_t, const lazy_shared_ptr&) /*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 +#else + template +#endif typename object_traits::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:: lazy_unique_ptr () {} +#ifdef ODB_CXX11_NULLPTR template lazy_unique_ptr:: lazy_unique_ptr (std::nullptr_t) {} +#endif template lazy_unique_ptr:: @@ -512,6 +514,7 @@ namespace odb lazy_unique_ptr:: lazy_unique_ptr (std::auto_ptr&& r): p_ (std::move (r)) {} +#ifdef ODB_CXX11_NULLPTR template lazy_unique_ptr& lazy_unique_ptr:: operator= (std::nullptr_t) @@ -519,6 +522,7 @@ namespace odb reset (); return *this; } +#endif template lazy_unique_ptr& lazy_unique_ptr:: @@ -560,12 +564,14 @@ namespace odb return p_.get (); } +#ifdef ODB_CXX11_EXPLICIT_CONVERSION_OPERATOR template lazy_unique_ptr:: operator bool() const { return p_ || i_; } +#endif template typename lazy_unique_ptr::pointer lazy_unique_ptr:: @@ -787,6 +793,15 @@ namespace odb return a.equal (b); } + template + inline bool + operator!= (const lazy_unique_ptr& a, + const lazy_unique_ptr& b) + { + return !a.equal (b); + } + +#ifdef ODB_CXX11_NULLPTR template inline bool operator== (const lazy_unique_ptr& a, std::nullptr_t) @@ -801,14 +816,6 @@ namespace odb return !b; } - template - inline bool - operator!= (const lazy_unique_ptr& a, - const lazy_unique_ptr& b) - { - return !a.equal (b); - } - template inline bool operator!= (const lazy_unique_ptr& 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:: lazy_shared_ptr () {} +#ifdef ODB_CXX11_NULLPTR template inline lazy_shared_ptr:: lazy_shared_ptr (std::nullptr_t) {} +#endif template template @@ -850,6 +860,7 @@ namespace odb inline lazy_shared_ptr:: lazy_shared_ptr (Y* p, D d, A a): p_ (p, d, a) {} +#ifdef ODB_CXX11_NULLPTR template template inline lazy_shared_ptr:: @@ -859,6 +870,7 @@ namespace odb template inline lazy_shared_ptr:: lazy_shared_ptr (std::nullptr_t p, D d, A a): p_ (p, d, a) {} +#endif template template @@ -1050,12 +1062,14 @@ namespace odb return p_.use_count (); } +#ifdef ODB_CXX11_EXPLICIT_CONVERSION_OPERATOR template inline lazy_shared_ptr:: operator bool () const { return p_ || i_; } +#endif template template @@ -1311,25 +1325,26 @@ namespace odb return a.equal (b); } - template + template inline bool - operator== (const lazy_shared_ptr& p, std::nullptr_t) + operator!= (const lazy_shared_ptr& a, const lazy_shared_ptr& b) { - return !p; + return !a.equal (b); } +#ifdef ODB_CXX11_NULLPTR template inline bool - operator== (std::nullptr_t, const lazy_shared_ptr& p) + operator== (const lazy_shared_ptr& p, std::nullptr_t) { return !p; } - template + template inline bool - operator!= (const lazy_shared_ptr& a, const lazy_shared_ptr& b) + operator== (std::nullptr_t, const lazy_shared_ptr& p) { - return !a.equal (b); + return !p; } template @@ -1345,6 +1360,7 @@ namespace odb { return p; } +#endif template 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 void reset (database_type&, std::auto_ptr&); template void reset (database_type&, const std::tr1::shared_ptr&); -#ifdef ODB_CXX11 +#ifdef ODB_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGUMENT template #else - template + template #endif typename object_traits::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 #else template 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 +#include // 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 #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 +#include // 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 #endif // ODB_TR1_WRAPPER_TRAITS_HXX -- cgit v1.1