2010-07-30 61 views
4

在boost多索引中,我可以驗證特定索引類型是否通過元編程來排序嗎? 有順序索引,散列索引,序列索引等。我可以通過元編程找到它們嗎?C++ Boost多索引類型識別

假設有像指數:

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

我想知道double_set指數是否是有序或散列或測序。當然在這種情況下,它是有序的。

+0

你能告訴你想如何使用它? – GManNickG 2010-07-30 21:45:59

回答

5

是:

#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> >));