based

Opinionated utility library
git clone git://git.dimitrijedobrota.com/based.git
Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING

commit 87de479f3b8f1a935ae8485e35fbf00fd1b5e2ab
parent 63aeca13c6a6ac9fcc06d31e1c9e7de93b505cee
author Dimitrije Dobrota < mail@dimitrijedobrota.com >
date Sat, 28 Jun 2025 19:33:17 +0200

Begin of iterator traits and classes

Diffstat:
A include/based/iterator/concept.hpp | ++++++++++++++++++++++++++++++++++++++
A include/based/iterator/traits.hpp | ++++++++++++++++++
A include/based/iterator/types.hpp | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

3 files changed, 156 insertions(+), 0 deletions(-)


diff --git a/ include/based/iterator/concept.hpp b/ include/based/iterator/concept.hpp

@@ -0,0 +1,38 @@

#pragma once

#include "based/concept/comparable/equality.hpp"
#include "based/concept/is_copy_assignable.hpp"
#include "based/concept/is_copy_constructible.hpp"
#include "based/concept/is_destructible.hpp"
#include "based/concept/is_referenceable.hpp"
#include "based/concept/is_same.hpp"
#include "based/concept/is_swappable.hpp"
#include "based/iterator/traits.hpp"

namespace based::trait
{

template<class Itr>
concept IsLegacyIterator = requires(Itr itr) {
requires(IsCopyConstructible<Itr>);
requires(IsCopyAssignable<Itr>);
requires(IsDestructible<Itr>);
requires(IsSwappable<Itr>);
typename trait::Iterator<Itr>::difference_type;
typename trait::Iterator<Itr>::reference;
typename trait::Iterator<Itr>::pointer;
typename trait::Iterator<Itr>::iterator_category;
// clang-format off
{ *itr } -> IsReferenceable;
{ ++itr } -> IsSame<Itr&>;
{ *itr++ } -> IsReferenceable;
// clang-format on
};

template<class Itr>
concept IsLegacyInputIterator = requires(Itr itr) {
requires(IsLegacyIterator<Itr>);
requires(IsEqualityComparable<Itr>);
};

} // namespace based::trait

diff --git a/ include/based/iterator/traits.hpp b/ include/based/iterator/traits.hpp

@@ -0,0 +1,18 @@

#pragma once

namespace based::trait
{

template<class Itr>
class Iterator;

template<class Itr>
using IterValue = typename trait::Iterator<Itr>::value_type;

template<class Itr>
using IterDifference = typename trait::Iterator<Itr>::difference_type;

template<class Itr>
using IterCategory = typename trait::Iterator<Itr>::iterator_category;

} // namespace based::trait

diff --git a/ include/based/iterator/types.hpp b/ include/based/iterator/types.hpp

@@ -0,0 +1,100 @@

#pragma once

#include "based/concept/is_convertible.hpp"
#include "based/concept/is_same.hpp"
#include "based/integral/types.hpp"

namespace based
{

namespace iterator
{

class Type
{
template<
class Category,
class T,
class Distance = PtrDiffT,
class Pointer = T*,
class Reference = T&>
struct Iterator
{
using iterator_category = Category;
using value_type = T;
using difference_type = Distance;
using pointer = Pointer;
using reference = Reference;
};
};

} // namespace iterator

using IteratorType = iterator::Type;

namespace reverse_iterator
{

template<class Itr>
class Type
{
protected:
Itr m_current = Itr(); // NOLINT(*visibility*)

public:
Type() = default;
constexpr explicit Type(Itr itr)
: m_current(itr)
{
}

template<class U>
requires(!trait::IsSame<U, Itr> && trait::IsConvertible<const U&, Itr>)
constexpr explicit Type(const U& other)
: m_current(other.base())
{
}

friend constexpr bool operator==(const Type& lhs, const Type& rhs) = default;
friend constexpr auto operator<=>(const Type& lhs, const Type& rhs) = default;

constexpr decltype(auto) operator*() const
{
return *std::prev(m_current); // <== returns the content of prev
}

constexpr Type& operator++()
{
--m_current;
return *this;
}

constexpr Type operator++(int)
{
auto tmp = *this;
++(*this);
return tmp;
}

constexpr Type& operator--()
{
++m_current;
return *this;
}

constexpr Type operator--(int)
{
auto tmp = *this;
--(*this);
return tmp;
}

constexpr Itr base() const { return m_current; }

// Other member functions, friend functions, and member typedefs are not shown
// here.
};

} // namespace reverse_iterator

} // namespace based