C++, Последовательности и контейнеры
От: sergey_shandar США http://getboost.codeplex.com/
Дата: 28.08.04 05:40
Оценка: 28 (3)
Развитие вот этой темы
Автор: _nn_
Дата: 25.08.04
(пары begin() и end()) в библиотеке kafe. Там еще много всего, в том числе реализация некоторых идей которые обсуждались на RSDN/C++ форуме. Многое еще не оформленно толком, но некоторые вещи уже, как говориться, устаканились, поэтому и вынес их в kafe 0.2 и на публичное обозрение.


1. Алгоритмы

В стандартной библиотеке якзыка C++ во многих алгоритмах использется пара итераторов, определяющая начало и конец последовательности. Например, функция std::for_each принимает начало последовательности и конец последовательности. Обычно, это выглядит так:
std::for_each(C.begin(), C.end(), F);
где C это может быть какой то контейнет, например std::vector<int>, а F какой то функтор. Но можно было бы передавать в функции не C.begin(), C.end(), а просто C. Выглядеть должно это так:
kafe::for_each(C, F);
Такой набор функций, принимающих последовательности или контейнеры вместо пары итераторов реализован в <kafe/algorithm.hpp>.

Иногда нужно передать не begin() и end() в качестве последовательности, а два других итератора, например, подпоследовательность. По прежнему можно воспользоваться стандартным набором алгоритмов из <algorithm>. В некоторых случаях можно воспользоваться специальными методами, такими как make_sequence.



2. Контейнеры

Описание файла <kafe/container.hpp>.

2. 1. Последовательность
template<class Iterator> class kafe::sequence — последовательность обладающая свойствами контейнера. Содержит в себе итераторы на первый и на следующий за последним элемент какой то последовательности.
namespace kafe
{

template<class Iterator>
class sequence
{
public:
    typedef Iterator iterator;
    typedef Iterator const_iterator;
    ...

    sequence(Iterator Begin, Iterator End);
    
    const_iterator begin() const;
    const_iterator end() const;
    iterator begin();
    iterator end();
    ...
};

}


Для создания последовательностей можно использовать функцию make_sequence.
namespace kafe
{

template<class Iterator>
sequence<Iterator> make_sequence(Iterator Begin, Iterator End);

}


2. 2. Ссылка на массив
В языке C++ обычные C массивы не обладают свойствами C++ контейнера. Обычно, работа с такими массивами выглядит так:
#include <algorithm>
int Array[] = { 3, 4, -456, 0x56A, 8355 };
int main()
{
    std::sort(Array, Array + 5);
}


Такой способ не очень удобен. Для работы с такими массивом лучше использовать kafe::array_ref обладающего свойствами контейнера.
namespace kafe
{

template<class ValueType>
class array_ref: public sequence<ValueType *>
{
public:
    template<size_t Size>
    array_ref(ValueType (&X)[Size]);
    ...
};

}


Для создания array_ref можно использовать make_array_ref:
namespace kafe
{
template<class ValueType, size_t Size>
array_ref<ValueType> make_array_ref(ValueType (&X)[Size]);
}
тогда предыдущий пример будет выглядеть так:
#include <kafe/algorithm.hpp>
#include <kafe/container.hpp>
int Array[] = { 3, 4, -456, 0x56A, 8355 };
int main()
{
    kafe::sort(kafe::make_array_ref(Array));
}


2. 3. Реализация стандартного контейнера
К С++ контейнерам предьявляеться достаточно много требований по реалиализации множества методов (таких как begin(), end(), empty(), size() и т.д.) и обьявления множества типов (таких как const_iterator, iterator, value_type и т.д.). Многие из этих типов можно обьявить используя std::iterator_traits, и многие из этих методов можно реализовать при помощи других методов, например, empty() как { return begin() == end(); }. Оболочка для реализаций контейнеров — template<class Base> class kafe::container::implementation.

namespace kafe
{
namespace container
{

template<class Base>
class implementation: public Base
{
public:
    typedef ... const_pointer;
    typedef ... const_value_type;
    typedef ... const_reference;
    typedef ... const_reverse_iterator;
    typedef ... difference_type;
    typedef ... pointer;
    typedef ... value_type;
    typedef ... reference;
    typedef ... reverse_iterator;

    bool empty() const;

    difference_type size() const;

    const_reverse_iterator rbegin() const;
    reverse_iterator rbegin();

    const_reverse_iterator rend() const;
    reverse_iterator rend();

    const_reference at(difference_type) const;
    reference at(difference_type);

    const_reference operator[](difference_type) const;
    reference operator[](difference_type);
};

}
}
Типы необходимые для реализации контейнераМетоды необходимые для реализации контейнера
P.S. Кидайте камни
getboost.codeplex.com
citylizard.codeplex.com
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.