composite_key.hpp
来自「support vector clustering for vc++」· HPP 代码 · 共 1,316 行 · 第 1/3 页
HPP
1,316 行
>
struct compare_ckey_cval_normal
{
static bool compare(
const KeyCons& c,const Value& v,const ValCons& vc,
const CompareCons& comp)
{
if(comp.get_head()(c.get_head()(v),vc.get_head()))return true;
if(comp.get_head()(vc.get_head(),c.get_head()(v)))return false;
return compare_ckey_cval<
BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value,
BOOST_DEDUCED_TYPENAME ValCons::tail_type,
BOOST_DEDUCED_TYPENAME CompareCons::tail_type
>::compare(c.get_tail(),v,vc.get_tail(),comp.get_tail());
}
static bool compare(
const ValCons& vc,const KeyCons& c,const Value& v,
const CompareCons& comp)
{
if(comp.get_head()(vc.get_head(),c.get_head()(v)))return true;
if(comp.get_head()(c.get_head()(v),vc.get_head()))return false;
return compare_ckey_cval<
BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value,
BOOST_DEDUCED_TYPENAME ValCons::tail_type,
BOOST_DEDUCED_TYPENAME CompareCons::tail_type
>::compare(vc.get_tail(),c.get_tail(),v,comp.get_tail());
}
};
template
<
typename KeyCons,typename Value,
typename ValCons,typename CompareCons
>
struct compare_ckey_cval:
mpl::if_<
mpl::or_<
is_same<KeyCons,tuples::null_type>,
is_same<ValCons,tuples::null_type>
>,
compare_ckey_cval_terminal<KeyCons,Value,ValCons,CompareCons>,
compare_ckey_cval_normal<KeyCons,Value,ValCons,CompareCons>
>::type
{
};
template<typename KeyCons,typename Value,typename HashCons>
struct hash_ckey; /* fwd decl. */
template<typename KeyCons,typename Value,typename HashCons>
struct hash_ckey_terminal
{
static std::size_t hash(
const KeyCons&,const Value&,const HashCons&,std::size_t carry)
{
return carry;
}
};
template<typename KeyCons,typename Value,typename HashCons>
struct hash_ckey_normal
{
static std::size_t hash(
const KeyCons& c,const Value& v,const HashCons& h,std::size_t carry=0)
{
/* same hashing formula as boost::hash_combine */
carry^=h.get_head()(c.get_head()(v))+0x9e3779b9+(carry<<6)+(carry>>2);
return hash_ckey<
BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value,
BOOST_DEDUCED_TYPENAME HashCons::tail_type
>::hash(c.get_tail(),v,h.get_tail(),carry);
}
};
template<typename KeyCons,typename Value,typename HashCons>
struct hash_ckey:
mpl::if_<
is_same<KeyCons,tuples::null_type>,
hash_ckey_terminal<KeyCons,Value,HashCons>,
hash_ckey_normal<KeyCons,Value,HashCons>
>::type
{
};
template<typename ValCons,typename HashCons>
struct hash_cval; /* fwd decl. */
template<typename ValCons,typename HashCons>
struct hash_cval_terminal
{
static std::size_t hash(const ValCons&,const HashCons&,std::size_t carry)
{
return carry;
}
};
template<typename ValCons,typename HashCons>
struct hash_cval_normal
{
static std::size_t hash(
const ValCons& vc,const HashCons& h,std::size_t carry=0)
{
carry^=h.get_head()(vc.get_head())+0x9e3779b9+(carry<<6)+(carry>>2);
return hash_cval<
BOOST_DEDUCED_TYPENAME ValCons::tail_type,
BOOST_DEDUCED_TYPENAME HashCons::tail_type
>::hash(vc.get_tail(),h.get_tail(),carry);
}
};
template<typename ValCons,typename HashCons>
struct hash_cval:
mpl::if_<
is_same<ValCons,tuples::null_type>,
hash_cval_terminal<ValCons,HashCons>,
hash_cval_normal<ValCons,HashCons>
>::type
{
};
} /* namespace multi_index::detail */
/* composite_key_result */
template<typename CompositeKey>
struct composite_key_result
{
typedef CompositeKey composite_key_type;
typedef typename composite_key_type::value_type value_type;
composite_key_result(
const composite_key_type& composite_key_,const value_type& value_):
composite_key(composite_key_),value(value_)
{}
const composite_key_type& composite_key;
const value_type& value;
};
/* composite_key */
/* NB. Some overloads of operator() have an extra dummy parameter int=0.
* This disambiguator serves several purposes:
* - Without it, MSVC++ 6.0 incorrectly regards some overloads as
* specializations of a previous member function template.
* - MSVC++ 6.0/7.0 seem to incorrectly treat some different memfuns
* as if they have the same signature.
* - If remove_const is broken due to lack of PTS, int=0 avoids the
* declaration of memfuns with identical signature.
*/
template<
typename Value,
BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,KeyFromValue)
>
struct composite_key:
private tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(KeyFromValue)>
{
private:
typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(KeyFromValue)> super;
public:
typedef super key_extractor_tuple;
typedef Value value_type;
typedef composite_key_result<composite_key> result_type;
composite_key(
BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,KeyFromValue)):
super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k))
{}
composite_key(const key_extractor_tuple& x):super(x){}
const key_extractor_tuple& key_extractors()const{return *this;}
key_extractor_tuple& key_extractors(){return *this;}
template<typename ChainedPtr>
#if !defined(BOOST_NO_SFINAE)
typename disable_if<
is_convertible<const ChainedPtr&,const value_type&>,result_type>::type
#else
result_type
#endif
operator()(const ChainedPtr& x)const
{
return operator()(*x);
}
result_type operator()(const value_type& x)const
{
return result_type(*this,x);
}
result_type operator()(const reference_wrapper<const value_type>& x)const
{
return result_type(*this,x.get());
}
result_type operator()(const reference_wrapper<value_type>& x,int=0)const
{
return result_type(*this,x.get());
}
};
/* comparison operators */
/* == */
template<typename CompositeKey1,typename CompositeKey2>
inline bool operator==(
const composite_key_result<CompositeKey1>& x,
const composite_key_result<CompositeKey2>& y)
{
typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1;
typedef typename CompositeKey1::value_type value_type1;
typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2;
typedef typename CompositeKey2::value_type value_type2;
BOOST_STATIC_ASSERT(
tuples::length<key_extractor_tuple1>::value==
tuples::length<key_extractor_tuple2>::value);
return detail::equal_ckey_ckey<
key_extractor_tuple1,value_type1,
key_extractor_tuple2,value_type2,
detail::generic_operator_equal_tuple
>::compare(
x.composite_key.key_extractors(),x.value,
y.composite_key.key_extractors(),y.value,
detail::generic_operator_equal_tuple());
}
template<
typename CompositeKey,
BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)
>
inline bool operator==(
const composite_key_result<CompositeKey>& x,
const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& y)
{
typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
typedef typename CompositeKey::value_type value_type;
typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
BOOST_STATIC_ASSERT(
tuples::length<key_extractor_tuple>::value==
tuples::length<key_tuple>::value);
return detail::equal_ckey_cval<
key_extractor_tuple,value_type,
key_tuple,detail::generic_operator_equal_tuple
>::compare(
x.composite_key.key_extractors(),x.value,
y,detail::generic_operator_equal_tuple());
}
template
<
BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
typename CompositeKey
>
inline bool operator==(
const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x,
const composite_key_result<CompositeKey>& y)
{
typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
typedef typename CompositeKey::value_type value_type;
typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
BOOST_STATIC_ASSERT(
tuples::length<key_extractor_tuple>::value==
tuples::length<key_tuple>::value);
return detail::equal_ckey_cval<
key_extractor_tuple,value_type,
key_tuple,detail::generic_operator_equal_tuple
>::compare(
x,y.composite_key.key_extractors(),
y.value,detail::generic_operator_equal_tuple());
}
/* < */
template<typename CompositeKey1,typename CompositeKey2>
inline bool operator<(
const composite_key_result<CompositeKey1>& x,
const composite_key_result<CompositeKey2>& y)
{
typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1;
typedef typename CompositeKey1::value_type value_type1;
typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2;
typedef typename CompositeKey2::value_type value_type2;
return detail::compare_ckey_ckey<
key_extractor_tuple1,value_type1,
key_extractor_tuple2,value_type2,
detail::generic_operator_less_tuple
>::compare(
x.composite_key.key_extractors(),x.value,
y.composite_key.key_extractors(),y.value,
detail::generic_operator_less_tuple());
}
template
<
typename CompositeKey,
BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)
>
inline bool operator<(
const composite_key_result<CompositeKey>& x,
const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& y)
{
typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
typedef typename CompositeKey::value_type value_type;
typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
return detail::compare_ckey_cval<
key_extractor_tuple,value_type,
key_tuple,detail::generic_operator_less_tuple
>::compare(
x.composite_key.key_extractors(),x.value,
y,detail::generic_operator_less_tuple());
}
template
<
BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
typename CompositeKey
>
inline bool operator<(
const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x,
const composite_key_result<CompositeKey>& y)
{
typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
typedef typename CompositeKey::value_type value_type;
typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
return detail::compare_ckey_cval<
key_extractor_tuple,value_type,
key_tuple,detail::generic_operator_less_tuple
>::compare(
x,y.composite_key.key_extractors(),
y.value,detail::generic_operator_less_tuple());
}
/* rest of comparison operators */
#define BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(t1,t2,a1,a2) \
template<t1,t2> inline bool operator!=(const a1& x,const a2& y) \
{ \
return !(x==y); \
} \
\
template<t1,t2> inline bool operator>(const a1& x,const a2& y) \
{ \
return y<x; \
} \
\
template<t1,t2> inline bool operator>=(const a1& x,const a2& y) \
{ \
return !(x<y); \
} \
\
template<t1,t2> inline bool operator<=(const a1& x,const a2& y) \
{ \
return !(y<x); \
}
BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(
typename CompositeKey1,
typename CompositeKey2,
composite_key_result<CompositeKey1>,
composite_key_result<CompositeKey2>
)
BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(
typename CompositeKey,
BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
composite_key_result<CompositeKey>,
tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>
)
BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(
BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
typename CompositeKey,
tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>,
composite_key_result<CompositeKey>
)
/* composite_key_equal_to */
template
<
BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Pred)
>
struct composite_key_equal_to:
private tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Pred)>
{
private:
typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Pred)> super;
public:
typedef super key_eq_tuple;
composite_key_equal_to(
BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,Pred)):
super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k))
{}
composite_key_equal_to(const key_eq_tuple& x):super(x){}
const key_eq_tuple& key_eqs()const{return *this;}
key_eq_tuple& key_eqs(){return *this;}
template<typename CompositeKey1,typename CompositeKey2>
bool operator()(
const composite_key_result<CompositeKey1> & x,
const composite_key_result<CompositeKey2> & y)const
{
typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1;
typedef typename CompositeKey1::value_type value_type1;
typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2;
typedef typename CompositeKey2::value_type value_type2;
BOOST_STATIC_ASSERT(
tuples::length<key_extractor_tuple1>::value<=
tuples::length<key_eq_tuple>::value&&
tuples::length<key_extractor_tuple1>::value==
tuples::length<key_extractor_tuple2>::value);
return detail::equal_ckey_ckey<
key_extractor_tuple1,value_type1,
key_extractor_tuple2,value_type2,
key_eq_tuple
>::compare(
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?