【问题标题】:C++ Boost multi-index type identificationC++ Boost多索引类型识别
【发布时间】:2010-07-30 10:36:01
【问题描述】:

在 boost 多索引中,我是否可以通过元编程验证特定索引类型是否已排序? 有有序索引、散列索引、序列索引等,可以通过元编程找出来吗?

假设有一个像这样的索引:

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

我想知道 double_set 索引是有序的、散列的还是有序的。当然在这种情况下,它是有序的。

【问题讨论】:

  • 你能说明你想如何使用它吗?

标签: c++ boost multi-index


【解决方案1】:

是的:

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

【讨论】:

    猜你喜欢
    • 2015-10-23
    • 1970-01-01
    • 2012-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多