mirror of
https://github.com/boostorg/multi_index.git
synced 2025-05-11 13:24:04 +00:00
improved lookup efficiency in the event of implicit conversion to key_type
This commit is contained in:
parent
87ff899ceb
commit
79541fce51
103
include/boost/multi_index/detail/is_transparent.hpp
Normal file
103
include/boost/multi_index/detail/is_transparent.hpp
Normal file
@ -0,0 +1,103 @@
|
||||
/* Copyright 2003-2014 Joaquin M Lopez Munoz.
|
||||
* 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)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_IS_TRANSPARENT_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_IS_TRANSPARENT_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/type_traits/intrinsics.hpp>
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
/* Metafunction that checks if f(arg,arg2) executes without argument type
|
||||
* conversion. By default (i.e. when it cannot be determined) it evaluates to
|
||||
* true.
|
||||
*/
|
||||
|
||||
template<typename F,typename Arg1,typename Arg2,typename=void>
|
||||
struct is_transparent:mpl::true_{};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#if !defined(BOOST_NO_SFINAE)&& \
|
||||
!defined(BOOST_NO_CXX11_DECLTYPE)&& \
|
||||
defined(BOOST_IS_FINAL)
|
||||
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
#include <boost/type_traits/is_class.hpp>
|
||||
#include <boost/type_traits/is_final.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/utility/declval.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
struct not_is_transparent_result_type{};
|
||||
|
||||
template<typename F,typename Arg1,typename Arg2>
|
||||
struct is_transparent_class_helper:F
|
||||
{
|
||||
using F::operator();
|
||||
template<typename T,typename Q>
|
||||
not_is_transparent_result_type operator()(T,Q)const;
|
||||
};
|
||||
|
||||
template<typename F,typename Arg1,typename Arg2,typename=void>
|
||||
struct is_transparent_class:mpl::true_{};
|
||||
|
||||
template<typename F,typename Arg1,typename Arg2>
|
||||
struct is_transparent_class<
|
||||
F,Arg1,Arg2,
|
||||
typename enable_if<
|
||||
is_same<
|
||||
decltype(
|
||||
declval<const is_transparent_class_helper<F,Arg1,Arg2> >()(
|
||||
declval<const Arg1&>(),declval<const Arg2&>())
|
||||
),
|
||||
not_is_transparent_result_type
|
||||
>
|
||||
>::type
|
||||
>:mpl::false_{};
|
||||
|
||||
template<typename F,typename Arg1,typename Arg2>
|
||||
struct is_transparent<
|
||||
F,Arg1,Arg2,
|
||||
typename enable_if<
|
||||
mpl::and_<
|
||||
is_class<F>,
|
||||
mpl::not_<is_final<F> >
|
||||
>
|
||||
>::type
|
||||
>:is_transparent_class<F,Arg1,Arg2>{};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
||||
#endif
|
@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2014 Joaquin M Lopez Munoz.
|
||||
* 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)
|
||||
@ -41,6 +41,8 @@
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/multi_index/detail/promotes_arg.hpp>
|
||||
#include <utility>
|
||||
|
||||
namespace boost{
|
||||
@ -51,6 +53,9 @@ namespace detail{
|
||||
|
||||
/* Common code for index memfuns having templatized and
|
||||
* non-templatized versions.
|
||||
* Implementation note: When CompatibleKey is consistently promoted to
|
||||
* KeyFromValue::result_type for comparison, the promotion is made once in
|
||||
* advance to increase efficiency.
|
||||
*/
|
||||
|
||||
template<
|
||||
@ -60,6 +65,35 @@ template<
|
||||
inline Node* ordered_index_find(
|
||||
Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
|
||||
const CompatibleCompare& comp)
|
||||
{
|
||||
typedef typename KeyFromValue::result_type key_type;
|
||||
|
||||
return ordered_index_find(
|
||||
top,y,key,x,comp,
|
||||
mpl::and_<
|
||||
promotes_1st_arg<CompatibleCompare,CompatibleKey,key_type>,
|
||||
promotes_2nd_arg<CompatibleCompare,key_type,CompatibleKey>>());
|
||||
}
|
||||
|
||||
template<
|
||||
typename Node,typename KeyFromValue,
|
||||
typename CompatibleCompare
|
||||
>
|
||||
inline Node* ordered_index_find(
|
||||
Node* top,Node* y,const KeyFromValue& key,
|
||||
const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x,
|
||||
const CompatibleCompare& comp,mpl::true_)
|
||||
{
|
||||
return ordered_index_find(top,y,key,x,comp,mpl::false_());
|
||||
}
|
||||
|
||||
template<
|
||||
typename Node,typename KeyFromValue,
|
||||
typename CompatibleKey,typename CompatibleCompare
|
||||
>
|
||||
inline Node* ordered_index_find(
|
||||
Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
|
||||
const CompatibleCompare& comp,mpl::false_)
|
||||
{
|
||||
Node* y0=y;
|
||||
|
||||
@ -81,6 +115,33 @@ template<
|
||||
inline Node* ordered_index_lower_bound(
|
||||
Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
|
||||
const CompatibleCompare& comp)
|
||||
{
|
||||
typedef typename KeyFromValue::result_type key_type;
|
||||
|
||||
return ordered_index_lower_bound(
|
||||
top,y,key,x,comp,
|
||||
promotes_2nd_arg<CompatibleCompare,key_type,CompatibleKey>());
|
||||
}
|
||||
|
||||
template<
|
||||
typename Node,typename KeyFromValue,
|
||||
typename CompatibleCompare
|
||||
>
|
||||
inline Node* ordered_index_lower_bound(
|
||||
Node* top,Node* y,const KeyFromValue& key,
|
||||
const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x,
|
||||
const CompatibleCompare& comp,mpl::true_)
|
||||
{
|
||||
return ordered_index_lower_bound(top,y,key,x,comp,mpl::false_());
|
||||
}
|
||||
|
||||
template<
|
||||
typename Node,typename KeyFromValue,
|
||||
typename CompatibleKey,typename CompatibleCompare
|
||||
>
|
||||
inline Node* ordered_index_lower_bound(
|
||||
Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
|
||||
const CompatibleCompare& comp,mpl::false_)
|
||||
{
|
||||
while(top){
|
||||
if(!comp(key(top->value()),x)){
|
||||
@ -100,6 +161,33 @@ template<
|
||||
inline Node* ordered_index_upper_bound(
|
||||
Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
|
||||
const CompatibleCompare& comp)
|
||||
{
|
||||
typedef typename KeyFromValue::result_type key_type;
|
||||
|
||||
return ordered_index_upper_bound(
|
||||
top,y,key,x,comp,
|
||||
promotes_1st_arg<CompatibleCompare,CompatibleKey,key_type>());
|
||||
}
|
||||
|
||||
template<
|
||||
typename Node,typename KeyFromValue,
|
||||
typename CompatibleCompare
|
||||
>
|
||||
inline Node* ordered_index_upper_bound(
|
||||
Node* top,Node* y,const KeyFromValue& key,
|
||||
const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x,
|
||||
const CompatibleCompare& comp,mpl::true_)
|
||||
{
|
||||
return ordered_index_upper_bound(top,y,key,x,comp,mpl::false_());
|
||||
}
|
||||
|
||||
template<
|
||||
typename Node,typename KeyFromValue,
|
||||
typename CompatibleKey,typename CompatibleCompare
|
||||
>
|
||||
inline Node* ordered_index_upper_bound(
|
||||
Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
|
||||
const CompatibleCompare& comp,mpl::false_)
|
||||
{
|
||||
while(top){
|
||||
if(comp(x,key(top->value()))){
|
||||
@ -119,6 +207,35 @@ template<
|
||||
inline std::pair<Node*,Node*> ordered_index_equal_range(
|
||||
Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
|
||||
const CompatibleCompare& comp)
|
||||
{
|
||||
typedef typename KeyFromValue::result_type key_type;
|
||||
|
||||
return ordered_index_equal_range(
|
||||
top,y,key,x,comp,
|
||||
mpl::and_<
|
||||
promotes_1st_arg<CompatibleCompare,CompatibleKey,key_type>,
|
||||
promotes_2nd_arg<CompatibleCompare,key_type,CompatibleKey>>());
|
||||
}
|
||||
|
||||
template<
|
||||
typename Node,typename KeyFromValue,
|
||||
typename CompatibleCompare
|
||||
>
|
||||
inline std::pair<Node*,Node*> ordered_index_equal_range(
|
||||
Node* top,Node* y,const KeyFromValue& key,
|
||||
const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x,
|
||||
const CompatibleCompare& comp,mpl::true_)
|
||||
{
|
||||
return ordered_index_equal_range(top,y,key,x,comp,mpl::false_());
|
||||
}
|
||||
|
||||
template<
|
||||
typename Node,typename KeyFromValue,
|
||||
typename CompatibleKey,typename CompatibleCompare
|
||||
>
|
||||
inline std::pair<Node*,Node*> ordered_index_equal_range(
|
||||
Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
|
||||
const CompatibleCompare& comp,mpl::false_)
|
||||
{
|
||||
while(top){
|
||||
if(comp(key(top->value()),x)){
|
||||
@ -130,8 +247,10 @@ inline std::pair<Node*,Node*> ordered_index_equal_range(
|
||||
}
|
||||
else{
|
||||
return std::pair<Node*,Node*>(
|
||||
ordered_index_lower_bound(Node::from_impl(top->left()),top,key,x,comp),
|
||||
ordered_index_upper_bound(Node::from_impl(top->right()),y,key,x,comp));
|
||||
ordered_index_lower_bound(
|
||||
Node::from_impl(top->left()),top,key,x,comp,mpl::false_()),
|
||||
ordered_index_upper_bound(
|
||||
Node::from_impl(top->right()),y,key,x,comp,mpl::false_()));
|
||||
}
|
||||
}
|
||||
|
||||
|
83
include/boost/multi_index/detail/promotes_arg.hpp
Normal file
83
include/boost/multi_index/detail/promotes_arg.hpp
Normal file
@ -0,0 +1,83 @@
|
||||
/* Copyright 2003-2014 Joaquin M Lopez Munoz.
|
||||
* 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)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_PROMOTES_ARG_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_PROMOTES_ARG_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/type_traits/intrinsics.hpp>
|
||||
|
||||
/* Metafunctions to check if f(arg1,arg2) promotes either arg1 to the type of
|
||||
* arg2 or viceversa. By default, (i.e. if it cannot be determined), no
|
||||
* promotion is assumed.
|
||||
*/
|
||||
|
||||
#if !defined(BOOST_IS_CONVERTIBLE)
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
template<typename F,typename Arg1,typename Arg2>
|
||||
struct promotes_1st_arg:mpl::false_{};
|
||||
|
||||
template<typename F,typename Arg1,typename Arg2>
|
||||
struct promotes_2nd_arg:mpl::false_{};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#else
|
||||
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
#include <boost/multi_index/detail/is_transparent.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
template<typename F,typename Arg1,typename Arg2>
|
||||
struct promotes_1st_arg:
|
||||
mpl::and_<
|
||||
mpl::not_<is_transparent<F,Arg1,Arg2> >,
|
||||
is_convertible<const Arg1,Arg2>,
|
||||
is_transparent<F,Arg2,Arg2>
|
||||
>
|
||||
{};
|
||||
|
||||
template<typename F,typename Arg1,typename Arg2>
|
||||
struct promotes_2nd_arg:
|
||||
mpl::and_<
|
||||
mpl::not_<is_transparent<F,Arg1,Arg2> >,
|
||||
is_convertible<const Arg2,Arg1>,
|
||||
is_transparent<F,Arg1,Arg1>
|
||||
>
|
||||
{};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif /* defined(BOOST_IS_CONVERTIBLE) */
|
||||
#endif
|
@ -32,6 +32,7 @@
|
||||
#include <boost/multi_index/detail/hash_index_iterator.hpp>
|
||||
#include <boost/multi_index/detail/index_node_base.hpp>
|
||||
#include <boost/multi_index/detail/modify_key_adaptor.hpp>
|
||||
#include <boost/multi_index/detail/promotes_arg.hpp>
|
||||
#include <boost/multi_index/detail/safe_mode.hpp>
|
||||
#include <boost/multi_index/detail/scope_guard.hpp>
|
||||
#include <boost/multi_index/detail/vartempl_support.hpp>
|
||||
@ -459,6 +460,11 @@ public:
|
||||
* type as iterator.
|
||||
*/
|
||||
|
||||
/* Implementation note: When CompatibleKey is consistently promoted to
|
||||
* KeyFromValue::result_type for equality comparison, the promotion is made
|
||||
* once in advance to increase efficiency.
|
||||
*/
|
||||
|
||||
template<typename CompatibleKey>
|
||||
iterator find(const CompatibleKey& k)const
|
||||
{
|
||||
@ -472,14 +478,8 @@ public:
|
||||
const CompatibleKey& k,
|
||||
const CompatibleHash& hash,const CompatiblePred& eq)const
|
||||
{
|
||||
std::size_t buc=buckets.position(hash(k));
|
||||
for(node_impl_pointer x=buckets.at(buc)->prior();
|
||||
x!=node_impl_pointer(0);x=node_alg::next_to_inspect(x)){
|
||||
if(eq(k,key(node_type::from_impl(x)->value()))){
|
||||
return make_iterator(node_type::from_impl(x));
|
||||
}
|
||||
}
|
||||
return end();
|
||||
return find(
|
||||
k,hash,eq,promotes_1st_arg<CompatiblePred,CompatibleKey,key_type>());
|
||||
}
|
||||
|
||||
template<typename CompatibleKey>
|
||||
@ -495,20 +495,8 @@ public:
|
||||
const CompatibleKey& k,
|
||||
const CompatibleHash& hash,const CompatiblePred& eq)const
|
||||
{
|
||||
std::size_t buc=buckets.position(hash(k));
|
||||
for(node_impl_pointer x=buckets.at(buc)->prior();
|
||||
x!=node_impl_pointer(0);x=node_alg::next_to_inspect(x)){
|
||||
if(eq(k,key(node_type::from_impl(x)->value()))){
|
||||
size_type res=0;
|
||||
node_impl_pointer y=end_of_range(x);
|
||||
do{
|
||||
++res;
|
||||
x=node_alg::after(x);
|
||||
}while(x!=y);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return count(
|
||||
k,hash,eq,promotes_1st_arg<CompatiblePred,CompatibleKey,key_type>());
|
||||
}
|
||||
|
||||
template<typename CompatibleKey>
|
||||
@ -524,16 +512,8 @@ public:
|
||||
const CompatibleKey& k,
|
||||
const CompatibleHash& hash,const CompatiblePred& eq)const
|
||||
{
|
||||
std::size_t buc=buckets.position(hash(k));
|
||||
for(node_impl_pointer x=buckets.at(buc)->prior();
|
||||
x!=node_impl_pointer(0);x=node_alg::next_to_inspect(x)){
|
||||
if(eq(k,key(node_type::from_impl(x)->value()))){
|
||||
return std::pair<iterator,iterator>(
|
||||
make_iterator(node_type::from_impl(x)),
|
||||
make_iterator(node_type::from_impl(end_of_range(x))));
|
||||
}
|
||||
}
|
||||
return std::pair<iterator,iterator>(end(),end());
|
||||
return equal_range(
|
||||
k,hash,eq,promotes_1st_arg<CompatiblePred,CompatibleKey,key_type>());
|
||||
}
|
||||
|
||||
/* bucket interface */
|
||||
@ -1527,6 +1507,95 @@ private:
|
||||
return make_iterator(p.first);
|
||||
}
|
||||
|
||||
template<
|
||||
typename CompatibleHash,typename CompatiblePred
|
||||
>
|
||||
iterator find(
|
||||
const key_type& k,
|
||||
const CompatibleHash& hash,const CompatiblePred& eq,mpl::true_)const
|
||||
{
|
||||
return find(k,hash,eq,mpl::false());
|
||||
}
|
||||
|
||||
template<
|
||||
typename CompatibleKey,typename CompatibleHash,typename CompatiblePred
|
||||
>
|
||||
iterator find(
|
||||
const CompatibleKey& k,
|
||||
const CompatibleHash& hash,const CompatiblePred& eq,mpl::false_)const
|
||||
{
|
||||
std::size_t buc=buckets.position(hash(k));
|
||||
for(node_impl_pointer x=buckets.at(buc)->prior();
|
||||
x!=node_impl_pointer(0);x=node_alg::next_to_inspect(x)){
|
||||
if(eq(k,key(node_type::from_impl(x)->value()))){
|
||||
return make_iterator(node_type::from_impl(x));
|
||||
}
|
||||
}
|
||||
return end();
|
||||
}
|
||||
|
||||
template<
|
||||
typename CompatibleHash,typename CompatiblePred
|
||||
>
|
||||
size_type count(
|
||||
const key_type& k,
|
||||
const CompatibleHash& hash,const CompatiblePred& eq,mpl::true_)const
|
||||
{
|
||||
return count(k,hash,eq,mpl::false());
|
||||
}
|
||||
|
||||
template<
|
||||
typename CompatibleKey,typename CompatibleHash,typename CompatiblePred
|
||||
>
|
||||
size_type count(
|
||||
const CompatibleKey& k,
|
||||
const CompatibleHash& hash,const CompatiblePred& eq,mpl::false_)const
|
||||
{
|
||||
std::size_t buc=buckets.position(hash(k));
|
||||
for(node_impl_pointer x=buckets.at(buc)->prior();
|
||||
x!=node_impl_pointer(0);x=node_alg::next_to_inspect(x)){
|
||||
if(eq(k,key(node_type::from_impl(x)->value()))){
|
||||
size_type res=0;
|
||||
node_impl_pointer y=end_of_range(x);
|
||||
do{
|
||||
++res;
|
||||
x=node_alg::after(x);
|
||||
}while(x!=y);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<
|
||||
typename CompatibleHash,typename CompatiblePred
|
||||
>
|
||||
std::pair<iterator,iterator> equal_range(
|
||||
const key_type& k,
|
||||
const CompatibleHash& hash,const CompatiblePred& eq,mpl::true_)const
|
||||
{
|
||||
return equal_range(k,hash,eq,mpl::false_());
|
||||
}
|
||||
|
||||
template<
|
||||
typename CompatibleKey,typename CompatibleHash,typename CompatiblePred
|
||||
>
|
||||
std::pair<iterator,iterator> equal_range(
|
||||
const CompatibleKey& k,
|
||||
const CompatibleHash& hash,const CompatiblePred& eq,mpl::false_)const
|
||||
{
|
||||
std::size_t buc=buckets.position(hash(k));
|
||||
for(node_impl_pointer x=buckets.at(buc)->prior();
|
||||
x!=node_impl_pointer(0);x=node_alg::next_to_inspect(x)){
|
||||
if(eq(k,key(node_type::from_impl(x)->value()))){
|
||||
return std::pair<iterator,iterator>(
|
||||
make_iterator(node_type::from_impl(x)),
|
||||
make_iterator(node_type::from_impl(end_of_range(x))));
|
||||
}
|
||||
}
|
||||
return std::pair<iterator,iterator>(end(),end());
|
||||
}
|
||||
|
||||
key_from_value key;
|
||||
hasher hash_;
|
||||
key_equal eq_;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Boost.MultiIndex test for standard set operations.
|
||||
*
|
||||
* Copyright 2003-2013 Joaquin M Lopez Munoz.
|
||||
* Copyright 2003-2014 Joaquin M Lopez Munoz.
|
||||
* 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)
|
||||
@ -19,6 +19,34 @@
|
||||
|
||||
using namespace boost::multi_index;
|
||||
|
||||
struct type1{};
|
||||
|
||||
struct type2
|
||||
{
|
||||
private:
|
||||
operator type1()const{return type1();}
|
||||
};
|
||||
|
||||
struct less_type12
|
||||
{
|
||||
bool operator()(type1,type1)const{return false;}
|
||||
bool operator()(type1,type2)const{return false;}
|
||||
bool operator()(type2,type1)const{return false;}
|
||||
};
|
||||
|
||||
struct hash_type12
|
||||
{
|
||||
std::size_t operator()(type1)const{return 0;}
|
||||
std::size_t operator()(type2)const{return 0;}
|
||||
};
|
||||
|
||||
struct eq_type12
|
||||
{
|
||||
bool operator()(type1,type1)const{return true;}
|
||||
bool operator()(type1,type2)const{return true;}
|
||||
bool operator()(type2,type1)const{return true;}
|
||||
};
|
||||
|
||||
void test_set_ops()
|
||||
{
|
||||
employee_set es;
|
||||
@ -55,4 +83,26 @@ void test_set_ops()
|
||||
std::pair<employee_set_by_age::iterator,employee_set_by_age::iterator> p2=
|
||||
i2.equal_range(30);
|
||||
BOOST_TEST(p2.first==p2.second&&p2.first->age==31);
|
||||
|
||||
/* check promotion detection plays nice with private conversion */
|
||||
|
||||
multi_index_container<
|
||||
type1,
|
||||
indexed_by<
|
||||
ordered_unique<identity<type1>,less_type12>,
|
||||
hashed_unique<identity<type1>,hash_type12,eq_type12>
|
||||
>
|
||||
> c;
|
||||
c.insert(type1());
|
||||
|
||||
BOOST_TEST(c.find(type2())==c.begin());
|
||||
BOOST_TEST(c.count(type2())==1);
|
||||
BOOST_TEST(c.lower_bound(type2())==c.begin());
|
||||
BOOST_TEST(c.upper_bound(type2())==c.end());
|
||||
BOOST_TEST(c.equal_range(type2())==std::make_pair(c.begin(),c.end()));
|
||||
|
||||
BOOST_TEST(c.get<1>().find(type2())==c.get<1>().begin());
|
||||
BOOST_TEST(c.get<1>().count(type2())==1);
|
||||
BOOST_TEST(c.get<1>().equal_range(type2())==
|
||||
std::make_pair(c.get<1>().begin(),c.get<1>().end()));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user