Lunchbox
1.6.0
|
00001 00002 /* Copyright (c) 2006-2012, Stefan Eilemann <eile@equalizergraphics.com> 00003 * 2010-2012, Daniel Nachbaur <danielnachbaur@gmail.com> 00004 * 00005 * This library is free software; you can redistribute it and/or modify it under 00006 * the terms of the GNU Lesser General Public License version 2.1 as published 00007 * by the Free Software Foundation. 00008 * 00009 * This library is distributed in the hope that it will be useful, but WITHOUT 00010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00011 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 00012 * details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public License 00015 * along with this library; if not, write to the Free Software Foundation, Inc., 00016 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00017 */ 00018 00025 #ifndef LUNCHBOX_STDEXT_H 00026 #define LUNCHBOX_STDEXT_H 00027 00028 #include <lunchbox/compiler.h> 00029 #include <lunchbox/uint128_t.h> 00030 00031 #include <algorithm> 00032 #include <string> 00033 #include <vector> 00034 00035 //----- Common extensions of the STL 00036 #ifdef __GNUC__ 00037 # if defined LB_GCC_4_3_OR_LATER && !defined __INTEL_COMPILER 00038 # define LB_STDEXT_TR1 00039 # elif defined __clang__ 00040 # define LB_STDEXT_TR1 00041 # else 00042 # define LB_STDEXT_EXT 00043 # endif 00044 #elif defined _MSC_VER 00045 # define LB_STDEXT_MSVC 00046 #elif defined __xlC__ 00047 # define LB_STDEXT_TR1 00048 # define LB_STDEXT_TR1_BOOST 00049 #else 00050 # define LB_STDEXT_STD 00051 #endif 00052 00053 #ifdef LB_STDEXT_TR1 00054 # ifdef LB_STDEXT_TR1_BOOST 00055 # include <boost/tr1/functional.hpp> 00056 # include <boost/tr1/unordered_map.hpp> 00057 # include <boost/tr1/unordered_set.hpp> 00058 # else 00059 # include <tr1/unordered_map> 00060 # include <tr1/unordered_set> 00061 # endif 00062 /* Alias stde namespace to uniformly access stl extensions. */ 00063 namespace stde = std::tr1; 00064 # define LB_STDEXT_NAMESPACE_OPEN namespace std { namespace tr1 { 00065 # define LB_STDEXT_NAMESPACE_CLOSE }} 00066 #endif 00067 00068 #ifdef LB_STDEXT_EXT 00069 # include <ext/hash_map> 00070 # include <ext/hash_set> 00071 /* Alias stde namespace to uniformly access stl extensions. */ 00072 namespace stde = __gnu_cxx; 00073 # define LB_STDEXT_NAMESPACE_OPEN namespace __gnu_cxx { 00074 # define LB_STDEXT_NAMESPACE_CLOSE } 00075 #endif 00076 00077 #ifdef LB_STDEXT_MSVC 00078 # include <hash_map> 00079 # include <hash_set> 00080 /* Alias stde namespace to uniformly access stl extensions. */ 00081 namespace stde = stdext; 00082 # define LB_STDEXT_NAMESPACE_OPEN namespace stdext { 00083 # define LB_STDEXT_NAMESPACE_CLOSE } 00084 #endif 00085 00086 #ifdef LB_STDEXT_STD 00087 # include <hash_map> 00088 # include <hash_set> 00089 /* Alias stde namespace to uniformly access stl extensions. */ 00090 namespace stde = std; 00091 # define LB_STDEXT_NAMESPACE_OPEN namespace std { 00092 # define LB_STDEXT_NAMESPACE_CLOSE } 00093 #endif 00094 00095 00096 LB_STDEXT_NAMESPACE_OPEN 00097 00098 //----- Our extensions of the STL 00099 #ifdef LB_STDEXT_TR1 00100 # ifndef LB_HAVE_HASH_MAP 00101 template<class K, class T, class H = hash< K >, 00102 class P = std::equal_to< K >, class A = std::allocator< K > > 00103 class hash_map : public unordered_map< K, T, H, P, A > 00104 { 00105 }; 00106 # endif // LB_HAVE_HASH_MAP 00107 # ifndef LB_HAVE_HASH_SET 00108 template<class T, class H = hash< T >, 00109 class P = std::equal_to< T >, class A = std::allocator< T > > 00110 class hash_set : public unordered_set< T, H, P, A > 00111 { 00112 }; 00113 # endif // LB_HAVE_HASH_SET 00114 #endif 00115 00116 #ifdef LB_STDEXT_EXT 00117 # ifndef LB_HAVE_STRING_HASH 00118 00119 template<> struct hash< std::string > 00120 { 00121 size_t operator()( const std::string& str ) const 00122 { 00123 return hash< const char* >()( str.c_str() ); 00124 } 00125 }; 00126 # endif // LB_HAVE_STRING_HASH 00127 00128 # if !defined __INTEL_COMPILER 00129 # ifndef LB_HAVE_LONG_HASH 00130 00131 template<> struct hash< uint64_t > 00132 { 00133 size_t operator()( const uint64_t& val ) const 00134 { 00135 // OPT: tr1 does the same, however it seems suboptimal on 32 bits 00136 // if the lower 32 bits never change, e.g., for ObjectVersion 00137 return static_cast< size_t >( val ); 00138 } 00139 }; 00140 # endif 00141 # endif // !__INTEL_COMPILER 00142 00143 # ifndef LB_HAVE_VOID_PTR_HASH 00144 00145 template<> struct hash< void* > 00146 { 00147 template< typename P > 00148 size_t operator()( const P& key ) const 00149 { 00150 return reinterpret_cast<size_t>(key); 00151 } 00152 }; 00153 00154 template<> struct hash< const void* > 00155 { 00156 template< typename P > 00157 size_t operator()( const P& key ) const 00158 { 00159 return reinterpret_cast<size_t>(key); 00160 } 00161 }; 00162 # endif // LB_HAVE_VOID_PTR_HASH 00163 #endif // LB_STDEXT_EXT 00164 00165 #ifdef LB_STDEXT_MSVC 00166 # ifndef LB_HAVE_STRING_HASH 00167 00169 template<> inline size_t hash_compare< std::string >::operator() 00170 ( const std::string& key ) const 00171 { 00172 return hash_value( key.c_str( )); 00173 } 00174 00175 # endif 00176 00177 template<> inline size_t hash_compare< lunchbox::uint128_t >::operator() 00178 ( const lunchbox::uint128_t& key ) const 00179 { 00180 return static_cast< size_t >( key.high() ^ key.low() ); 00181 } 00182 00183 template<> inline size_t hash_value( const lunchbox::uint128_t& key ) 00184 { 00185 return static_cast< size_t >( key.high() ^ key.low() ); 00186 } 00187 00188 #else // MSVC 00189 00191 template<> struct hash< lunchbox::uint128_t > 00192 { 00193 size_t operator()( const lunchbox::uint128_t& key ) const 00194 { 00195 return key.high() ^ key.low(); 00196 } 00197 }; 00198 00199 #endif //! MSVC 00200 00205 template< typename C > void usort( C& c ) 00206 { 00207 std::sort( c.begin(), c.end( )); 00208 c.erase( std::unique( c.begin(), c.end( )), c.end( )); 00209 } 00210 00212 template< typename T > typename std::vector< T >::iterator 00213 find( std::vector< T >& container, const T& element ) 00214 { return std::find( container.begin(), container.end(), element ); } 00215 00217 template< typename T > typename std::vector< T >::const_iterator 00218 find( const std::vector< T >& container, const T& element ) 00219 { return std::find( container.begin(), container.end(), element ); } 00220 00222 template< typename T, typename P > typename std::vector< T >::iterator 00223 find_if( std::vector< T >& container, const P& predicate ) 00224 { return std::find_if( container.begin(), container.end(), predicate );} 00225 00227 template< typename T, typename P > typename std::vector<T>::const_iterator 00228 find_if( std::vector< const T >& container, const P& predicate ) 00229 { return std::find_if( container.begin(), container.end(), predicate );} 00230 00231 LB_STDEXT_NAMESPACE_CLOSE 00232 00233 #endif // LUNCHBOX_STDEXT_H