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