You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
221 lines
6.6 KiB
221 lines
6.6 KiB
|
|
// Copyright (C) 2005-2011 Daniel James |
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying |
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
|
|
|
#ifndef BOOST_UNORDERED_DETAIL_EXTRACT_KEY_HPP_INCLUDED |
|
#define BOOST_UNORDERED_DETAIL_EXTRACT_KEY_HPP_INCLUDED |
|
|
|
#include <boost/unordered/detail/table.hpp> |
|
|
|
namespace boost { |
|
namespace unordered { |
|
namespace detail { |
|
|
|
// key extractors |
|
// |
|
// no throw |
|
// |
|
// 'extract_key' is called with the emplace parameters to return a |
|
// key if available or 'no_key' is one isn't and will need to be |
|
// constructed. This could be done by overloading the emplace implementation |
|
// for the different cases, but that's a bit tricky on compilers without |
|
// variadic templates. |
|
|
|
struct no_key { |
|
no_key() {} |
|
template <class T> no_key(T const&) {} |
|
}; |
|
|
|
template <typename Key, typename T> |
|
struct is_key { |
|
template <typename T2> |
|
static choice1::type test(T2 const&); |
|
static choice2::type test(Key const&); |
|
|
|
enum { value = sizeof(test(boost::unordered::detail::make<T>())) == |
|
sizeof(choice2::type) }; |
|
|
|
typedef typename boost::detail::if_true<value>:: |
|
BOOST_NESTED_TEMPLATE then<Key const&, no_key>::type type; |
|
}; |
|
|
|
template <class ValueType> |
|
struct set_extractor |
|
{ |
|
typedef ValueType value_type; |
|
typedef ValueType key_type; |
|
|
|
static key_type const& extract(key_type const& v) |
|
{ |
|
return v; |
|
} |
|
|
|
#if BOOST_UNORDERED_USE_RV_REF |
|
static key_type const& extract(BOOST_RV_REF(key_type) v) |
|
{ |
|
return v; |
|
} |
|
#endif |
|
|
|
static no_key extract() |
|
{ |
|
return no_key(); |
|
} |
|
|
|
#if defined(BOOST_UNORDERED_STD_FORWARD_MOVE) |
|
template <class... Args> |
|
static no_key extract(Args const&...) |
|
{ |
|
return no_key(); |
|
} |
|
|
|
#else |
|
template <class Arg> |
|
static no_key extract(Arg const&) |
|
{ |
|
return no_key(); |
|
} |
|
|
|
template <class Arg1, class Arg2> |
|
static no_key extract(Arg1 const&, Arg2 const&) |
|
{ |
|
return no_key(); |
|
} |
|
#endif |
|
|
|
static bool compare_mapped(value_type const&, value_type const&) |
|
{ |
|
return true; |
|
} |
|
}; |
|
|
|
template <class Key, class ValueType> |
|
struct map_extractor |
|
{ |
|
typedef ValueType value_type; |
|
typedef typename boost::remove_const<Key>::type key_type; |
|
|
|
static key_type const& extract(value_type const& v) |
|
{ |
|
return v.first; |
|
} |
|
|
|
static key_type const& extract(key_type const& v) |
|
{ |
|
return v; |
|
} |
|
|
|
// TODO: Why does this cause errors? |
|
// |
|
//static key_type const& extract(BOOST_RV_REF(key_type) v) |
|
//{ |
|
// return v; |
|
//} |
|
|
|
template <class Second> |
|
static key_type const& extract(std::pair<key_type, Second> const& v) |
|
{ |
|
return v.first; |
|
} |
|
|
|
template <class Second> |
|
static key_type const& extract( |
|
std::pair<key_type const, Second> const& v) |
|
{ |
|
return v.first; |
|
} |
|
|
|
#if defined(BOOST_UNORDERED_STD_FORWARD_MOVE) |
|
template <class Arg1, class... Args> |
|
static key_type const& extract(key_type const& k, |
|
Arg1 const&, Args const&...) |
|
{ |
|
return k; |
|
} |
|
|
|
template <class... Args> |
|
static no_key extract(Args const&...) |
|
{ |
|
return no_key(); |
|
} |
|
#else |
|
|
|
template <class Arg1> |
|
static key_type const& extract(key_type const& k, Arg1 const&) |
|
{ |
|
return k; |
|
} |
|
|
|
static no_key extract() |
|
{ |
|
return no_key(); |
|
} |
|
|
|
template <class Arg> |
|
static no_key extract(Arg const&) |
|
{ |
|
return no_key(); |
|
} |
|
|
|
template <class Arg, class Arg1> |
|
static no_key extract(Arg const&, Arg1 const&) |
|
{ |
|
return no_key(); |
|
} |
|
#endif |
|
|
|
#if defined(BOOST_UNORDERED_STD_FORWARD_MOVE) |
|
|
|
#define BOOST_UNORDERED_KEY_FROM_TUPLE(namespace_) \ |
|
template <typename T2> \ |
|
static no_key extract(boost::unordered::piecewise_construct_t, \ |
|
namespace_::tuple<> const&, T2&&) \ |
|
{ \ |
|
return no_key(); \ |
|
} \ |
|
\ |
|
template <typename T, typename T2> \ |
|
static typename is_key<key_type, T>::type \ |
|
extract(boost::unordered::piecewise_construct_t, \ |
|
namespace_::tuple<T> const& k, T2&&) \ |
|
{ \ |
|
return typename is_key<key_type, T>::type( \ |
|
namespace_::get<0>(k)); \ |
|
} |
|
|
|
#else |
|
|
|
#define BOOST_UNORDERED_KEY_FROM_TUPLE(namespace_) \ |
|
static no_key extract(boost::unordered::piecewise_construct_t, \ |
|
namespace_::tuple<> const&) \ |
|
{ \ |
|
return no_key(); \ |
|
} \ |
|
\ |
|
template <typename T> \ |
|
static typename is_key<key_type, T>::type \ |
|
extract(boost::unordered::piecewise_construct_t, \ |
|
namespace_::tuple<T> const& k) \ |
|
{ \ |
|
return typename is_key<key_type, T>::type( \ |
|
namespace_::get<0>(k)); \ |
|
} |
|
|
|
#endif |
|
|
|
BOOST_UNORDERED_KEY_FROM_TUPLE(boost) |
|
|
|
#if !defined(BOOST_NO_0X_HDR_TUPLE) |
|
BOOST_UNORDERED_KEY_FROM_TUPLE(std) |
|
#endif |
|
|
|
|
|
static bool compare_mapped(value_type const& x, value_type const& y) |
|
{ |
|
return x.second == y.second; |
|
} |
|
}; |
|
}}} |
|
|
|
#endif
|
|
|