summaryrefslogtreecommitdiff
path: root/src/base
diff options
context:
space:
mode:
Diffstat (limited to 'src/base')
-rw-r--r--src/base/hashmap.hh113
-rw-r--r--src/base/inifile.cc1
-rw-r--r--src/base/range.hh8
-rw-r--r--src/base/stats/text.cc8
4 files changed, 115 insertions, 15 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__
diff --git a/src/base/inifile.cc b/src/base/inifile.cc
index 451198033..91e37f327 100644
--- a/src/base/inifile.cc
+++ b/src/base/inifile.cc
@@ -29,6 +29,7 @@
* Steve Reinhardt
*/
+#include <algorithm>
#include <fstream>
#include <iostream>
#include <string>
diff --git a/src/base/range.hh b/src/base/range.hh
index d9542c0ca..ac64a37f9 100644
--- a/src/base/range.hh
+++ b/src/base/range.hh
@@ -316,7 +316,13 @@ template <class T, class U>
inline bool
operator<(const Range<T> &range, const U &pos)
{
- return range.end < pos;
+ // with -std=gnu++0x, gcc and clang get confused when range.end is
+ // compared to pos using the operator "<", and the parser expects it
+ // to be the opening bracket for a template parameter,
+ // i.e. range.end<pos>(...);, the reason seems to be the range-type
+ // iteration introduced in c++11 where begin and end are members
+ // that return iterators
+ return operator<(range.end, pos);
}
/**
diff --git a/src/base/stats/text.cc b/src/base/stats/text.cc
index 8fb49dc59..28541ff59 100644
--- a/src/base/stats/text.cc
+++ b/src/base/stats/text.cc
@@ -166,7 +166,7 @@ ValueToString(Result value, int precision)
{
stringstream val;
- if (!isnan(value)) {
+ if (!std::isnan(value)) {
if (precision != -1)
val.precision(precision);
else if (value == rint(value))
@@ -211,15 +211,15 @@ void
ScalarPrint::operator()(ostream &stream) const
{
if ((flags.isSet(nozero) && value == 0.0) ||
- (flags.isSet(nonan) && isnan(value)))
+ (flags.isSet(nonan) && std::isnan(value)))
return;
stringstream pdfstr, cdfstr;
- if (!isnan(pdf))
+ if (!std::isnan(pdf))
ccprintf(pdfstr, "%.2f%%", pdf * 100.0);
- if (!isnan(cdf))
+ if (!std::isnan(cdf))
ccprintf(cdfstr, "%.2f%%", cdf * 100.0);
ccprintf(stream, "%-40s %12s %10s %10s", name,