diff options
Diffstat (limited to 'src/base/hashmap.hh')
-rw-r--r-- | src/base/hashmap.hh | 113 |
1 files changed, 103 insertions, 10 deletions
diff --git a/src/base/hashmap.hh b/src/base/hashmap.hh index e3a72bcf5..ce9325881 100644 --- a/src/base/hashmap.hh +++ b/src/base/hashmap.hh @@ -1,4 +1,16 @@ /* + * Copyright (c) 2012 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2003-2005 The Regents of The University of Michigan * All rights reserved. * @@ -26,29 +38,106 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: Nathan Binkert + * Andreas Hansson */ #ifndef __HASHMAP_HH__ #define __HASHMAP_HH__ -#if defined(__GNUC__) && __GNUC__ >= 3 +#if defined(__GNUC__) + +// for compilers that deprecate ext/hash_map, i.e. gcc >= 4.3 and +// clang, use unordered_map + +// we need to determine what is available, as in the non-c++0x case, +// e.g. gcc >= 4.3 and <= 4.5, the containers are in the std::tr1 +// namespace, and only gcc >= 4.6 (with -std=c++0x) adds the final +// container implementation in the std namespace + +#if defined(__clang__) +// align with -std=c++0x only for clang >= 3.0 in CCFLAGS and also +// check if the header is present as this depends on what clang was +// built against, using XCode clang 3.1, for example, the header is +// not present without adding -stdlib=libc++ +#if (__clang_major__ >= 3 && __has_include(<unordered_map>)) +#define HAVE_STD_UNORDERED_MAP 1 +#else +// we only support clang versions above 2.9 and these all have the tr1 +// unordered_map +#define HAVE_STD_TR1_UNORDERED_MAP 1 +#endif +#else +// align with -std=c++0x only for gcc >= 4.6 in CCFLAGS, contrary to +// clang we can rely entirely on the compiler version +#if ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4) +#define HAVE_STD_UNORDERED_MAP 1 +#else +#define HAVE_STD_TR1_UNORDERED_MAP 1 +#endif +#endif + +// set a default value of 0 +#ifndef HAVE_STD_UNORDERED_MAP +#define HAVE_STD_UNORDERED_MAP 0 +#endif + +// set a default value of 0 +#ifndef HAVE_STD_TR1_UNORDERED_MAP +#define HAVE_STD_TR1_UNORDERED_MAP 0 +#endif + +// now we are ready to deal with the actual includes based on what is +// available +#if (HAVE_STD_UNORDERED_MAP || HAVE_STD_TR1_UNORDERED_MAP) + +#define hash_map unordered_map +#define hash_multimap unordered_multimap +#define hash_set unordered_set +#define hash_multiset unordered_multiset + +// these versions also have an existing hash function for strings +#define HAVE_STRING_HASH 1 + +#if HAVE_STD_UNORDERED_MAP + +// clang or gcc >= 4.6 +#include <unordered_map> +#include <unordered_set> +// note that this assumes that -std=c++0x is added to the command line +// which is done in the SConstruct CXXFLAGS for gcc >= 4.6 and clang +// >= 3.0 +#define __hash_namespace std +#define __hash_namespace_begin namespace std { +#define __hash_namespace_end } +#else +// clang <= 3.0, gcc >= 4.3 and < 4.6 +#include <tr1/unordered_map> +#include <tr1/unordered_set> +#define __hash_namespace std::tr1 +#define __hash_namespace_begin namespace std { namespace tr1 { +#define __hash_namespace_end } } +#endif +#else +// gcc < 4.3 #include <ext/hash_map> #include <ext/hash_set> +#define __hash_namespace __gnu_cxx +#define __hash_namespace_begin namespace __gnu_cxx { +#define __hash_namespace_end } +#endif #else +// non GNU compiler #include <hash_map> #include <hash_set> +#define __hash_namsepace std +#define __hash_namespace_begin namespace std { +#define __hash_namespace_end } #endif #include <string> #include "base/types.hh" -#if defined(__GNUC__) && __GNUC__ >= 3 - #define __hash_namespace __gnu_cxx -#else - #define __hash_namespace std -#endif - namespace m5 { using ::__hash_namespace::hash_multimap; using ::__hash_namespace::hash_multiset; @@ -62,8 +151,8 @@ namespace m5 { // Some default Hashing Functions // -namespace __hash_namespace { -#if defined(__APPLE__) || !defined(__LP64__) && !defined(__alpha__) && !defined(__SUNPRO_CC) +__hash_namespace_begin +#if !defined(__LP64__) && !defined(__alpha__) && !defined(__SUNPRO_CC) template<> struct hash<uint64_t> { size_t operator()(uint64_t r) const { @@ -79,6 +168,9 @@ namespace __hash_namespace { }; #endif +// if the hash functions for strings are not already defined, then +// declare them here +#if !defined(HAVE_STRING_HASH) template<> struct hash<std::string> { size_t operator()(const std::string &s) const { @@ -92,6 +184,7 @@ namespace __hash_namespace { return (__stl_hash_string(r.first.c_str())) ^ r.second; } }; -} // namespace __hash_namespace +#endif +__hash_namespace_end #endif // __HASHMAP_HH__ |