Развитие
вот этой темыАвтор: _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);
};
}
}
Типы необходимые для реализации контейнераМетоды необходимые для реализации контейнераconst_iterator begin() constconst_iterator end() constiterator begin()iterator end()
P.S. Кидайте камни