Lunchbox  1.10.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
stdExt.h
Go to the documentation of this file.
1 
2 /* Copyright (c) 2006-2013, Stefan Eilemann <eile@equalizergraphics.com>
3  * 2010-2014, 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 
26 #ifndef LUNCHBOX_STDEXT_H
27 #define LUNCHBOX_STDEXT_H
28 
29 #include <lunchbox/algorithm.h> // usort
30 #include <lunchbox/compiler.h>
31 #include <lunchbox/uint128_t.h>
32 
33 #include <algorithm>
34 #include <string>
35 #include <vector>
36 #ifdef LB_USE_STD_PARALLEL
37 # include <parallel/algorithm>
38 #endif
39 
40 //----- Common extensions of the STL
41 #ifdef CXX_UNORDERED_MAP_SUPPORTED
42 # define LB_STDEXT_STD
43 # define LB_STDEXT_STD11
44 #elif defined __GNUC__
45 # if defined LB_GCC_4_3_OR_LATER && !defined __INTEL_COMPILER
46 # define LB_STDEXT_TR1
47 # elif defined __clang__
48 # define LB_STDEXT_TR1
49 # else
50 # define LB_STDEXT_EXT
51 # endif
52 #elif defined _MSC_VER
53 # define LB_STDEXT_MSVC
54 #elif defined __xlC__
55 # define LB_STDEXT_TR1
56 # define LB_STDEXT_TR1_BOOST
57 #else
58 # define LB_STDEXT_STD
59 #endif
60 
61 #ifdef LB_STDEXT_TR1
62 # ifdef LB_STDEXT_TR1_BOOST
63 # include <boost/tr1/functional.hpp>
64 # include <boost/tr1/unordered_map.hpp>
65 # include <boost/tr1/unordered_set.hpp>
66 # else
67 # include <tr1/unordered_map>
68 # include <tr1/unordered_set>
69 # endif
70 /* Alias stde namespace to uniformly access stl extensions. */
71 namespace stde = std::tr1;
72 # define LB_STDEXT_NAMESPACE_OPEN namespace std { namespace tr1 {
73 # define LB_STDEXT_NAMESPACE_CLOSE }}
74 #endif
75 
76 #ifdef LB_STDEXT_EXT
77 # include <ext/hash_map>
78 # include <ext/hash_set>
79 /* Alias stde namespace to uniformly access stl extensions. */
80 namespace stde = __gnu_cxx;
81 # define LB_STDEXT_NAMESPACE_OPEN namespace __gnu_cxx {
82 # define LB_STDEXT_NAMESPACE_CLOSE }
83 #endif
84 
85 #ifdef LB_STDEXT_MSVC
86 # include <hash_map>
87 # include <hash_set>
88 /* Alias stde namespace to uniformly access stl extensions. */
89 namespace stde = stdext;
90 # define LB_STDEXT_NAMESPACE_OPEN namespace stdext {
91 # define LB_STDEXT_NAMESPACE_CLOSE }
92 #endif
93 
94 #ifdef LB_STDEXT_STD
95 # ifdef LB_STDEXT_STD11
96 # include <unordered_map>
97 # include <unordered_set>
98 # else
99 # include <hash_map>
100 # include <hash_set>
101 # endif
102 /* Alias stde namespace to uniformly access stl extensions. */
103 namespace stde = std;
104 # define LB_STDEXT_NAMESPACE_OPEN namespace std {
105 # define LB_STDEXT_NAMESPACE_CLOSE }
106 #endif
107 
108 
109 LB_STDEXT_NAMESPACE_OPEN
110 
111 //----- Our extensions of the STL
112 #if defined LB_STDEXT_TR1 || defined LB_STDEXT_STD11
113 # ifndef LB_HAVE_HASH_MAP
114 # ifdef CXX_TEMPLATE_ALIAS_SUPPORTED
115 template< class K, class T, class H = hash< K >, class P = std::equal_to< K >,
116  class A = std::allocator< std::pair< const K, T > > >
117 using hash_map = unordered_map< K, T, H, P, A >;
118 # else
119 template< class K, class T, class H = hash< K >, class P = std::equal_to< K >,
120  class A = std::allocator< std::pair< const K, T > > >
121 class hash_map : public unordered_map< K, T, H, P, A > {};
122 # endif
123 # endif // LB_HAVE_HASH_MAP
124 # ifndef LB_HAVE_HASH_SET
125 # ifdef CXX_TEMPLATE_ALIAS_SUPPORTED
126 template< class T, class H = hash< T >,
127  class P = std::equal_to< T >, class A = std::allocator< T > >
128 using hash_set = unordered_set< T, H, P, A >;
129 # else
130 template< class T, class H = hash< T >,
131  class P = std::equal_to< T >, class A = std::allocator< T > >
132 class hash_set : public unordered_set< T, H, P, A > {};
133 # endif
134 # endif // LB_HAVE_HASH_SET
135 #endif
136 
137 #ifdef LB_STDEXT_EXT
138 # ifndef LB_HAVE_STRING_HASH
139 
140 template<> struct hash< std::string >
141 {
142  size_t operator()( const std::string& str ) const
143  { return hash< const char* >()( str.c_str() ); }
144 };
145 # endif // LB_HAVE_STRING_HASH
146 
147 # if !defined __INTEL_COMPILER
148 # ifndef LB_HAVE_LONG_HASH
149 
150 template<> struct hash< uint64_t >
151 {
152  size_t operator()( const uint64_t& val ) const
153  {
154  // OPT: tr1 does the same, however it seems suboptimal on 32 bits if the
155  // lower 32 bits never change, e.g., for ObjectVersion
156  return static_cast< size_t >( val );
157  }
158 };
159 # endif
160 # endif // !__INTEL_COMPILER
161 
162 # ifndef LB_HAVE_VOID_PTR_HASH
163 
164 template<> struct hash< void* >
165 {
166  template< typename P > size_t operator()( const P& key ) const
167  { return reinterpret_cast<size_t>(key); }
168 };
169 
170 template<> struct hash< const void* >
171 {
172  template< typename P > size_t operator()( const P& key ) const
173  { return reinterpret_cast<size_t>(key); }
174 };
175 # endif // LB_HAVE_VOID_PTR_HASH
176 #endif // LB_STDEXT_EXT
177 
178 #ifdef LB_STDEXT_MSVC
179 # ifndef LB_HAVE_STRING_HASH
180 
182 template<> inline
183 size_t hash_compare< std::string >::operator() ( const std::string& key ) const
184  { return hash_value( key.c_str( )); }
185 
186 # endif
187 
188 template<> inline size_t hash_compare< lunchbox::uint128_t >::operator()
189  ( const lunchbox::uint128_t& key ) const
190 {
191  return static_cast< size_t >( key.high() ^ key.low() );
192 }
193 
194 template<> inline size_t hash_value( const lunchbox::uint128_t& key )
195  { return static_cast< size_t >( key.high() ^ key.low() ); }
196 #else // MSVC
197 
199 template<> struct hash< lunchbox::uint128_t >
200 {
201  size_t operator()( const lunchbox::uint128_t& key ) const
202  { return key.high() ^ key.low(); }
203 };
204 #endif
205 
206 
207 template< typename C > void usort( C& c ) { lunchbox::usort( c ); }
208 
209 #ifndef LB_STDEXT_STD
210 
211 # ifdef LB_GCC_4_4_OR_LATER
212 using __gnu_parallel::sort;
213 # else
214 using std::sort;
215 # endif
216 #endif
217 
218 LB_STDEXT_NAMESPACE_CLOSE
219 
220 
221 #endif // LUNCHBOX_STDEXT_H
const uint64_t & high() const
Definition: uint128_t.h:244
const uint64_t & low() const
Definition: uint128_t.h:242
A base type for 128 bit unsigned integer values.
Definition: uint128_t.h:46
void usort(C &c)
MSVC.
Definition: stdExt.h:207
void usort(C &c)
Uniquely sort and eliminate duplicates in a container.
Definition: algorithm.h:62