Reputation: 5257
I'm trying to understand the C++ standard library. If I want to build a new kind of container fully compatible with latest C++17 standards (excluding polymorphic allocator support as I'm not that clear on that yet), with full compatibility with iterators, what is the complete set of member functions and types I must provide?
Take a sequence container like std::vector for example. In other words, say I want to provide everything that std::vector provides. Also considering allocator support.
Of course I also want to provide iterators, exactly as std::vector does it (I don't want to delegate to it; I want from the ground up remake), so I suppose I will need two nested iterator classes, one for iterator
and one for const_iterator
.
I've come up with the following:
template <class T, class Alloc = std::allocator_traits<T>>
class StdLibClass
{
public:
using allocator_type = Alloc;
using value_type = typename Alloc::value_type;
using reference = typename Alloc::reference;
using const_reference = typename Alloc::const_reference;
using difference_type = typename Alloc::difference_type;
using size_type = typename Alloc::size_type;
class Iterator
{
public:
using difference_type = typename Alloc::difference_type;
using value_type = typename Alloc::value_type;
using reference = typename Alloc::reference;
using pointer = typename Alloc::pointer;
using iterator_category = std::random_access_iterator_tag; // or another Iterator tag you want
Iterator();
Iterator(const Iterator&);
~Iterator();
Iterator& operator=(const Iterator&);
bool operator==(const Iterator&) const;
bool operator!=(const Iterator&) const;
bool operator<(const Iterator&) const;
bool operator>(const Iterator&) const;
bool operator<=(const Iterator&) const;
bool operator>=(const Iterator&) const;
Iterator &operator++();
Iterator operator++(int);
Iterator &operator--();
Iterator operator--(int);
Iterator &operator+=(size_type);
Iterator operator+(size_type) const;
friend Iterator operator+(size_type, const Iterator&);
Iterator &operator-=(size_type);
Iterator operator-(size_type) const;
difference_type operator-(Iterator) const;
reference operator*() const;
pointer operator->() const;
reference operator[](size_type) const;
};
class ConstIterator
{
public:
using difference_type = typename Alloc::difference_type;
using value_type = typename Alloc::value_type;
using reference = typename const Alloc::reference;
using pointer = typename const Alloc::pointer;
using iterator_category = std::random_access_iterator_tag; // or another Iterator tag you want
ConstIterator();
ConstIterator(const ConstIterator&);
ConstIterator(const Iterator&);
~ConstIterator();
ConstIterator& operator=(const ConstIterator&);
bool operator==(const ConstIterator&) const;
bool operator!=(const ConstIterator&) const;
bool operator<(const ConstIterator&) const;
bool operator>(const ConstIterator&) const;
bool operator<=(const ConstIterator&) const;
bool operator>=(const ConstIterator&) const;
ConstIterator &operator++();
ConstIterator operator++(int);
ConstIterator &operator--();
ConstIterator operator--(int);
ConstIterator &operator+=(size_type);
ConstIterator operator+(size_type) const;
friend ConstIterator operator+(size_type, const ConstIterator&);
ConstIterator &operator-=(size_type);
ConstIterator operator-(size_type) const;
difference_type operator-(ConstIterator) const;
reference operator*() const;
pointer operator->() const;
reference operator[](size_type) const;
};
using ReverseIterator = std::reverse_iterator<Iterator>;
using ConstReverseIterator = std::const_reverse_iterator<ConstIterator>;
StdLibClass();
~StdLibClass();
StdLibClass(const StdLibClass&);
StdLibClass& operator=(const StdLibClass&);
StdLibClass(const StdLibClass&&);
StdLibClass& operator=(const StdLibClass&&);
bool operator==(const StdLibClass&) const;
bool operator!=(const StdLibClass&) const;
bool operator<(const StdLibClass&) const;
bool operator>(const StdLibClass&) const;
bool operator<=(const StdLibClass&) const;
bool operator>=(const StdLibClass&) const;
Iterator begin();
ConstIterator begin() const;
ConstIterator cbegin() const;
Iterator end();
ConstIterator end() const;
ConstIterator cend() const;
ReverseIterator rbegin();
ConstReverseIterator rbegin() const;
ConstReverseIterator crbegin() const;
ReverseIterator rend();
ConstReverseIterator rend() const;
ConstReverseIterator crend() const;
reference front();
const_reference front() const;
reference back();
const_reference back() const;
template <class... TArgs>
void emplace_front(TArgs &&...);
template <class... TArgs>
void emplace_back(TArgs &&...);
void push_front(const T&);
void push_front(T&&);
void push_back(const T&);
void push_back(T&&);
void pop_front();
void pop_back();
reference operator[](size_type);
const_reference operator[](size_type) const;
reference at(size_type);
const_reference at(size_type) const;
template <class... TArgs>
Iterator emplace(ConstIterator, TArgs&&...);
Iterator insert(ConstIterator, const T&);
Iterator insert(ConstIterator, T&&);
Iterator insert(ConstIterator, size_type, T&);
template <class Iter>
Iterator insert(ConstIterator, Iter, Iter);
Iterator insert(ConstIterator, std::initializer_list<T>);
Iterator erase(ConstIterator);
Iterator erase(ConstIterator, ConstIterator);
void clear();
template <class Iter>
void assign(Iter, Iter);
void assign(std::initializer_list<T>);
void assign(size_type, const T&);
void swap(StdLibClass &);
size_type size() const;
size_type max_size() const;
bool empty() const;
Alloc get_allocator() const;
};
// possibly want to specialize std::swap for the class too
namespace std
{
template <>
void swap<T, StdLibClass<T, Alloc>>(StdLibClass<T, Alloc>&, StdLibClass<T, Alloc>&);
} // namespace std
int main()
{
return 0;
}
Some I've found in webpages around the internet, others I've found by digging the standard library headers. Is there some member or some other concept I'm missing?
Upvotes: 1
Views: 223
Reputation: 1334
I think, depending on the kind of container you want to implement, the new standard requirements (standard concepts) added in C++20 are a good place to look for the required interface of a standard container.
Example for Container
and especially AllocatorAwareContainer
Upvotes: 2