λ61
Loading...
Searching...
No Matches
meta.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2025 Tetex7
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18//
19// Created by tete on 07/15/2025.
20//
21
22#ifndef L61_META_HPP
23#define L61_META_HPP
24#include <concepts>
25#include <type_traits>
26#include <functional>
27#include <stdexcept>
28
29namespace l61
30{
31 class Object;
32}
33
34namespace l61::meta
35{
36 template<
37 typename cast_type, // The only mandatory template parameter The rest can be inferred
38 typename obj_type,
39 typename T = obj_type, // A leftover from an older rendition Since it's a compile time thing it will not be removed
40 typename Tx = std::conditional_t<std::is_pointer_v<cast_type>, cast_type, std::add_pointer_t<cast_type>>
41 >
42 __inline constexpr Tx dyn_cast(obj_type obj)
43 {
44 static_assert(std::is_pointer_v<T>, "l61::dyn_cast only works on pointer types");
45
46 //if (obj == nullptr) return nullptr;
47
48 if constexpr (std::same_as<T, Tx>)
49 return obj; // Just in case somebody accidentally attempts to cast of the same type
50
51 static_assert(std::is_base_of_v<std::remove_pointer_t<Tx>, std::remove_pointer_t<T>>, "l61::dyn_cast type must be a base of the obj_type's type");
52 return static_cast<Tx>(obj);
53 }
54
55 template<typename T>
56 __inline constexpr T dyn_cast(std::nullptr_t)
57 {
58 static_assert(std::is_pointer_v<T>, "l61::dyn_cast only works on pointer types");
59 return nullptr;
60 }
61
62 namespace nulling
63 {
64 struct null_t;
65
66 class NullAccessException final : public std::runtime_error
67 {
68 public:
69 NullAccessException() : std::runtime_error("Attempted Access to a Nullable Object"){}
70 ~NullAccessException() override = default;
71 };
72
74 {
75 private:
76 const bool is_null_;
77 protected:
78 explicit NullableMark(bool is_null) : is_null_(is_null){}
79
83 void throwIfNull() const noexcept(false)
84 {
85 if (isNull())
86 throw NullAccessException();
87 }
88 public:
89 [[nodiscard]] bool isNull() const { return is_null_; }
90 virtual ~NullableMark() = default;
91 };
92 }
93
94
95 template<typename T>
96 concept isNullableType = !std::same_as<T, nulling::null_t> && (std::default_initializable<T> || std::derived_from<T, nulling::NullableMark>);
97
98 template<typename T>
99 concept castToZeroCompatible = requires { (void)static_cast<T>(0); };
100
101 template<typename T, typename C>
102 concept canStoreBytesOf = sizeof(T) <= sizeof(C) && (alignof(C) % alignof(T) == 0);
103
104 template<typename T, typename C>
107 std::is_trivially_copyable_v<T>;
108
109 template<typename T>
110 concept stdHashCompatible = requires { {std::hash<T>()(std::declval<T>())} -> std::convertible_to<std::size_t>; };
111
112 namespace nulling
113 {
114 struct null_t final
115 {
116 constexpr null_t() = default;
117 constexpr null_t(const null_t&) = default;
118
119 template<isNullableType T>
120 constexpr operator T() const // NOLINT(*-explicit-constructor)
121 {
122 if constexpr (std::default_initializable<T>)
123 {
124 if constexpr (castToZeroCompatible<T>)
125 return static_cast<T>(0);
126 else if constexpr (std::is_pointer_v<T>)
127 return nullptr;
128 return T();
129 }
130 return T(null_t());
131 }
132
133 template<typename T>
134 void operator=(T&&) const {}
135 };
136 }
137
138 template<typename>
139 inline constexpr bool always_false = false;
140
141 template<typename>
142 inline constexpr bool always_true = true;
143
144 inline constexpr nulling::null_t null;
145 using nulling::null_t;
147}
148
149namespace l61
150{
151 using meta::dyn_cast;
152 using meta::null;
153}
154
155#endif //L61_META_HPP
Definition Object.hpp:47
NullableMark(bool is_null)
Definition meta.hpp:78
NullAccessException()
Definition meta.hpp:69
Definition meta.hpp:74
NullableMark(bool is_null)
Definition meta.hpp:78
bool isNull() const
Definition meta.hpp:89
void throwIfNull() const noexcept(false)
Definition meta.hpp:83
const bool is_null_
Definition meta.hpp:76
Definition meta.hpp:102
Definition meta.hpp:99
Definition meta.hpp:96
Definition meta.hpp:105
Definition meta.hpp:110
Definition meta.hpp:63
Definition Object.hpp:38
__inline constexpr Tx dyn_cast(obj_type obj)
Definition meta.hpp:42
constexpr bool always_true
Definition meta.hpp:142
constexpr bool always_false
Definition meta.hpp:139
constexpr nulling::null_t null
Definition meta.hpp:144
Definition Object.hpp:34
constexpr null_t()=default
Definition meta.hpp:115
constexpr null_t()=default
constexpr null_t(const null_t &)=default
void operator=(T &&) const
Definition meta.hpp:134