Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Boost.MultiIndex Documentation - Tutorial - Techniques

Boost , , Boost.MultiIndex Documentation - Tutorial

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

Boost.MultiIndex Tutorial: Techniques



Contents

Emulating standard containers with multi_index_container

Emulation of associative containers

Помимо академических мотиваций, существует практический интерес к эмуляции стандартных ассоциативных контейнеров с помощью<multi_index_container>, а именно использовать расширенные функции, предоставляемые<multi_index_container>для поиска, запроса диапазона и обновления.

Для эмуляции<std::set>можно следовать правилу замены:

std::set<Key,Compare,Allocator> ->
  multi_index_container<
    Key,
    indexed_by<ordered_unique<identity<Key>,Compare> >,
    Allocator
  >

В случае по умолчанию, где<Compare=std::less<Key>>и<Allocator=std::allocator<Key>>, правило замещения упрощается как

std::set<Key> -> multi_index_container<Key>

Замена<multi_index_container>на<std::set>сохраняет весь набор функциональных возможностей, предоставляемых<std::set>, поэтому в принципе это замена, не требующая дальнейших корректировок.

<std::multiset>можно эмулировать аналогичным образом в соответствии со следующим правилом:

std::multiset<Key,Compare,Allocator> ->
  multi_index_container<
    Key,
    indexed_by<ordered_non_unique<identity<Key>,Compare> >,
    Allocator
  >

Когда принимаются во внимание значения по умолчанию, правило принимает форму

std::multiset<Key> ->
  multi_index_container<
    Key,
    indexed_by<ordered_non_unique<identity<Key> > >
  >

Эмуляция<std::multiset>s с<multi_index_container>приводит к незначительной разнице по отношению к предлагаемому интерфейсу: функция члена<insert(const value_type&)>возвращает<iterator>не как в<std::multiset>s, а скорее<std::pair<iterator,bool>>в духе<std::set>s. Однако в этом конкретном случае<bool>член возвращаемой пары всегда<true>.

<std::map>и<std::multimap>не поддаются такой прямой эмуляции<multi_index_container>. Основная проблема заключается в том, что элементы a<multi_index_container>рассматриваются как постоянные, в то время как<std::map>и<std::multimap>обрабатывают объекты типа<std::pair<const Key,T>>, что позволяет свободно изменять значение части. Чтобы преодолеть эту трудность, нам нужно создать специальный класс пары:

template <typename T1,typename T2>
struct mutable_pair
{
  typedef T1 first_type;
  typedef T2 second_type;
  mutable_pair():first(T1()),second(T2()){}
  mutable_pair(const T1& f,const T2& s):first(f),second(s){}
  mutable_pair(const std::pair<T1,T2>& p):first(p.first),second(p.second){}
  T1         first;
  mutable T2 second;
};

Правила замены таковы:

std::map<Key,T,Compare,Allocator> ->
  multi_index_container<
    Element,
    indexed_by<
      ordered_unique<member<Element,Key,&Element::first>,Compare>
    >,
    typename Allocator::template rebind<Element>::other
  >
std::multimap<Key,T,Compare,Allocator> ->
  multi_index_container<
    Element,
    indexed_by<
      ordered_non_unique<member<Element,Key,&Element::first>,Compare>
    >,
    typename Allocator::template rebind<Element>::other
  >
(with Element=mutable_pair<Key,T>)

При рассмотрении значений по умолчанию правила принимают форму:

std::map<Key,T> ->
  multi_index_container<
    Element,
    indexed_by<ordered_unique<member<Element,Key,&Element::first> > >
  >
std::multimap<Key,T> ->
  multi_index_container<
    Element,
    indexed_by<ordered_non_unique<member<Element,Key,&Element::first> > >
  >
(with Element=mutable_pair<Key,T>)

В отличие от стандартных наборов, интерфейс этих<multi_index_container>эмулированных карт не совсем соответствует интерфейсу<std::map>и<std::multimap>. Наиболее очевидным отличием является отсутствие<operator []>, либо в режиме чтения, либо в режиме записи; это, однако, можно эмулировать с соответствующим использованием<find>и<insert>.

Эти эмуляции стандартных ассоциативных контейнеров с<multi_index_container>сопоставимы с оригинальными конструкциями с точки зрения пространственной и временной эффективности. Подробнее см. вразделе.

Emulation of std::list

В отличие от ассоциативных контейнеров, эмулирующих<std::list>в Boost. MultiIndex не добавляет какой-либо существенной функциональности, поэтому следующее представлено только для полноты.

Как и в случае со стандартными картами, основная трудность, которую приходится преодолевать при эмуляции<std::list>, связана с постоянной природой элементов<multi_index_container>. Опять же, необходим какой-то класс адаптации, например:

template <typename T>
struct mutable_value
{
  mutable_value(const T& t):t(t){}
  operator T&()const{return t;}
private:
  mutable T t;
};

Что позволяет использовать правило замещения:

std::list<T,Allocator> ->
  multi_index_container<
    Element,
    indexed_by<sequenced<> >,
    typename Allocator::template rebind<Element>::other
  >
(with Element=mutable_value<T>)

Если используется значение по умолчанию<Allocator=std::allocator<T>>:

std::list<T> ->
  multi_index_container<mutable_value<T>,indexed_by<sequenced<> > >

Metaprogramming and multi_index_container

Повышаю. MultiIndex предоставляет ряд возможностей, предназначенных для анализа и синтеза<multi_index_container>инстанциаций метапрограммамиMPL.

MPL analysis

Учитывая<multi_index_container>инстанциацию, для компиляционного контроля различных типов, происходящих в определении<multi_index_container>:

  • < [19] >,
  • < [21] >,
  • < [23] >,
  • < [25] >.
Каждый из этих типов представляет собой последовательность MPL с таким количеством элементов, что индексы составляют<multi_index_container>: например,<n>- элемент<iterator_type_list>такой же, как<nth_index<n>::type::iterator>.index_specifier_type_list,
  • index_type_list,
  • iterator_type_list,
  • const_iterator_type_list.
  • Each of these types is an MPL sequence with as many elements as indices comprise the multi_index_container: for instance, the n-th element of iterator_type_list is the same as nth_index<n>::type::iterator. [ORIG_END] -->

    Существует тонкое, но важное различие между<index_specifier_type_list>и<index_type_list>: В первом типологическом списке указаны указатели, с помощью которых была определена инстанциация<multi_index_container>, а в последнем доступны фактические классы реализации, соответствующие каждому спецификатору. Пример поможет прояснить это различие. Учитывая инстанциацию:

    typedef multi_index_container<
      int,
      indexed_by<
        ordered_unique<identity<int> >,
        sequenced<>
      >
    > indexed_t;
    

    <indexed_t::index_specifier_type_list>Список типов с элементами

    ordered_unique<identity<int> >
    sequenced<>
    

    При этом<indexed_t::index_type_list>человек

    multi_index_container::nth_type<0>::type
    multi_index_container::nth_type<1>::type
    

    Таким образом, списки типов радикально отличаются. Проверьтессылкудля точных концепций последовательности MPL, смоделированных этими списками типов.

    MPL synthesis

    Хотя обычно индексы определяются с помощью конструкции<indexed_by>, на самом деле вместо этого может быть предоставлена любая последовательность MPL указателей индексов:

    typedef mpl::vector<ordered_unique<identity<int> >,sequenced<> > index_list_t;
    typedef multi_index_container<
      int,
      index_list_t
    > indexed_t;
    

    Эта возможность позволяет синтезировать инстанциации<multi_index_container>через метапрограммы MPL, как показывает следующий пример:

    // original multi_index_container instantiation
    typedef multi_index_container<
      int,
      indexed_by<
        ordered_unique<identity<int> >
      >
    >                                indexed_t1;
    // we take its index list and add an index
    typedef boost::mpl::push_front<
      indexed_t1::index_specifier_type_list,
      sequenced<>
    >::type                          index_list_t;
    // augmented multi_index_container
    typedef multi_index_container<
      int,
      index_list_t
    >                                indexed_t2;
    



    Пересмотрено 7 ноября 2008 года

    © Copyright 2003-2008 Joaquín M López Muñoz. Распространяется под лицензией Boost Software License, версия 1.0. (См. сопроводительный файлLICENSE_1_0.txtили копию на) http://www.boost.org/LICENSE_1_0.txt

    Статья Boost.MultiIndex Documentation - Tutorial - Techniques раздела Boost.MultiIndex Documentation - Tutorial может быть полезна для разработчиков на c++ и boost.




    Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



    :: Главная :: Boost.MultiIndex Documentation - Tutorial ::


    реклама


    ©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
    Top.Mail.Ru

    Время компиляции файла: 2024-08-30 11:47:00
    2025-05-19 20:18:53/0.009984016418457/1