2010-07-30 5 views
4

부스트 다중 인덱스에서 특정 인덱스 유형이 메타 프로그래밍을 통해 정렬되었는지 여부를 확인할 수 있습니까? 정렬 된 인덱스, 해시 인덱스, 시퀀스 인덱스 등이 있습니다. 메타 프로그래밍을 통해 찾을 수 있습니까?C++ 다중 인덱스 유형 식별 향상

int main() 
{ 
    typedef multi_index_container<double> double_set; 
    return 0; 
} 

나는 double_set 지수가 주문 또는 해시 또는 서열 여부를 알고 싶어

는 같은 인덱스가 가정하자. 물론이 경우에는 명령이 내려집니다.

+0

당신은 당신이 그것을 사용하려는 방법을 보여 수 있습니까? – GManNickG

답변

5

Yes (예) :

#include <boost/multi_index_container.hpp> 
#include <boost/multi_index/ordered_index.hpp> 
#include <boost/multi_index/hashed_index.hpp> 
#include <boost/multi_index/sequenced_index.hpp> 
#include <boost/multi_index/random_access_index.hpp> 

#include <boost/mpl/bool.hpp> 
#include <boost/mpl/or.hpp> 
#include <boost/mpl/at.hpp> 
#include <boost/mpl/not.hpp> 
#include <boost/mpl/distance.hpp> 
#include <boost/mpl/begin.hpp> 

namespace mpl = boost::mpl; 
namespace mi = boost::multi_index; 

// 
// checking for ordered_unique: 
// 
template <typename MI> 
struct is_nth_index_ordered_unique_helper : mpl::false_ {}; 

template <typename KeyFromValue, typename Compare> 
struct is_nth_index_ordered_unique_helper< 
    mi::ordered_unique<KeyFromValue,Compare> 
> : mpl::true_ {}; 

template <typename TagList, typename KeyFromValue, typename Compare> 
struct is_nth_index_ordered_unique_helper< 
    mi::ordered_unique<TagList,KeyFromValue,Compare> 
> : mpl::true_ {}; 

template <typename MI, int N> 
struct is_nth_index_ordered_unique 
    : is_nth_index_ordered_unique_helper< 
     typename mpl::at_c< typename MI::index_specifier_type_list, N >::type 
     > {}; 

// 
// checking for ordered_non_unique: 
// 

template <typename MI> 
struct is_nth_index_ordered_non_unique_helper : mpl::false_ {}; 

template <typename KeyFromValue, typename Compare> 
struct is_nth_index_ordered_non_unique_helper< 
    mi::ordered_non_unique<KeyFromValue,Compare> 
> : mpl::true_ {}; 

template <typename TagList, typename KeyFromValue, typename Compare> 
struct is_nth_index_ordered_non_unique_helper< 
    mi::ordered_non_unique<TagList,KeyFromValue,Compare> 
> : mpl::true_ {}; 

template <typename MI, int N> 
struct is_nth_index_ordered_non_unique 
    : is_nth_index_ordered_non_unique_helper< 
     typename mpl::at_c< typename MI::index_specifier_type_list, N >::type 
     > {}; 

// 
// Combined (ordered_{non_,}unique): 
// 

template <typename MI, int N> 
struct is_nth_index_ordered 
    : mpl::or_< 
     is_nth_index_ordered_unique<MI,N>, 
     is_nth_index_ordered_non_unique<MI,N> 
     > {}; 

// 
// checking for sequenced: 
// 

template <typename MI> 
struct is_nth_index_sequenced_helper : mpl::false_ {}; 

template <typename TagList> 
struct is_nth_index_sequenced_helper< 
    mi::sequenced<TagList> 
> : mpl::true_ {}; 

template <typename MI, int N> 
struct is_nth_index_sequenced 
    : is_nth_index_sequenced_helper< 
     typename mpl::at_c< typename MI::index_specifier_type_list, N >::type 
     > {}; 

// 
// test with example container: 
// 
typedef mi::multi_index_container<double> double_set_1; 

BOOST_MPL_ASSERT((is_nth_index_ordered<double_set_1,0>)); 
BOOST_MPL_ASSERT((mpl::not_< is_nth_index_sequenced<double_set_1,0> >)); 
// or 
BOOST_STATIC_ASSERT((is_nth_index_ordered<double_set_1,0>::value)); 
BOOST_STATIC_ASSERT((mpl::not_< is_nth_index_sequenced<double_set_1,0> >::value)); 

// 
// And now with tag dispatch: 
// 

template <typename MI, typename Tag> 
struct tag_to_n 
    : mpl::distance< 
      typename mpl::begin<typename MI::index_type_list>::type, 
      typename MI::template index<Tag>::iter 
     > {}; 

template <typename MI, typename Tag> 
struct is_tagged_index_ordered_unique 
    : is_nth_index_ordered_unique<MI,tag_to_n<MI,Tag>::value> {}; 

template <typename MI, typename Tag> 
struct is_tagged_index_ordered_non_unique 
    : is_nth_index_ordered_non_unique<MI,tag_to_n<MI,Tag>::value> {}; 

template <typename MI, typename Tag> 
struct is_tagged_index_ordered 
    : is_nth_index_ordered<MI,tag_to_n<MI,Tag>::value> {}; 

template <typename MI, typename Tag> 
struct is_tagged_index_sequenced 
    : is_nth_index_sequenced<MI,tag_to_n<MI,Tag>::value> {}; 


// 
// test with another example container: 
// 

struct as_set {}; 
struct as_list {}; 

typedef mi::multi_index_container< 
    double, 
    mi::indexed_by< 
     mi::sequenced< mi::tag<as_list> >, 
     mi::ordered_non_unique< mi::tag<as_set>, mi::identity<double> > 
    > 
> double_set_2; 

void fun() { 
    double_set_2 ds2; 
} 

BOOST_MPL_ASSERT((is_nth_index_sequenced<double_set_2,0>)); 
BOOST_MPL_ASSERT((is_nth_index_ordered<double_set_2,1>)); 
BOOST_MPL_ASSERT((mpl::not_< is_nth_index_ordered<double_set_2,0> >)); 
BOOST_MPL_ASSERT((mpl::not_< is_nth_index_sequenced<double_set_2,1> >)); 

BOOST_MPL_ASSERT((is_tagged_index_sequenced<double_set_2,as_list>)); 
BOOST_MPL_ASSERT((is_tagged_index_ordered<double_set_2,as_set>)); 
BOOST_MPL_ASSERT((mpl::not_< is_tagged_index_ordered<double_set_2,as_list> >)); 
BOOST_MPL_ASSERT((mpl::not_< is_tagged_index_sequenced<double_set_2,as_set> >));