repr 0.1
Reconstructable string representations and more
Loading...
Searching...
No Matches
category.h
Go to the documentation of this file.
1#pragma once
2#include <concepts>
3#include <cstddef>
4#include <string_view>
5#include <type_traits>
6#include <utility>
8
9#include <librepr/name/type.h>
10#include <librepr/util/util.h>
11
12namespace librepr {
13template <typename T>
14struct Reflect;
15}
16
17namespace librepr::category {
18
19template <typename T>
20concept has_name = requires(T obj) { std::string_view{obj.name()}; };
21
22template <typename T>
23concept has_parent = requires { typename T::parent; };
24
25template <typename T>
26concept has_members = requires { typename T::members; };
27
28template <typename T>
29concept has_extent = requires {
30 { T::extent } -> std::convertible_to<std::size_t>;
31};
32
33template <typename T>
34concept has_alternatives = requires { typename T::alternatives; };
35
36template <typename T>
37concept has_enumerator_names = requires { T::enumerator_names; };
38
39template <typename T>
40concept has_value = requires(T obj) { obj.value(); };
41
42template <typename T>
44
45template <typename T>
46concept is_iterable = T::is_iterable;
47
48template <class T>
49struct Value : T {
50 // essentially a std::reference_wrapper without operator()
51 using descend = T;
52 using type = typename T::type;
53
54 template <detail::ref_convertible_to<type> U>
55 requires(!std::same_as<Value, std::remove_cvref_t<U>>)
56 constexpr explicit(false) Value(U&& obj) noexcept(noexcept(detail::convert_ref<type>(std::forward<U>(obj))))
57 : data(std::addressof(detail::convert_ref<type>(std::forward<U>(obj)))) {}
58
59 Value(const Value&) noexcept = default;
60 Value& operator=(const Value&) noexcept = default;
61 ~Value() = default;
62
63 constexpr explicit(false) operator type&() const noexcept { return *data; }
64 constexpr type& operator*() const noexcept { return *data; }
65 constexpr type* operator->() const noexcept { return data; }
66
67 [[nodiscard]] constexpr type& value() const noexcept { return *data; }
68
69 template <typename V>
70 void visit(V&& visitor) {
71 LIBREPR_MAYBE_DO(T::visit(std::forward<V>(visitor), value()));
72 }
73
74private:
75 type* data;
76};
77
78template <class T>
80
81template <typename T>
82struct Type {
83 using type = T;
84 [[nodiscard]] static auto type_name() { return librepr::get_name<type>(); }
85
86 template <typename V>
87 static void visit(V&& visitor) {
89 }
90};
91
92} // namespace librepr::category
T addressof(T... args)
Definition category.h:43
Definition category.h:34
Definition category.h:29
Definition category.h:26
Definition category.h:20
Definition category.h:23
Definition category.h:40
Definition category.h:46
#define LIBREPR_MAYBE_DO(...)
Definition macro/util.h:101
Definition aggregate.h:28
Definition ctvi/ctvi.h:9
std::string code_for()
Definition repr:39
Reflect(T &) -> Reflect< T >
Definition reflection/reflect.h:16
Definition category.h:82
static void visit(V &&visitor)
Definition category.h:87
static auto type_name()
Definition category.h:84
T type
Definition category.h:83
Definition category.h:49
void visit(V &&visitor)
Definition category.h:70
constexpr type & value() const noexcept
Definition category.h:67
Value(const Value &) noexcept=default
constexpr type & operator*() const noexcept
Definition category.h:64
typename T::type type
Definition category.h:52
T descend
Definition category.h:51
Value & operator=(const Value &) noexcept=default
constexpr type * operator->() const noexcept
Definition category.h:65