GCC Code Coverage Report


Directory: include/kumi/
File: include/kumi/utils/identifier.hpp
Date: 2026-10-14 16:33:56
Exec Total Coverage
Lines: 7 7 100.0%
Functions: 70 70 100.0%
Branches: 0 0 -%

Line Branch Exec Source
1 //======================================================================================================================
2 /*
3 KUMI - Compact Tuple Tools
4 Copyright : KUMI Project Contributors
5 SPDX-License-Identifier: BSL-1.0
6 */
7 //======================================================================================================================
8 #pragma once
9
10 namespace kumi
11 {
12 template<typename T> struct only_t
13 {
14 template<typename U> static constexpr bool value = std::same_as<T, U>;
15 };
16
17 template<template<class> typename Traits> struct traits_check
18 {
19 template<typename U> static constexpr bool value = Traits<U>::value;
20 };
21
22 //====================================================================================================================
23 /**
24 @ingroup kumi_utility
25 @brief Option restricting an identifier to accept a single type `T`.
26 @tparam T Type that the parametrized identifier will accept.
27
28 @include doc/infra/only.cpp
29 **/
30 //====================================================================================================================
31 template<typename T> inline constexpr kumi::only_t<T> only = {};
32
33 //====================================================================================================================
34 /**
35 @ingroup kumi_utility
36 @brief Option restricting an identifier to accept values whose type satisfies the trait `Traits`.
37 @tparam Traits Traits that the parametrized identifier will use to validate its value.
38
39 @include doc/infra/checked.cpp
40 **/
41 //====================================================================================================================
42 template<template<class> typename Traits> inline constexpr traits_check<Traits> if_ = {};
43
44 template<typename ID, typename Check = void> struct identifier;
45
46 template<typename ID> struct identifier<ID, void>
47 {
48 using type = std::remove_cvref_t<ID>;
49
50 constexpr identifier() noexcept = default;
51
52 constexpr identifier(ID const&) noexcept {}
53
54 1 template<typename T> constexpr kumi::field<type, std::unwrap_ref_decay_t<T>> operator=(T&& v) const noexcept
55 {
56 1 return {KUMI_FWD(v)};
57 }
58
59 template<typename CharT, typename Traits>
60 friend std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os,
61 identifier const&) noexcept
62 {
63 return os << kumi::_::make_str(type{});
64 }
65 };
66
67 //====================================================================================================================
68 /**
69 @ingroup kumi_types
70 @class identifier
71 @brief identifier definition class
72
73 kumi::identifier defines an identifier, i.e. an entity that can receive values and can be stored as part of a
74 product type. It is defined by a unique type ID which can be an actual type or generated from kumi::name and an
75 optional checking operations that will validate the value passed to the identifier is acceptable.
76
77 kumi::identifier can also be used to define custom identifier type with specific behavior.
78
79 @tparam ID identifier type being defined
80 @tparam Checker Potential type checker meta-function. By default, this is `void` to notify no check is performed.
81
82 @include doc/infra/regular.cpp
83 **/
84 //====================================================================================================================
85 template<typename ID, typename Checker> struct identifier
86 {
87 //! @brief Derived identifier type
88 using type = identifier<ID, Checker>;
89
90 //! A checked field str representation is the underlying type, checker is ignored
91 friend constexpr kumi::_::str_like auto to_str(identifier const&) { return kumi::_::make_str(ID{}); }
92
93 //! @brief Default constructor
94 constexpr identifier() noexcept = default;
95
96 //==================================================================================================================
97 /**
98 @brief Constructs an identifier from an ID and a checker type.
99
100 @param id Identifier of the identifier.
101 @param check Object performing the compile-time verification of the identifier's value.
102
103 @include doc/infra/only.cpp
104 **/
105 //==================================================================================================================
106 constexpr identifier([[maybe_unused]] ID const& id, [[maybe_unused]] Checker const& check) noexcept {}
107
108 //==================================================================================================================
109 /**
110 @brief Assignment of a value to an identifier
111
112 Binds a value to the current kumi::identifier and returns a field instance.
113
114 @param v Bound value
115 @return A kumi::field binding the identifier to `v`.
116
117 @code
118 #include <kumi/kumi.hpp>
119 #include <iostream>
120
121 int main()
122 {
123 using namespace kumi::literals;
124 std::cout << ("value"_id = 42.1337) << "\n";
125 }
126 @endcode
127 **/
128 //==================================================================================================================
129 template<typename T>
130 requires(Checker::template value<T>)
131 constexpr auto operator=(T&& v) const noexcept -> kumi::field<type, std::unwrap_ref_decay_t<T>>
132 {
133 return {KUMI_FWD(v)};
134 }
135
136 template<typename T>
137 requires(!Checker::template value<T>)
138 constexpr kumi::field<type, std::unwrap_ref_decay_t<T>> operator=(T&& v) const = delete;
139
140 //! @related kumi::identifier
141 //! @brief Output stream insertion
142 template<typename CharT, typename Traits>
143 friend std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os,
144 identifier const&) noexcept
145 {
146 return os << kumi::_::make_str(identifier{});
147 }
148 };
149
150 template<typename ID> identifier(ID const&) -> identifier<ID>;
151 template<typename ID, typename Checker> identifier(ID const&, Checker const&) -> identifier<ID, Checker>;
152
153 //====================================================================================================================
154 /**
155 @ingroup kumi_types
156 @class name
157 @brief Compile-time text based identifier
158 @tparam ID Compile-time string representing an identifier
159 **/
160 //====================================================================================================================
161 template<kumi::str ID> struct name
162 {
163 //! @brief Derived identifier type
164 using type = name<ID>;
165
166 //! Text representation of a name, as a kumi::str
167 friend constexpr kumi::_::str_like auto to_str(name const&) { return ID; }
168
169 //==================================================================================================================
170 /**
171 @brief Assignment of a value to an identifier
172
173 Binds a value to the current name and returns a kumi::field instance.
174
175 @param v Bound value
176 @return A kumi::field binding the identifier to `v`.
177 **/
178 //==================================================================================================================
179 363 template<typename T> constexpr auto operator=(T&& v) const noexcept -> kumi::field<type, std::unwrap_ref_decay_t<T>>
180 {
181 363 return {KUMI_FWD(v)};
182 }
183
184 //! @related kumi::name
185 //! @brief Output stream insertion
186 template<typename CharT, typename Traits>
187 23 friend std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, name const&) noexcept
188 {
189 23 return os << ID;
190 }
191 };
192
193 //! identifier comparison
194 template<kumi::concepts::identifier L, kumi::concepts::identifier R>
195 KUMI_ABI constexpr bool operator==(L const&, R const&)
196 {
197 8 return std::same_as<std::remove_cvref_t<L>, std::remove_cvref_t<R>>;
198 }
199
200 namespace _
201 {
202 // MSVC workaround for get<>
203 // MSVC evaluates require clauses before checking the type of NTTPs
204 template<auto N, typename... Ts> consteval auto contains_identifier()
205 {
206 if constexpr (std::integral<std::remove_cvref_t<decltype(N)>>) return false;
207 else if constexpr (kumi::concepts::index<decltype(N)>) return false;
208 else if constexpr (kumi::concepts::identifier<std::remove_cvref_t<decltype(N)>>) return false;
209 else return kumi::concepts::contains_identifier<kumi::name<N>, Ts...>;
210 }
211
212 template<auto N, typename... Ts> consteval auto contains_label()
213 {
214 if constexpr (std::integral<std::remove_cvref_t<decltype(N)>>) return false;
215 else if constexpr (kumi::concepts::index<decltype(N)>) return false;
216 else if constexpr (!kumi::_::str_like<decltype(N)>) return false;
217 else return kumi::concepts::contains_label<std::integral_constant<kumi::str<N.size()>, N>, Ts...>;
218 }
219 }
220 }
221