103 lines
3.6 KiB
C++
103 lines
3.6 KiB
C++
//
|
|
// Created by Patrick Maschek on 19.01.2024.
|
|
//
|
|
|
|
#ifndef UDIFF_CONST_LIST_H_
|
|
#define UDIFF_CONST_LIST_H_
|
|
|
|
#include <concepts>
|
|
#include <iterator>
|
|
|
|
namespace cc {
|
|
|
|
class const_list_node;
|
|
|
|
template<typename N>
|
|
requires std::derived_from<N, const_list_node>
|
|
class _const_list_iterator_base {
|
|
protected:
|
|
N *_curr;
|
|
|
|
public:
|
|
constexpr _const_list_iterator_base() : _curr() {}
|
|
constexpr explicit _const_list_iterator_base(N *curr) : _curr(curr) {}
|
|
|
|
constexpr virtual const N& operator*() const { return *_curr; }
|
|
constexpr virtual const N* operator->() const { return _curr; }
|
|
|
|
constexpr virtual _const_list_iterator_base &operator++() noexcept = 0;
|
|
constexpr virtual _const_list_iterator_base &operator--() noexcept = 0;
|
|
constexpr virtual _const_list_iterator_base operator++(int) & noexcept = 0;
|
|
constexpr virtual _const_list_iterator_base operator--(int) & noexcept = 0;
|
|
|
|
constexpr bool operator==(const _const_list_iterator_base &other) { return _curr == other._curr; }
|
|
};
|
|
|
|
template<typename N>
|
|
class _const_list_iterator : public _const_list_iterator_base<N> {
|
|
using _Base = _const_list_iterator_base<N>;
|
|
public:
|
|
constexpr _const_list_iterator() : _Base() {}
|
|
constexpr explicit _const_list_iterator(N *curr) : _Base(curr) {}
|
|
|
|
constexpr N& operator*() const override { return *_Base::_curr; }
|
|
constexpr N* operator->() const override { return _Base::_curr; }
|
|
|
|
constexpr _const_list_iterator &operator++() noexcept override { _Base::_curr == _Base::_curr->_next; return *this; }
|
|
constexpr _const_list_iterator &operator--() noexcept override { _Base::_curr == _Base::_curr->_prev; return *this; }
|
|
constexpr _const_list_iterator operator++(int) & noexcept override { auto tmp = *this; _Base::_curr == _Base::_curr->_next; return tmp; }
|
|
constexpr _const_list_iterator operator--(int) & noexcept override { auto tmp = *this; _Base::_curr == _Base::_curr->_prev; return tmp; }
|
|
};
|
|
|
|
template<typename N>
|
|
class _const_const_list_iterator : public _const_list_iterator_base<N> {
|
|
using _Base = _const_list_iterator_base<N>;
|
|
public:
|
|
constexpr _const_const_list_iterator() : _Base() {}
|
|
constexpr explicit _const_const_list_iterator(N *curr) : _Base(curr) {}
|
|
|
|
constexpr _const_const_list_iterator &operator++() noexcept override { _Base::_curr == _Base::_curr->_next; return *this; }
|
|
constexpr _const_const_list_iterator &operator--() noexcept override { _Base::_curr == _Base::_curr->_prev; return *this; }
|
|
constexpr _const_const_list_iterator operator++(int) & noexcept override { auto tmp = *this; _Base::_curr == _Base::_curr->_next; return tmp; }
|
|
constexpr _const_const_list_iterator operator--(int) & noexcept override { auto tmp = *this; _Base::_curr == _Base::_curr->_prev; return tmp; }
|
|
};
|
|
|
|
template<typename N>
|
|
requires std::derived_from<N, const_list_node>
|
|
class const_list {
|
|
|
|
public:
|
|
|
|
using value_type = N;
|
|
using size_type = std::size_t;
|
|
using difference_type = std::ptrdiff_t;
|
|
using reference = value_type&;
|
|
using const_reference = const value_type&;
|
|
using pointer = value_type *;
|
|
using const_pointer = const value_type *;
|
|
using iterator = _const_list_iterator<N>;
|
|
using const_iterator = _const_const_list_iterator<N>;
|
|
using reverse_iterator = std::reverse_iterator<iterator>;
|
|
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
|
|
|
|
|
private:
|
|
const_list_node *_start;
|
|
|
|
};
|
|
|
|
class const_list_node {
|
|
private:
|
|
const_list_node *_prev;
|
|
const_list_node *_next;
|
|
|
|
friend class const_list<const_list_node>;
|
|
friend class _const_list_iterator_base<const_list_node>;
|
|
};
|
|
|
|
|
|
|
|
} // cc
|
|
|
|
#endif //UDIFF_CONST_LIST_H_
|