X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=cds%2Fopt%2Fhash.h;h=2949b506bf15078e9bba897a8b441030a0980baf;hb=71bc01900f436052b81f405046f8fc69aa26973f;hp=6d5a88d78c2a8716d5b5fbadb7cbdffe24135569;hpb=d5ac3ffc7748bbcdd83464aae294509f0b48a6f5;p=libcds.git diff --git a/cds/opt/hash.h b/cds/opt/hash.h index 6d5a88d7..2949b506 100644 --- a/cds/opt/hash.h +++ b/cds/opt/hash.h @@ -1,11 +1,39 @@ -//$$CDS-header$$ +/* + This file is a part of libcds - Concurrent Data Structures library -#ifndef __CDS_OPT_HASH_H -#define __CDS_OPT_HASH_H + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 + + Source code repo: http://github.com/khizmax/libcds/ + Download: http://sourceforge.net/projects/libcds/files/ + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef CDSLIB_OPT_HASH_H +#define CDSLIB_OPT_HASH_H #include +#include #include -#include namespace cds { namespace opt { @@ -15,8 +43,6 @@ namespace cds { namespace opt { The default value of template argument \p Functor is \p cds::opt::v::hash that is synonym for std::hash implementation of standard library. - If standard C++ library of the compiler you use does not provide TR1 implementation - the \p cds library automatically selects boost::hash. */ template struct hash { @@ -30,23 +56,22 @@ namespace cds { namespace opt { namespace v { //@cond - using cds::details::hash; + using std::hash; /// Metafunction selecting default hash implementation /** The metafunction selects appropriate hash functor implementation. If \p Hash is not equal to opt::none, then result of metafunction is \p Hash. - Otherwise, the result is std::hash or boost::hash - depending of compiler you use. + Otherwise, the result is std::hash . - Note that default hash function like std::hash or boost::hash + Note that default hash function like std::hash is generally not suitable for complex type \p Q and its derivatives. You should manually provide particular hash functor for such types. */ template struct hash_selector { - typedef Hash type ; ///< resulting implementation of hash functor + typedef Hash type; ///< resulting implementation of hash functor }; template <> @@ -56,14 +81,13 @@ namespace cds { namespace opt { template size_t operator()( Q const& key ) const { - return hash()( key ); + return std::hash()( key ); } }; }; //@endcond } // namespace v -#ifdef CDS_CXX11_VARIADIC_TEMPLATE_SUPPORT //@cond namespace details { template struct hash_list; @@ -82,14 +106,12 @@ namespace cds { namespace opt { hash_list( hash_tuple_type const& t) : hash_tuple( t ) {} -# ifdef CDS_MOVE_SEMANTICS_SUPPORT hash_list( hash_tuple_type&& t) - : hash_tuple( std::forward(t) ) + : hash_tuple( std::forward(t)) {} -# endif template - typename std::enable_if< (I == sizeof...(Functors)) >::type apply( size_t * dest, T const& v ) const + typename std::enable_if< (I == sizeof...(Functors)) >::type apply( size_t * /*dest*/, T const& /*v*/ ) const {} template @@ -108,21 +130,19 @@ namespace cds { namespace opt { } // namespace details //@endcond + /// Declare tuple for hash functors \p Functors + template + using hash_tuple = details::hash_list< std::tuple< Functors... >>; + //@cond // At least, two functors must be provided. Single functor is not supported -//#if CDS_COMPILER != CDS_COMPILER_INTEL - // Intel C++ compiler does not support template struct hash< std::tuple >; -//#endif //@endcond - /// Multi-functor hash option setter - specialization for std::tuple + /// Multi-functor hash option setter - specialization for \p std::tuple template struct hash< std::tuple > { -//# if CDS_COMPILER == CDS_COMPILER_INTEL - //static_assert( sizeof...(Functors) > 1, "At least, two functors must be provided. Single functor is not supported" ); -//# endif //@cond template struct pack: public Base { @@ -131,400 +151,6 @@ namespace cds { namespace opt { //@endcond }; -#else // no variadic template support - namespace details { - template struct hash_list; - template - struct hash_list< std::tuple > - { - static size_t const size = 2; - typedef size_t values[size]; - typedef std::tuple hash_tuple_type; - - hash_tuple_type hash_tuple; - - hash_list() - {} - hash_list( hash_tuple_type const& t) - : hash_tuple( t ) - {} -# ifdef CDS_MOVE_SEMANTICS_SUPPORT - hash_list( hash_tuple_type&& t) - : hash_tuple( t ) - {} -# endif - - template - void operator()( size_t * dest, T const& v ) const - { - dest[0] = std::get<0>( hash_tuple )( v ); - dest[1] = std::get<1>( hash_tuple )( v ); - } - }; - - template - struct hash_list< std::tuple > - { - static size_t const size = 3; - typedef size_t values[size]; - typedef std::tuple hash_tuple_type; - - hash_tuple_type hash_tuple; - - hash_list() - {} - hash_list( hash_tuple_type const& t) - : hash_tuple( t ) - {} -# ifdef CDS_MOVE_SEMANTICS_SUPPORT - hash_list( hash_tuple_type&& t) - : hash_tuple( t ) - {} -# endif - - template - void operator()( size_t * dest, T const& v ) const - { - dest[0] = std::get<0>( hash_tuple )( v ); - dest[1] = std::get<1>( hash_tuple )( v ); - dest[2] = std::get<2>( hash_tuple )( v ); - } - }; - - template - struct hash_list< std::tuple > - { - static size_t const size = 4; - typedef size_t values[size]; - typedef std::tuple hash_tuple_type; - - hash_tuple_type hash_tuple; - - hash_list() - {} - hash_list( hash_tuple_type const& t) - : hash_tuple( t ) - {} -# ifdef CDS_MOVE_SEMANTICS_SUPPORT - hash_list( hash_tuple_type&& t) - : hash_tuple( t ) - {} -# endif - - template - void operator()( size_t * dest, T const& v ) const - { - dest[0] = std::get<0>( hash_tuple )( v ); - dest[1] = std::get<1>( hash_tuple )( v ); - dest[2] = std::get<2>( hash_tuple )( v ); - dest[3] = std::get<3>( hash_tuple )( v ); - } - }; - - template - struct hash_list< std::tuple > - { - static size_t const size = 5; - typedef size_t values[size]; - typedef std::tuple hash_tuple_type; - - hash_tuple_type hash_tuple; - - hash_list() - {} - hash_list( hash_tuple_type const& t) - : hash_tuple( t ) - {} -# ifdef CDS_MOVE_SEMANTICS_SUPPORT - hash_list( hash_tuple_type&& t) - : hash_tuple( t ) - {} -# endif - - template - void operator()( size_t * dest, T const& v ) const - { - dest[0] = std::get<0>( hash_tuple )( v ); - dest[1] = std::get<1>( hash_tuple )( v ); - dest[2] = std::get<2>( hash_tuple )( v ); - dest[3] = std::get<3>( hash_tuple )( v ); - dest[4] = std::get<4>( hash_tuple )( v ); - } - }; - - template - struct hash_list< std::tuple > - { - static size_t const size = 6; - typedef size_t values[size]; - typedef std::tuple hash_tuple_type; - - hash_tuple_type hash_tuple; - - hash_list() - {} - hash_list( hash_tuple_type const& t) - : hash_tuple( t ) - {} -# ifdef CDS_MOVE_SEMANTICS_SUPPORT - hash_list( hash_tuple_type&& t) - : hash_tuple( t ) - {} -# endif - - template - void operator()( size_t * dest, T const& v ) const - { - dest[0] = std::get<0>( hash_tuple )( v ); - dest[1] = std::get<1>( hash_tuple )( v ); - dest[2] = std::get<2>( hash_tuple )( v ); - dest[3] = std::get<3>( hash_tuple )( v ); - dest[4] = std::get<4>( hash_tuple )( v ); - dest[5] = std::get<5>( hash_tuple )( v ); - } - }; - - template - struct hash_list< std::tuple > - { - static size_t const size = 7; - typedef size_t values[size]; - typedef std::tuple hash_tuple_type; - - hash_tuple_type hash_tuple; - - hash_list() - {} - hash_list( hash_tuple_type const& t) - : hash_tuple( t ) - {} -# ifdef CDS_MOVE_SEMANTICS_SUPPORT - hash_list( hash_tuple_type&& t) - : hash_tuple( t ) - {} -# endif - - template - void operator()( size_t * dest, T const& v ) const - { - dest[0] = std::get<0>( hash_tuple )( v ); - dest[1] = std::get<1>( hash_tuple )( v ); - dest[2] = std::get<2>( hash_tuple )( v ); - dest[3] = std::get<3>( hash_tuple )( v ); - dest[4] = std::get<4>( hash_tuple )( v ); - dest[5] = std::get<5>( hash_tuple )( v ); - dest[6] = std::get<6>( hash_tuple )( v ); - } - }; - - template - struct hash_list< std::tuple > - { - static size_t const size = 8; - typedef size_t values[size]; - typedef std::tuple hash_tuple_type; - - hash_tuple_type hash_tuple; - - hash_list() - {} - hash_list( hash_tuple_type const& t) - : hash_tuple( t ) - {} -# ifdef CDS_MOVE_SEMANTICS_SUPPORT - hash_list( hash_tuple_type&& t) - : hash_tuple( t ) - {} -# endif - - template - void operator()( size_t * dest, T const& v ) const - { - dest[0] = std::get<0>( hash_tuple )( v ); - dest[1] = std::get<1>( hash_tuple )( v ); - dest[2] = std::get<2>( hash_tuple )( v ); - dest[3] = std::get<3>( hash_tuple )( v ); - dest[4] = std::get<4>( hash_tuple )( v ); - dest[5] = std::get<5>( hash_tuple )( v ); - dest[6] = std::get<6>( hash_tuple )( v ); - dest[7] = std::get<7>( hash_tuple )( v ); - } - }; - -#if !((CDS_COMPILER == CDS_COMPILER_MSVC || CDS_COMPILER == CDS_COMPILER_INTEL) && _MSC_VER == 1700) - // MSVC 11: max count of argument is 8 - - template - struct hash_list< std::tuple > - { - static size_t const size = 9; - typedef size_t values[size]; - typedef std::tuple hash_tuple_type; - - hash_tuple_type hash_tuple; - - hash_list() - {} - hash_list( hash_tuple_type const& t) - : hash_tuple( t ) - {} -# ifdef CDS_MOVE_SEMANTICS_SUPPORT - hash_list( hash_tuple_type&& t) - : hash_tuple( t ) - {} -# endif - - template - void operator()( size_t * dest, T const& v ) const - { - dest[0] = std::get<0>( hash_tuple )( v ); - dest[1] = std::get<1>( hash_tuple )( v ); - dest[2] = std::get<2>( hash_tuple )( v ); - dest[3] = std::get<3>( hash_tuple )( v ); - dest[4] = std::get<4>( hash_tuple )( v ); - dest[5] = std::get<5>( hash_tuple )( v ); - dest[6] = std::get<6>( hash_tuple )( v ); - dest[7] = std::get<7>( hash_tuple )( v ); - dest[8] = std::get<8>( hash_tuple )( v ); - } - }; - - template - struct hash_list< std::tuple > - { - static size_t const size = 10; - typedef size_t values[size]; - typedef std::tuple hash_tuple_type; - - hash_tuple_type hash_tuple; - - hash_list() - {} - hash_list( hash_tuple_type const& t) - : hash_tuple( t ) - {} -# ifdef CDS_MOVE_SEMANTICS_SUPPORT - hash_list( hash_tuple_type&& t) - : hash_tuple( t ) - {} -# endif - - template - void operator()( size_t * dest, T const& v ) const - { - dest[0] = std::get<0>( hash_tuple )( v ); - dest[1] = std::get<1>( hash_tuple )( v ); - dest[2] = std::get<2>( hash_tuple )( v ); - dest[3] = std::get<3>( hash_tuple )( v ); - dest[4] = std::get<4>( hash_tuple )( v ); - dest[5] = std::get<5>( hash_tuple )( v ); - dest[6] = std::get<6>( hash_tuple )( v ); - dest[7] = std::get<7>( hash_tuple )( v ); - dest[8] = std::get<8>( hash_tuple )( v ); - dest[9] = std::get<9>( hash_tuple )( v ); - } - }; -#endif - } // namespace details - - template< typename F1, typename F2 > - struct hash< std::tuple< F1, F2 > > - { - //@cond - template struct pack: public Base - { - typedef details::hash_list< std::tuple > hash; - }; - //@endcond - }; - template< typename F1, typename F2, typename F3 > - struct hash< std::tuple< F1, F2, F3 > > - { - //@cond - template struct pack: public Base - { - typedef details::hash_list< std::tuple > hash; - }; - //@endcond - }; - template< typename F1, typename F2, typename F3, typename F4 > - struct hash< std::tuple< F1, F2, F3, F4 > > - { - //@cond - template struct pack: public Base - { - typedef details::hash_list< std::tuple > hash; - }; - //@endcond - }; - template< typename F1, typename F2, typename F3, typename F4, typename F5 > - struct hash< std::tuple< F1, F2, F3, F4, F5 > > - { - //@cond - template struct pack: public Base - { - typedef details::hash_list< std::tuple > hash; - }; - //@endcond - }; - template< typename F1, typename F2, typename F3, typename F4, typename F5, typename F6 > - struct hash< std::tuple< F1, F2, F3, F4, F5, F6 > > - { - //@cond - template struct pack: public Base - { - typedef details::hash_list< std::tuple > hash; - }; - //@endcond - }; - template< typename F1, typename F2, typename F3, typename F4, typename F5, typename F6, typename F7 > - struct hash< std::tuple< F1, F2, F3, F4, F5, F6, F7 > > - { - //@cond - template struct pack: public Base - { - typedef details::hash_list< std::tuple > hash; - }; - //@endcond - }; - template< typename F1, typename F2, typename F3, typename F4, typename F5, typename F6, typename F7, typename F8 > - struct hash< std::tuple< F1, F2, F3, F4, F5, F6, F7, F8 > > - { - //@cond - template struct pack: public Base - { - typedef details::hash_list< std::tuple > hash; - }; - //@endcond - }; - -#if !((CDS_COMPILER == CDS_COMPILER_MSVC || CDS_COMPILER == CDS_COMPILER_INTEL) && _MSC_VER == 1700) - // MSVC 11: max count of argument is 8 - - template< typename F1, typename F2, typename F3, typename F4, typename F5, typename F6, typename F7, typename F8, typename F9 > - struct hash< std::tuple< F1, F2, F3, F4, F5, F6, F7, F8, F9 > > - { - //@cond - template struct pack: public Base - { - typedef details::hash_list< std::tuple > hash; - }; - //@endcond - }; - template< typename F1, typename F2, typename F3, typename F4, typename F5, typename F6, typename F7, typename F8, typename F9, - typename F10 > - struct hash< std::tuple< F1, F2, F3, F4, F5, F6, F7, F8, F9, F10 > > - { - //@cond - template struct pack: public Base - { - typedef details::hash_list< std::tuple > hash; - }; - //@endcond - }; -#endif // !MSVC11 -#endif // #ifdef CDS_CXX11_VARIADIC_TEMPLATE_SUPPORT //@cond namespace details { @@ -545,11 +171,9 @@ namespace cds { namespace opt { hash_list_wrapper( hash_tuple_type const& t) : m_wrappedList( t ) {} -# ifdef CDS_MOVE_SEMANTICS_SUPPORT hash_list_wrapper( hash_tuple_type&& t) - : m_wrappedList( std::forward(t) ) + : m_wrappedList( std::forward(t)) {} -# endif void operator()( size_t * dest, wrapped_type const& what ) const { @@ -568,4 +192,4 @@ namespace cds { namespace opt { }} // namespace cds::opt -#endif // #ifndef __CDS_OPT_HASH_H +#endif // #ifndef CDSLIB_OPT_HASH_H