MAINT-1175: Ditch LLTypeInfoLookup, make map<const type_info*> work.
Instead of forbidding std::map<const std::type_info*, ...> outright (which includes LLRegistry<const std::type_info*, ...> and LLRegistrySingleton<const std::type_info*, ...>), try to make it work by specializing std::less<const std::type_info*> to use std::type_info::before(). Make LLRegistryDefaultComparator<T> use std::less<T> so it can capitalize on that specialization.master
parent
5e1e44ca7e
commit
2e83dfa217
|
|
@ -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*)¶m);
|
||||
return found_it->second(*this, (void*)¶m);
|
||||
}
|
||||
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*)¶m, name_stack);
|
||||
return found_it->second(*this, (const void*)¶m, 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;
|
||||
|
|
|
|||
|
|
@ -31,44 +31,18 @@
|
|||
|
||||
#include <boost/type_traits.hpp>
|
||||
#include "llsingleton.h"
|
||||
#include "lltypeinfolookup.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>
|
||||
struct LLRegistryMapSelector
|
||||
{
|
||||
typedef std::map<KEY, VALUE> type;
|
||||
};
|
||||
|
||||
template <typename VALUE>
|
||||
struct LLRegistryMapSelector<std::type_info*, VALUE>
|
||||
{
|
||||
typedef LLTypeInfoLookup<VALUE> type;
|
||||
};
|
||||
|
||||
template <typename VALUE>
|
||||
struct LLRegistryMapSelector<const std::type_info*, VALUE>
|
||||
{
|
||||
typedef LLTypeInfoLookup<VALUE> type;
|
||||
};
|
||||
|
||||
template <typename KEY, typename VALUE, typename COMPARATOR = LLRegistryDefaultComparator<KEY> >
|
||||
class LLRegistry
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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,33 @@ llbind2nd(const _Operation& __oper, const _Tp& __x)
|
|||
return llbinder2nd<_Operation>(__oper, _Arg2_type(__x));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 lhs->before(*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 lhs->before(*rhs);
|
||||
}
|
||||
};
|
||||
} // std
|
||||
|
||||
#endif // LL_LLSTL_H
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "llinitparam.h"
|
||||
#include "llregistry.h"
|
||||
#include "llxuiparser.h"
|
||||
#include "llstl.h"
|
||||
|
||||
class LLView;
|
||||
|
||||
|
|
@ -62,14 +63,14 @@ protected:
|
|||
|
||||
// lookup widget name by type
|
||||
class LLWidgetNameRegistry
|
||||
: public LLRegistrySingleton<const std::type_info*, std::string, LLWidgetNameRegistry , LLCompareTypeID>
|
||||
: public LLRegistrySingleton<const std::type_info*, std::string, LLWidgetNameRegistry>
|
||||
{};
|
||||
|
||||
// lookup function for generating empty param block by widget type
|
||||
// this is used for schema generation
|
||||
//typedef const LLInitParam::BaseBlock& (*empty_param_block_func_t)();
|
||||
//class LLDefaultParamBlockRegistry
|
||||
//: public LLRegistrySingleton<const std::type_info*, empty_param_block_func_t, LLDefaultParamBlockRegistry, LLCompareTypeID>
|
||||
//: public LLRegistrySingleton<const std::type_info*, empty_param_block_func_t, LLDefaultParamBlockRegistry>
|
||||
//{};
|
||||
|
||||
extern LLFastTimer::DeclareTimer FTM_WIDGET_SETUP;
|
||||
|
|
|
|||
Loading…
Reference in New Issue