summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2012-07-28 09:48:18 -0400
committerNat Goodspeed <nat@lindenlab.com>2012-07-28 09:48:18 -0400
commitf37d109e251a273a1b620c416cef3991981e6184 (patch)
tree66403f3d3585d214137666e0cf5eeb656ee84df2 /indra/llcommon
parentfd7bfb03c946b0190bf0965e19b1b679eac3c383 (diff)
parent27cbfef0269146eb296bbd2b810a6d331e5cb7d2 (diff)
Automated merge with ssh://hg.lindenlab.com/nat/viewer-maint-1175
Diffstat (limited to 'indra/llcommon')
-rw-r--r--indra/llcommon/llinitparam.h32
-rw-r--r--indra/llcommon/llregistry.h24
-rw-r--r--indra/llcommon/llstl.h51
3 files changed, 71 insertions, 36 deletions
diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h
index 66c72c2d9f..9a6d1eff5c 100644
--- a/indra/llcommon/llinitparam.h
+++ b/indra/llcommon/llinitparam.h
@@ -35,7 +35,7 @@
#include <boost/shared_ptr.hpp>
#include "llerror.h"
-#include "lltypeinfolookup.h"
+#include "llstl.h"
namespace LLInitParam
{
@@ -220,9 +220,9 @@ namespace LLInitParam
typedef bool (*parser_write_func_t)(Parser& parser, const void*, name_stack_t&);
typedef boost::function<void (name_stack_t&, S32, S32, const possible_values_t*)> parser_inspect_func_t;
- typedef LLTypeInfoLookup<parser_read_func_t> parser_read_func_map_t;
- typedef LLTypeInfoLookup<parser_write_func_t> parser_write_func_map_t;
- typedef LLTypeInfoLookup<parser_inspect_func_t> parser_inspect_func_map_t;
+ typedef std::map<const std::type_info*, parser_read_func_t> parser_read_func_map_t;
+ typedef std::map<const std::type_info*, parser_write_func_t> parser_write_func_map_t;
+ typedef std::map<const std::type_info*, parser_inspect_func_t> parser_inspect_func_map_t;
Parser(parser_read_func_map_t& read_map, parser_write_func_map_t& write_map, parser_inspect_func_map_t& inspect_map)
: mParseSilently(false),
@@ -234,20 +234,20 @@ namespace LLInitParam
template <typename T> bool readValue(T& param)
{
- boost::optional<parser_read_func_t> found_it = mParserReadFuncs->find<T>();
- if (found_it)
+ parser_read_func_map_t::iterator found_it = mParserReadFuncs->find(&typeid(T));
+ if (found_it != mParserReadFuncs->end())
{
- return (*found_it)(*this, (void*)&param);
+ return found_it->second(*this, (void*)&param);
}
return false;
}
template <typename T> bool writeValue(const T& param, name_stack_t& name_stack)
{
- boost::optional<parser_write_func_t> found_it = mParserWriteFuncs->find<T>();
- if (found_it)
+ parser_write_func_map_t::iterator found_it = mParserWriteFuncs->find(&typeid(T));
+ if (found_it != mParserWriteFuncs->end())
{
- return (*found_it)(*this, (const void*)&param, name_stack);
+ return found_it->second(*this, (const void*)&param, name_stack);
}
return false;
}
@@ -255,10 +255,10 @@ namespace LLInitParam
// dispatch inspection to registered inspection functions, for each parameter in a param block
template <typename T> bool inspectValue(name_stack_t& name_stack, S32 min_count, S32 max_count, const possible_values_t* possible_values)
{
- boost::optional<parser_inspect_func_t> found_it = mParserInspectFuncs->find<T>();
- if (found_it)
+ parser_inspect_func_map_t::iterator found_it = mParserInspectFuncs->find(&typeid(T));
+ if (found_it != mParserInspectFuncs->end())
{
- (*found_it)(name_stack, min_count, max_count, possible_values);
+ found_it->second(name_stack, min_count, max_count, possible_values);
return true;
}
return false;
@@ -273,14 +273,14 @@ namespace LLInitParam
template <typename T>
void registerParserFuncs(parser_read_func_t read_func, parser_write_func_t write_func = NULL)
{
- mParserReadFuncs->insert<T>(read_func);
- mParserWriteFuncs->insert<T>(write_func);
+ mParserReadFuncs->insert(std::make_pair(&typeid(T), read_func));
+ mParserWriteFuncs->insert(std::make_pair(&typeid(T), write_func));
}
template <typename T>
void registerInspectFunc(parser_inspect_func_t inspect_func)
{
- mParserInspectFuncs->insert<T>(inspect_func);
+ mParserInspectFuncs->insert(std::make_pair(&typeid(T), inspect_func));
}
bool mParseSilently;
diff --git a/indra/llcommon/llregistry.h b/indra/llcommon/llregistry.h
index babc1b87aa..853c427a13 100644
--- a/indra/llcommon/llregistry.h
+++ b/indra/llcommon/llregistry.h
@@ -30,38 +30,22 @@
#include <list>
#include <boost/type_traits.hpp>
-#include <boost/static_assert.hpp>
#include "llsingleton.h"
+#include "llstl.h"
template <typename T>
struct LLRegistryDefaultComparator
{
- // It would be Bad if this comparison were used for const char*
- BOOST_STATIC_ASSERT(! (boost::is_same<typename boost::remove_const<typename boost::remove_pointer<T>::type>::type, char>::value));
- bool operator()(const T& lhs, const T& rhs) const { return lhs < rhs; }
-};
-
-// comparator for const char* registry keys
-template <>
-struct LLRegistryDefaultComparator<const char*>
-{
- bool operator()(const char* lhs, const char* rhs) const
+ bool operator()(const T& lhs, const T& rhs) const
{
- return strcmp(lhs, rhs) < 0;
+ using std::less;
+ return less<T>()(lhs, rhs);
}
};
template <typename KEY, typename VALUE, typename COMPARATOR = LLRegistryDefaultComparator<KEY> >
class LLRegistry
{
- // Do not use LLRegistry with KEY = std::type_info* or KEY = const std::type_info*.
- // This is known to fail on Linux.
- // If you must use LLRegistry with dynamic type info, use KEY = const char*
- // and pass std::type_info::name(); this works across load modules.
- // Disallow both std::type_info* and const std::type_info*. First remove
- // the pointer, then remove const, then compare is_same<std::type_info>.
- BOOST_STATIC_ASSERT(! (boost::is_same<typename boost::remove_const<typename boost::remove_pointer<KEY>::type>::type, std::type_info>::value));
-
public:
typedef LLRegistry<KEY, VALUE, COMPARATOR> registry_t;
typedef typename boost::add_reference<typename boost::add_const<KEY>::type>::type ref_const_key_t;
diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h
index 8ad12c9a03..d3941e1bc9 100644
--- a/indra/llcommon/llstl.h
+++ b/indra/llcommon/llstl.h
@@ -33,6 +33,7 @@
#include <vector>
#include <set>
#include <deque>
+#include <typeinfo>
// Use to compare the first element only of a pair
// e.g. typedef std::set<std::pair<int, Data*>, compare_pair<int, Data*> > some_pair_set_t;
@@ -470,4 +471,54 @@ llbind2nd(const _Operation& __oper, const _Tp& __x)
return llbinder2nd<_Operation>(__oper, _Arg2_type(__x));
}
+/**
+ * Compare std::type_info* pointers a la std::less. We break this out as a
+ * separate function for use in two different std::less specializations.
+ */
+inline
+bool before(const std::type_info* lhs, const std::type_info* rhs)
+{
+#if LL_LINUX && defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 4))
+ // If we're building on Linux with gcc, and it's either gcc 3.x or
+ // 4.{0,1,2,3}, then we have to use a workaround. Note that we use gcc on
+ // Mac too, and some people build with gcc on Windows (cygwin or mingw).
+ // On Linux, different load modules may produce different type_info*
+ // pointers for the same type. Have to compare name strings to get good
+ // results.
+ return strcmp(lhs->name(), rhs->name()) < 0;
+#else // not Linux, or gcc 4.4+
+ // Just use before(), as we normally would
+ return lhs->before(*rhs);
+#endif
+}
+
+/**
+ * Specialize std::less<std::type_info*> to use std::type_info::before().
+ * See MAINT-1175. It is NEVER a good idea to directly compare std::type_info*
+ * because, on Linux, you might get different std::type_info* pointers for the
+ * same type (from different load modules)!
+ */
+namespace std
+{
+ template <>
+ struct less<const std::type_info*>:
+ public std::binary_function<const std::type_info*, const std::type_info*, bool>
+ {
+ bool operator()(const std::type_info* lhs, const std::type_info* rhs) const
+ {
+ return before(lhs, rhs);
+ }
+ };
+
+ template <>
+ struct less<std::type_info*>:
+ public std::binary_function<std::type_info*, std::type_info*, bool>
+ {
+ bool operator()(std::type_info* lhs, std::type_info* rhs) const
+ {
+ return before(lhs, rhs);
+ }
+ };
+} // std
+
#endif // LL_LLSTL_H