Equalizer 1.0
|
00001 00002 /* Copyright (c) 2006-2011, 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 COBASE_STDEXT_H 00025 #define COBASE_STDEXT_H 00026 00027 #include <co/base/compiler.h> 00028 #include <co/base/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 EQ_GCC_4_3_OR_LATER && !defined __INTEL_COMPILER 00037 # define CO_STDEXT_TR1 00038 # else 00039 # define CO_STDEXT_EXT 00040 # ifndef EQ_HAVE_LONG_HASH 00041 # define EQ_HAVE_LONG_HASH 00042 # endif 00043 # endif 00044 #else 00045 # ifdef _MSC_VER 00046 # define CO_STDEXT_MSVC 00047 # else 00048 # define CO_STDEXT_STD 00049 # endif 00050 #endif 00051 00052 #ifdef CO_STDEXT_TR1 00053 # include <tr1/unordered_map> 00054 # include <tr1/unordered_set> 00055 /* Alias stde namespace to uniformly access stl extensions. */ 00056 namespace stde = std::tr1; 00057 # define CO_STDEXT_NAMESPACE_OPEN namespace std { namespace tr1 { 00058 # define CO_STDEXT_NAMESPACE_CLOSE }} 00059 #endif 00060 00061 #ifdef CO_STDEXT_EXT 00062 # include <ext/hash_map> 00063 # include <ext/hash_set> 00064 /* Alias stde namespace to uniformly access stl extensions. */ 00065 namespace stde = __gnu_cxx; 00066 # define CO_STDEXT_NAMESPACE_OPEN namespace __gnu_cxx { 00067 # define CO_STDEXT_NAMESPACE_CLOSE } 00068 #endif 00069 00070 #ifdef CO_STDEXT_MSVC 00071 # include <hash_map> 00072 # include <hash_set> 00073 /* Alias stde namespace to uniformly access stl extensions. */ 00074 namespace stde = stdext; 00075 # define CO_STDEXT_NAMESPACE_OPEN namespace stdext { 00076 # define CO_STDEXT_NAMESPACE_CLOSE } 00077 #endif 00078 00079 #ifdef CO_STDEXT_STD 00080 # include <hash_map> 00081 # include <hash_set> 00082 /* Alias stde namespace to uniformly access stl extensions. */ 00083 namespace stde = std; 00084 # define CO_STDEXT_NAMESPACE_OPEN namespace std { 00085 # define CO_STDEXT_NAMESPACE_CLOSE } 00086 #endif 00087 00088 00089 CO_STDEXT_NAMESPACE_OPEN 00090 00091 //----- Our extensions of the STL 00092 #ifdef CO_STDEXT_TR1 00093 # ifndef EQ_HAVE_HASH_MAP 00094 template<class K, class T, class H = hash< K >, 00095 class P = std::equal_to< K >, class A = std::allocator< K > > 00096 class hash_map : public unordered_map< K, T, H, P, A > 00097 { 00098 }; 00099 # endif // EQ_HAVE_HASH_MAP 00100 #endif 00101 00102 #ifdef CO_STDEXT_EXT 00103 # ifndef EQ_HAVE_STRING_HASH 00104 00105 template<> struct hash< std::string > 00106 { 00107 size_t operator()( const std::string& str ) const 00108 { 00109 return hash< const char* >()( str.c_str() ); 00110 } 00111 }; 00112 # endif // EQ_HAVE_STRING_HASH 00113 00114 # if !defined __INTEL_COMPILER 00115 # ifndef EQ_HAVE_LONG_HASH 00116 00117 template<> struct hash< uint64_t > 00118 { 00119 size_t operator()( const uint64_t& val ) const 00120 { 00121 // OPT: tr1 does the same, however it seems suboptimal on 32 bits 00122 // if the lower 32 bits never change, e.g., for ObjectVersion 00123 return static_cast< size_t >( val ); 00124 } 00125 }; 00126 # endif 00127 # endif // !__INTEL_COMPILER 00128 00129 # ifndef EQ_HAVE_VOID_PTR_HASH 00130 00131 template<> struct hash< void* > 00132 { 00133 template< typename P > 00134 size_t operator()( const P& key ) const 00135 { 00136 return reinterpret_cast<size_t>(key); 00137 } 00138 }; 00139 00140 template<> struct hash< const void* > 00141 { 00142 template< typename P > 00143 size_t operator()( const P& key ) const 00144 { 00145 return reinterpret_cast<size_t>(key); 00146 } 00147 }; 00148 # endif // EQ_HAVE_VOID_PTR_HASH 00149 #endif // CO_STDEXT_EXT 00150 00151 #ifdef CO_STDEXT_MSVC 00152 # ifndef EQ_HAVE_STRING_HASH 00153 00155 template<> inline size_t hash_compare< std::string >::operator() 00156 ( const std::string& key ) const 00157 { 00158 return hash_value( key.c_str( )); 00159 } 00160 00161 # endif 00162 00163 template<> inline size_t hash_compare< co::base::uint128_t >::operator() 00164 ( const co::base::uint128_t& key ) const 00165 { 00166 return static_cast< size_t >( key.high() ^ key.low() ); 00167 } 00168 00169 template<> inline size_t hash_value( const co::base::uint128_t& key ) 00170 { 00171 return static_cast< size_t >( key.high() ^ key.low() ); 00172 } 00173 00174 #else // MSVC 00175 00176 template<> struct hash< co::base::uint128_t > 00177 { 00178 size_t operator()( const co::base::uint128_t& key ) const 00179 { 00180 return key.high() ^ key.low(); 00181 } 00182 }; 00183 00184 #endif //! MSVC 00185 00190 template< typename C > void usort( C& c ) 00191 { 00192 std::sort( c.begin(), c.end( )); 00193 c.erase( std::unique( c.begin(), c.end( )), c.end( )); 00194 } 00195 00197 template< typename T > typename std::vector< T >::iterator 00198 find( std::vector< T >& container, const T& element ) 00199 { return std::find( container.begin(), container.end(), element ); } 00200 00202 template< typename T > typename std::vector< T >::const_iterator 00203 find( const std::vector< T >& container, const T& element ) 00204 { return std::find( container.begin(), container.end(), element ); } 00205 00207 template< typename T, typename P > typename std::vector< T >::iterator 00208 find_if( std::vector< T >& container, const P& predicate ) 00209 { return std::find_if( container.begin(), container.end(), predicate );} 00210 00212 template< typename T, typename P > typename std::vector<T>::const_iterator 00213 find_if( std::vector< const T >& container, const P& predicate ) 00214 { return std::find_if( container.begin(), container.end(), predicate );} 00215 00216 CO_STDEXT_NAMESPACE_CLOSE 00217 00218 #endif // COBASE_STDEXT_H