From d5987c64ad2f25928f8d4900b1a9bf84822be6a0 Mon Sep 17 00:00:00 2001 From: khizmax Date: Sat, 13 Dec 2014 16:08:20 +0300 Subject: [PATCH] add support for GCC 5: std::list::size() complexity is O(1) --- cds/container/striped_map/std_list.h | 19 ++++++++-------- cds/container/striped_set/std_list.h | 33 ++++++++++++++-------------- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/cds/container/striped_map/std_list.h b/cds/container/striped_map/std_list.h index 826fedcb..4297e5e9 100644 --- a/cds/container/striped_map/std_list.h +++ b/cds/container/striped_map/std_list.h @@ -123,17 +123,18 @@ namespace cds { namespace intrusive { namespace striped_set { private: //@cond container_type m_List; -# ifdef __GLIBCXX__ +# if defined(__GLIBCXX__ ) && !( CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION >= 50000 ) // GCC C++ lib bug: // In GCC (at least up to 4.7.x), the complexity of std::list::size() is O(N) // (see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49561) + // Fixed in GCC 5 size_t m_nSize ; // list size # endif //@endcond public: adapted_container() -# ifdef __GLIBCXX__ +# if defined(__GLIBCXX__ ) && !( CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION >= 50000 ) : m_nSize(0) # endif {} @@ -147,7 +148,7 @@ namespace cds { namespace intrusive { namespace striped_set { it = m_List.insert( it, value_type( key, mapped_type()) ); f( *it ); -# ifdef __GLIBCXX__ +# if defined(__GLIBCXX__ ) && !( CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION >= 50000 ) ++m_nSize; # endif return true; @@ -165,7 +166,7 @@ namespace cds { namespace intrusive { namespace striped_set { //value_type newItem( key ); it = m_List.emplace( it, value_type( std::forward(key), std::move( mapped_type( std::forward(args)...) )) ); -# ifdef __GLIBCXX__ +# if defined(__GLIBCXX__ ) && !( CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION >= 50000 ) ++m_nSize; # endif return true; @@ -182,7 +183,7 @@ namespace cds { namespace intrusive { namespace striped_set { value_type newItem( key, mapped_type() ); it = m_List.insert( it, newItem ); func( true, *it ); -# ifdef __GLIBCXX__ +# if defined(__GLIBCXX__ ) && !( CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION >= 50000 ) ++m_nSize; # endif return std::make_pair( true, true ); @@ -204,7 +205,7 @@ namespace cds { namespace intrusive { namespace striped_set { // key exists f( *it ); m_List.erase( it ); -# ifdef __GLIBCXX__ +# if defined(__GLIBCXX__ ) && !( CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION >= 50000 ) --m_nSize; # endif @@ -221,7 +222,7 @@ namespace cds { namespace intrusive { namespace striped_set { // key exists f( *it ); m_List.erase( it ); -# ifdef __GLIBCXX__ +# if defined(__GLIBCXX__ ) && !( CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION >= 50000 ) --m_nSize; # endif @@ -268,14 +269,14 @@ namespace cds { namespace intrusive { namespace striped_set { assert( it == m_List.end() || key_comparator()( itWhat->first, it->first ) != 0 ); copy_item()( m_List, it, itWhat ); -# ifdef __GLIBCXX__ +# if defined(__GLIBCXX__ ) && !( CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION >= 50000 ) ++m_nSize; # endif } size_t size() const { -# ifdef __GLIBCXX__ +# if defined(__GLIBCXX__ ) && !( CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION >= 50000 ) return m_nSize; # else return m_List.size(); diff --git a/cds/container/striped_set/std_list.h b/cds/container/striped_set/std_list.h index 8399f04e..12868d5d 100644 --- a/cds/container/striped_set/std_list.h +++ b/cds/container/striped_set/std_list.h @@ -117,17 +117,18 @@ namespace cds { namespace intrusive { namespace striped_set { private: //@cond container_type m_List; -# ifdef __GLIBCXX__ +# if defined(__GLIBCXX__ ) && !( CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION >= 50000 ) // GCC C++ lib bug: - // In GCC (at least up to 4.7.x), the complexity of std::list::size() is O(N) + // In GCC, the complexity of std::list::size() is O(N) // (see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49561) + // Fixed in GCC 5 size_t m_nSize ; // list size # endif //@endcond public: adapted_container() -# ifdef __GLIBCXX__ +# if defined(__GLIBCXX__ ) && !( CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION >= 50000 ) : m_nSize(0) # endif {} @@ -141,7 +142,7 @@ namespace cds { namespace intrusive { namespace striped_set { it = m_List.insert( it, newItem ); f( *it ); -# ifdef __GLIBCXX__ +# if defined(__GLIBCXX__ ) && !( CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION >= 50000 ) ++m_nSize; # endif return true; @@ -154,17 +155,17 @@ namespace cds { namespace intrusive { namespace striped_set { template bool emplace( Args&&... args ) { -#if CDS_COMPILER == CDS_COMPILER_MSVC && CDS_COMPILER_VERSION == CDS_COMPILER_MSVC12 - // MS VC++ 2013: internal compiler error - // Use assignment workaround, see http://connect.microsoft.com/VisualStudio/feedback/details/804941/visual-studio-2013-rc-c-internal-compiler-error-with-std-forward - value_type val = value_type( std::forward(args)... ); -#else +//#if CDS_COMPILER == CDS_COMPILER_MSVC && CDS_COMPILER_VERSION == CDS_COMPILER_MSVC12 +// // MS VC++ 2013: internal compiler error +// // Use assignment workaround, see http://connect.microsoft.com/VisualStudio/feedback/details/804941/visual-studio-2013-rc-c-internal-compiler-error-with-std-forward +// value_type val = value_type( std::forward(args)... ); +//#else value_type val(std::forward(args)...); -#endif +//#endif iterator it = std::lower_bound( m_List.begin(), m_List.end(), val, find_predicate() ); if ( it == m_List.end() || key_comparator()( val, *it ) != 0 ) { it = m_List.emplace( it, std::move( val ) ); -# ifdef __GLIBCXX__ +# if defined(__GLIBCXX__ ) && !( CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION >= 50000 ) ++m_nSize; # endif return true; @@ -181,7 +182,7 @@ namespace cds { namespace intrusive { namespace striped_set { value_type newItem( val ); it = m_List.insert( it, newItem ); func( true, *it, val ); -# ifdef __GLIBCXX__ +# if defined(__GLIBCXX__ ) && !( CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION >= 50000 ) ++m_nSize; # endif return std::make_pair( true, true ); @@ -203,7 +204,7 @@ namespace cds { namespace intrusive { namespace striped_set { // key exists f( *it ); m_List.erase( it ); -# ifdef __GLIBCXX__ +# if defined(__GLIBCXX__ ) && !( CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION >= 50000 ) --m_nSize; # endif @@ -220,7 +221,7 @@ namespace cds { namespace intrusive { namespace striped_set { // key exists f( *it ); m_List.erase( it ); -# ifdef __GLIBCXX__ +# if defined(__GLIBCXX__ ) && !( CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION >= 50000 ) --m_nSize; # endif @@ -268,14 +269,14 @@ namespace cds { namespace intrusive { namespace striped_set { assert( it == m_List.end() || key_comparator()( *itWhat, *it ) != 0 ); copy_item()( m_List, it, itWhat ); -# ifdef __GLIBCXX__ +# if defined(__GLIBCXX__ ) && !( CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION >= 50000 ) ++m_nSize; # endif } size_t size() const { -# ifdef __GLIBCXX__ +# if defined(__GLIBCXX__ ) && !( CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION >= 50000 ) return m_nSize; # else return m_List.size(); -- 2.34.1