18 constexpr FixedString(
char const (&
s)[
N]) { std::copy_n(
s,
N, this->elems); }
19 constexpr std::strong_ordering operator<=>(FixedString
const&)
const =
default;
27 template <
typename SELF_TYPE,
typename OTHERS_
SELF_TYPE =
SELF_TYPE>
29 static constexpr bool applies_to =
true;
32 template <
typename SELF_TYPE,
typename OTHERS_
SELF_TYPE =
SELF_TYPE>
34 static constexpr bool applies_to =
true;
37 struct incrementable {
38 template <
typename SELF_TYPE>
39 static constexpr bool applies_to =
true;
44 struct location {
template <
typename SELF_TYPE>
static constexpr bool applies_to =
true; };
48 struct displacement {
template <
typename SELF_TYPE>
static constexpr bool applies_to =
true; };
50 struct implicitly_convertible {
template <
typename SELF_TYPE>
static constexpr bool applies_to =
true; };
51 struct implicitly_constructible {
template <
typename SELF_TYPE>
static constexpr bool applies_to =
true; };
53 struct implicitly_constructible_from {
using type = T;
template <
typename SELF_TYPE>
static constexpr bool applies_to =
true; };
55 template <
typename LOCATION_NAMED_TYPE>
56 struct is_displacement_of {
58 template <
typename SELF_TYPE>
59 static constexpr bool applies_to = std::same_as<typename std::remove_cvref_t<LOCATION_NAMED_TYPE>::base_type,
typename SELF_TYPE::base_type>;
62 template <
typename DISPLACEMENT_NAMED_TYPE>
63 struct is_location_of {
65 template <
typename SELF_TYPE>
66 static constexpr bool applies_to = std::same_as<typename std::remove_cvref_t<DISPLACEMENT_NAMED_TYPE>::base_type,
typename SELF_TYPE::base_type>;
69 template <
typename DISPLACEMENT_TYPE,
typename LOCATION_TYPE>
70 concept named_is_displacement_of =
75 template <
typename NAMED_TYPE,
typename TRAIT_TYPE>
79 template <
typename T, detail::FixedString
PARAMETER,
typename...
TRAITS>
82 using addable = traits::addable;
83 using subtractable = traits::subtractable;
84 using location = traits::location;
85 using displacement = traits::displacement;
89 static constexpr detail::FixedString name =
PARAMETER;
93 static constexpr auto find_displacement_type_impl(traits::is_location_of<U>)
95 return std::type_identity<std::remove_cvref_t<T>>{};
97 static constexpr auto find_displacement_type_impl(...)
99 return std::type_identity<void>{};
105 using type_candidate = std::remove_cvref_t<
typename decltype(find_displacement_type_impl(
trait))::type>;
106 if constexpr (std::is_same_v<type_candidate, void>)
107 return find_displacement_type_traits(traits...);
109 return std::type_identity<type_candidate>{};
112 static constexpr auto find_displacement_type_traits() {
return std::type_identity<void>{}; }
114 static constexpr auto find_displacement_type()
116 return find_displacement_type_traits(
TRAITS{}...);
121 static constexpr bool has_trait = (std::is_same_v<TRAIT, TRAITS> || ...) && TRAIT::template applies_to<self_type,
OTHER...>;
123 using displacement_type =
typename decltype(find_displacement_type())::type;
127 template <
typename...
ARGS>
128 requires std::constructible_from<T,
ARGS...>
129 constexpr explicit named(
ARGS&&...
args)
noexcept(std::is_nothrow_constructible_v<T,
ARGS...>) : value(std::forward<
ARGS>(
args)...) {}
131 template <
typename U>
133 constexpr named(
U&&
arg)
noexcept(std::is_nothrow_move_constructible_v<T>)
134 : value(std::forward<
U>(
arg))
138 template <
typename U>
140 constexpr named(
U&&
arg)
noexcept(std::is_nothrow_move_constructible_v<T>)
141 : value((T)std::forward<
U>(
arg))
153 constexpr named(
U&&
arg)
154 : named(named_cast<self_type>(std::forward<
U>(
arg)))
159 constexpr T
const& operator*()
const &
noexcept {
return value; }
160 constexpr T operator*() &&
noexcept {
return std::move(value); }
162 constexpr T* operator->()
noexcept {
return &value; }
163 constexpr T
const* operator->()
const noexcept {
return &value; }
165 constexpr T&
get() &
noexcept {
return value; }
167 constexpr T
get() &&
noexcept {
return std::move(value); }
169 template <
typename U>
170 constexpr U as()
noexcept {
return static_cast<U>(value); }
181 template <
typename U>
183 constexpr explicit operator U()
const
189 constexpr operator base_type()
const noexcept requires has_trait<traits::implicitly_convertible> {
return value; }
191 constexpr auto operator<=>(named
const&)
const =
default;
193 template <
typename U>
194 constexpr auto operator<=>(
U const& b)
const {
return value <=> b; }
195 template <
typename U>
196 constexpr bool operator==(
U const& b)
const {
return value == b; }
199 constexpr named& operator++()
200 requires has_trait<traits::incrementable>
206 constexpr auto operator+(self_type
const&
val)
const
209 return self_type{ this->value +
val.value };
212 constexpr auto& operator+=(self_type
const&
val)
215 this->value +=
val.value;
227 friend constexpr auto operator-(self_type
const&
other, self_type
const&
self)
230 return self_type{
other.value -
self.value };
234 constexpr auto operator-(self_type
val)
const
237 return displacement_type{ this->value -
val.value };
241 template <
typename LOCATION_TYPE>
245 (traits::applies_to<LOCATION_TYPE, location>) &&
246 (traits::named_is_displacement_of<self_type, LOCATION_TYPE>) &&
247 (addable::applies_to<self_type, LOCATION_TYPE>)
249 return std::remove_cvref_t<LOCATION_TYPE>{ this->value + std::forward<LOCATION_TYPE>(
val).value };
253 template <
typename DISPLACEMENT_TYPE>
257 (traits::applies_to<DISPLACEMENT_TYPE, displacement>) &&
258 (traits::named_is_displacement_of<DISPLACEMENT_TYPE, self_type>) &&
259 (addable::applies_to<self_type, DISPLACEMENT_TYPE>)
261 return self_type{ this->value + std::forward<DISPLACEMENT_TYPE>(
val).value };
264 template <
typename U>
265 constexpr auto operator*(
U&&
val)
const
266 requires has_trait<displacement> && std::constructible_from<T, decltype(std::declval<T>() * std::declval<U>())>
268 return self_type{ this->value * std::forward<U>(
val) };
271 template <
typename U>
272 constexpr auto operator/(
U&&
val)
const
273 requires has_trait<displacement> && std::constructible_from<T, decltype(std::declval<T>() / std::declval<U>())>
275 return self_type{ this->value / std::forward<U>(
val) };
278 constexpr auto operator/(self_type
const&
val)
const
281 return this->value /
val.value;
288 static_assert(std::is_trivially_copyable_v<named<
int,
"int">> == std::is_trivially_copyable_v<int>);
293 static constexpr bool is_named_impl(...) {
return false; }
295 template <
typename OTHER>
296 static constexpr bool is_named_v = ::ghassanpl::detail::is_named_impl(std::type_identity<std::remove_cvref_t<OTHER>>{});
299 template <
typename T, detail::FixedString PARAMETER,
typename STRINGIFIER>
302 return str(
val.value);
312#define ghassanpl_named_string_literal(named_name, suffix) \
313 inline named_name operator"" suffix(const char* str, std::size_t len) { \
314 return named_name{named_name::base_type{str,len}}; \
317#define ghassanpl_named_string_literal_ce(named_name, suffix) \
318 constexpr ghassanpl_named_string_literal(named_name, suffix)
constexpr auto bit_count
Equal to the number of bits in the type.
nlohmann::json const & get(nlohmann::json const &g, std::string_view key, jtype type=jtype::discarded)
Gets the item in the json object g with the key key, or an empty json object if none found.
The below code is based on Sun's libm library code, which is licensed under the following license:
Primary namespace for everything in this library.
This trait implies the named type is an linear type, that is, a type that has the addition operator d...
This trait implies the named type is an affine type, that is, a type that does not have the addition ...