Lunchbox  1.8.0
stdExt.h
Go to the documentation of this file.
1 
2 /* Copyright (c) 2006-2012, Stefan Eilemann <eile@equalizergraphics.com>
3  * 2010-2012, Daniel Nachbaur <danielnachbaur@gmail.com>
4  *
5  * This library is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU Lesser General Public License version 2.1 as published
7  * by the Free Software Foundation.
8  *
9  * This library is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12  * details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this library; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
25 #ifndef LUNCHBOX_STDEXT_H
26 #define LUNCHBOX_STDEXT_H
27 
28 #include <lunchbox/compiler.h>
29 #include <lunchbox/uint128_t.h>
30 #include <lunchbox/uuid.h>
31 
32 #include <algorithm>
33 #include <string>
34 #include <vector>
35 #ifdef LB_GCC_4_4_OR_LATER
36 # include <parallel/algorithm>
37 #endif
38 
39 //----- Common extensions of the STL
40 #ifdef __GNUC__
41 # if defined LB_GCC_4_3_OR_LATER && !defined __INTEL_COMPILER
42 # define LB_STDEXT_TR1
43 # elif defined __clang__
44 # define LB_STDEXT_TR1
45 # else
46 # define LB_STDEXT_EXT
47 # endif
48 #elif defined _MSC_VER
49 # define LB_STDEXT_MSVC
50 #elif defined __xlC__
51 # define LB_STDEXT_TR1
52 # define LB_STDEXT_TR1_BOOST
53 #else
54 # define LB_STDEXT_STD
55 #endif
56 
57 #ifdef LB_STDEXT_TR1
58 # ifdef LB_STDEXT_TR1_BOOST
59 # include <boost/tr1/functional.hpp>
60 # include <boost/tr1/unordered_map.hpp>
61 # include <boost/tr1/unordered_set.hpp>
62 # else
63 # include <tr1/unordered_map>
64 # include <tr1/unordered_set>
65 # endif
66 /* Alias stde namespace to uniformly access stl extensions. */
67 namespace stde = std::tr1;
68 # define LB_STDEXT_NAMESPACE_OPEN namespace std { namespace tr1 {
69 # define LB_STDEXT_NAMESPACE_CLOSE }}
70 #endif
71 
72 #ifdef LB_STDEXT_EXT
73 # include <ext/hash_map>
74 # include <ext/hash_set>
75 /* Alias stde namespace to uniformly access stl extensions. */
76 namespace stde = __gnu_cxx;
77 # define LB_STDEXT_NAMESPACE_OPEN namespace __gnu_cxx {
78 # define LB_STDEXT_NAMESPACE_CLOSE }
79 #endif
80 
81 #ifdef LB_STDEXT_MSVC
82 # include <hash_map>
83 # include <hash_set>
84 /* Alias stde namespace to uniformly access stl extensions. */
85 namespace stde = stdext;
86 # define LB_STDEXT_NAMESPACE_OPEN namespace stdext {
87 # define LB_STDEXT_NAMESPACE_CLOSE }
88 #endif
89 
90 #ifdef LB_STDEXT_STD
91 # include <hash_map>
92 # include <hash_set>
93 /* Alias stde namespace to uniformly access stl extensions. */
94 namespace stde = std;
95 # define LB_STDEXT_NAMESPACE_OPEN namespace std {
96 # define LB_STDEXT_NAMESPACE_CLOSE }
97 #endif
98 
99 
100 LB_STDEXT_NAMESPACE_OPEN
101 
102 //----- Our extensions of the STL
103 #ifdef LB_STDEXT_TR1
104 # ifndef LB_HAVE_HASH_MAP
105  template<class K, class T, class H = hash< K >,
106  class P = std::equal_to< K >, class A = std::allocator< K > >
107  class hash_map : public unordered_map< K, T, H, P, A >
108  {
109  };
110 # endif // LB_HAVE_HASH_MAP
111 # ifndef LB_HAVE_HASH_SET
112  template<class T, class H = hash< T >,
113  class P = std::equal_to< T >, class A = std::allocator< T > >
114  class hash_set : public unordered_set< T, H, P, A >
115  {
116  };
117 # endif // LB_HAVE_HASH_SET
118 #endif
119 
120 #ifdef LB_STDEXT_EXT
121 # ifndef LB_HAVE_STRING_HASH
122 
123  template<> struct hash< std::string >
124  {
125  size_t operator()( const std::string& str ) const
126  {
127  return hash< const char* >()( str.c_str() );
128  }
129  };
130 # endif // LB_HAVE_STRING_HASH
131 
132 # if !defined __INTEL_COMPILER
133 # ifndef LB_HAVE_LONG_HASH
134 
135  template<> struct hash< uint64_t >
136  {
137  size_t operator()( const uint64_t& val ) const
138  {
139  // OPT: tr1 does the same, however it seems suboptimal on 32 bits
140  // if the lower 32 bits never change, e.g., for ObjectVersion
141  return static_cast< size_t >( val );
142  }
143  };
144 # endif
145 # endif // !__INTEL_COMPILER
146 
147 # ifndef LB_HAVE_VOID_PTR_HASH
148 
149  template<> struct hash< void* >
150  {
151  template< typename P >
152  size_t operator()( const P& key ) const
153  {
154  return reinterpret_cast<size_t>(key);
155  }
156  };
157 
158  template<> struct hash< const void* >
159  {
160  template< typename P >
161  size_t operator()( const P& key ) const
162  {
163  return reinterpret_cast<size_t>(key);
164  }
165  };
166 # endif // LB_HAVE_VOID_PTR_HASH
167 #endif // LB_STDEXT_EXT
168 
169 #ifdef LB_STDEXT_MSVC
170 # ifndef LB_HAVE_STRING_HASH
171 
173  template<> inline size_t hash_compare< std::string >::operator()
174  ( const std::string& key ) const
175  {
176  return hash_value( key.c_str( ));
177  }
178 
179 # endif
180 
181  template<> inline size_t hash_compare< lunchbox::uint128_t >::operator()
182  ( const lunchbox::uint128_t& key ) const
183  {
184  return static_cast< size_t >( key.high() ^ key.low() );
185  }
186 
187  template<> inline size_t hash_value( const lunchbox::uint128_t& key )
188  {
189  return static_cast< size_t >( key.high() ^ key.low() );
190  }
191 
192  template<> inline size_t hash_compare< lunchbox::UUID >::operator()
193  ( const lunchbox::UUID& key ) const
194  {
195  return static_cast< size_t >( key.high() ^ key.low() );
196  }
197 
198  template<> inline size_t hash_value( const lunchbox::UUID& key )
199  {
200  return static_cast< size_t >( key.high() ^ key.low() );
201  }
202 
203 #else // MSVC
204 
206  template<> struct hash< lunchbox::uint128_t >
207  {
208  size_t operator()( const lunchbox::uint128_t& key ) const
209  {
210  return key.high() ^ key.low();
211  }
212  };
213 
215  template<> struct hash< lunchbox::UUID >
216  {
217  size_t operator()( const lunchbox::UUID& key ) const
218  {
219  return key.high() ^ key.low();
220  }
221  };
222 
223 #endif
224 
225 
229  template< typename C > void usort( C& c )
230  {
231  std::sort( c.begin(), c.end( ));
232  c.erase( std::unique( c.begin(), c.end( )), c.end( ));
233  }
234 
236 #ifdef LB_GCC_4_4_OR_LATER
237  using __gnu_parallel::sort;
238 #else
239  using std::sort;
240 #endif
241 
243  template< typename T > typename std::vector< T >::iterator
244  find( std::vector< T >& container, const T& element )
245  { return std::find( container.begin(), container.end(), element ); }
246 
248  template< typename T > typename std::vector< T >::const_iterator
249  find( const std::vector< T >& container, const T& element )
250  { return std::find( container.begin(), container.end(), element ); }
251 
253  template< typename T, typename P > typename std::vector< T >::iterator
254  find_if( std::vector< T >& container, const P& predicate )
255  { return std::find_if( container.begin(), container.end(), predicate );}
256 
258  template< typename T, typename P > typename std::vector<T>::const_iterator
259  find_if( std::vector< const T >& container, const P& predicate )
260  { return std::find_if( container.begin(), container.end(), predicate );}
261 
262 LB_STDEXT_NAMESPACE_CLOSE
263 
264 #endif // LUNCHBOX_STDEXT_H