zeus

Unnamed repository; edit this file 'description' to name the repository.
git clone Unknown
Log | Files | Refs

commit e58770b0d523f37a4afaa41bf760c97091079686
parent c322880ba8d307b301969c3df510ec197b86a5f6
author Dimitrije Dobrota < mail@dimitrijedobrota.com >
date Thu, 15 May 2025 21:02:49 +0200

Decorators for custom type building

Diffstat:
A decorator_types.cpp | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

1 files changed, 274 insertions(+), 0 deletions(-)


diff --git a/ decorator_types.cpp b/ decorator_types.cpp

@@ -0,0 +1,274 @@

#include <utility>

template <typename V> class Value {
protected:
V m_val;

public:
template <typename FV1> using rebind = Value<V>;

using value_type = Value;
using basic_type = V;

explicit Value() : m_val(V()) {}

explicit Value(const Value &) = default;
explicit Value(V value) : m_val(value) {}

Value &operator=(const Value &) = default;

Value(Value &&) = default;
Value &operator=(Value &&) = default;
Value &operator=(V &&rhs) {
m_val = std::move(rhs);
return *this;
}
};

template <class V, class FV = void>
class ImplicitFrom : public V::template rebind<FV> {
using base_type = typename V::template rebind<FV>;

public:
template <typename FV1> using rebind = ImplicitFrom<V, FV1>;

using base_type::base_type;
using base_type::operator=;

using value_type = typename base_type::value_type;
using basic_type = typename value_type::basic_type;

explicit ImplicitFrom(value_type v) : base_type(v) {}

ImplicitFrom(basic_type rhs) : base_type(rhs) {}
FV &operator=(V rhs) {
this->m_val = rhs;
return *this;
}
};

template <class V>
class ImplicitFrom<V, void> : public V::template rebind<ImplicitFrom<V>> {
using base_type = typename V::template rebind<ImplicitFrom<V>>;

public:
template <typename FV1> using rebind = ImplicitFrom<V, FV1>;

using base_type::base_type;
using base_type::operator=;

using value_type = typename base_type::value_type;
using basic_type = typename value_type::basic_type;

explicit ImplicitFrom(value_type v) : base_type(v) {}

ImplicitFrom(basic_type rhs) : base_type(rhs) {}
ImplicitFrom &operator=(V rhs) {
this->m_val = rhs;
return *this;
}
};

template <class V, class FV = void>
class ImplicitTo : public V::template rebind<FV> {
using base_type = typename V::template rebind<FV>;

public:
template <typename FV1> using rebind = ImplicitTo<V, FV1>;

using base_type::base_type;
using base_type::operator=;

using value_type = typename base_type::value_type;
using basic_type = typename value_type::basic_type;

explicit ImplicitTo(value_type v) : base_type(v) {}

operator basic_type() { return this->m_val; }
operator const basic_type() const { return this->m_val; }
};

template <class V>
class ImplicitTo<V, void> : public V::template rebind<ImplicitTo<V>> {
using base_type = typename V::template rebind<ImplicitTo<V>>;

public:
template <typename FV1> using rebind = ImplicitTo<V, FV1>;

using base_type::base_type;
using base_type::operator=;

using value_type = typename base_type::value_type;
using basic_type = typename value_type::basic_type;

explicit ImplicitTo(value_type v) : base_type(v) {}

operator basic_type() { return this->m_val; }
operator const basic_type() const { return this->m_val; }
};

template <class V, class FV = void>
class Comparable : public V::template rebind<FV> {
using base_type = typename V::template rebind<FV>;

public:
template <typename FV1> using rebind = Comparable<V, FV1>;

using base_type::base_type;
using base_type::operator=;

using value_type = typename base_type::value_type;
using basic_type = typename value_type::basic_type;

explicit Comparable(value_type v) : base_type(v) {}

friend bool operator==(FV lhs, FV rhs) { return lhs.m_val == rhs.m_val; }
};

template <class V>
class Comparable<V, void> : public V::template rebind<Comparable<V>> {
using base_type = typename V::template rebind<Comparable<V>>;

public:
template <typename FV1> using rebind = Comparable<V, FV1>;

using base_type::base_type;
using base_type::operator=;

using value_type = typename base_type::value_type;
using basic_type = typename value_type::basic_type;

explicit Comparable(value_type v) : base_type(v) {}

friend bool operator==(Comparable lhs, Comparable rhs) {
return lhs.m_val == rhs.m_val;
}
};

template <class V, class FV = void>
class Ordered : public V::template rebind<FV> {
using base_type = typename V::template rebind<FV>;

public:
template <typename FV1> using rebind = Ordered<V, FV1>;

using base_type::base_type;
using base_type::operator=;

using value_type = typename base_type::value_type;
using basic_type = typename value_type::basic_type;

explicit Ordered(value_type v) : base_type(v) {}

friend auto operator<=>(FV lhs, FV rhs) { return lhs.m_val <=> rhs.m_val; }
};

template <class V>
class Ordered<V, void> : public V::template rebind<Ordered<V>> {
using base_type = typename V::template rebind<Ordered<V>>;

public:
template <typename FV1> using rebind = Ordered<V, FV1>;

using base_type::base_type;
using base_type::operator=;

using value_type = typename base_type::value_type;
using basic_type = typename value_type::basic_type;

explicit Ordered(value_type v) : base_type(v) {}

friend auto operator<=>(Ordered lhs, Ordered rhs) {
return lhs.m_val <=> rhs.m_val;
}
};

template <class V, class FV = void>
class Addable : public V::template rebind<FV> {
using base_type = typename V::template rebind<FV>;

public:
template <typename FV1> using rebind = Addable<V, FV1>;

using base_type::base_type;
using base_type::operator=;

using value_type = typename base_type::value_type;
using basic_type = typename value_type::basic_type;

explicit Addable(value_type v) : base_type(v) {}

friend FV operator+(FV lhs, FV rhs) { return FV(lhs.m_val + rhs.m_val); }
};

template <class V>
class Addable<V, void> : public V::template rebind<Addable<V>> {
using base_type = typename V::template rebind<Addable<V>>;

public:
template <typename FV1> using rebind = Addable<V, FV1>;

using base_type::base_type;
using base_type::operator=;

using value_type = typename base_type::value_type;
using basic_type = typename value_type::basic_type;

explicit Addable(value_type v) : base_type(v) {}

friend Addable operator+(Addable lhs, Addable rhs) {
return Addable(lhs.m_val + rhs.m_val);
}
};

template <class V, class FV = void>
class Subtractable : public V::template rebind<FV> {
using base_type = typename V::template rebind<FV>;

public:
template <typename FV1> using rebind = Subtractable<V, FV1>;

using base_type::base_type;
using base_type::operator=;

using value_type = typename base_type::value_type;
using basic_type = typename value_type::basic_type;

explicit Subtractable(value_type v) : base_type(v) {}

friend FV operator-(FV lhs, FV rhs) { return FV(lhs.m_val - rhs.m_val); }
};

template <class V>
class Subtractable<V, void> : public V::template rebind<Subtractable<V>> {
using base_type = typename V::template rebind<Subtractable<V>>;

public:
template <typename FV1> using rebind = Subtractable<V, FV1>;

using base_type::base_type;
using base_type::operator=;

using value_type = typename base_type::value_type;
using basic_type = typename value_type::basic_type;

explicit Subtractable(value_type v) : base_type(v) {}

friend Subtractable operator-(Subtractable lhs, Subtractable rhs) {
return Subtractable(lhs.m_val - rhs.m_val);
}
};

int main() {
using V = Subtractable<Addable<Ordered<Comparable<Value<int>>>>>;
V i;
V j(5);
V k(3);

auto a = i == j;
auto b = i <= j;
auto c = i > j;
auto d = i + j == V(7) - k;

return a + b + c + d;
}