zeusUnnamed 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
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;
}