@@ -109,6 +109,47 @@ struct NonNegativeInt {
109109 int value;
110110};
111111
112+ struct ExplicitCommonLhs {
113+ int value;
114+ };
115+
116+ struct ExplicitCommonRhs {
117+ int value;
118+ };
119+
120+ struct ExplicitCommonRep {
121+ long long value;
122+
123+ friend constexpr auto operator +(ExplicitCommonRep lhs,
124+ ExplicitCommonRep rhs) noexcept
125+ -> ExplicitCommonRep {
126+ return ExplicitCommonRep{lhs.value + rhs.value };
127+ }
128+
129+ friend constexpr auto operator -(ExplicitCommonRep lhs,
130+ ExplicitCommonRep rhs) noexcept
131+ -> ExplicitCommonRep {
132+ return ExplicitCommonRep{lhs.value - rhs.value };
133+ }
134+
135+ friend constexpr auto operator *(ExplicitCommonRep lhs,
136+ ExplicitCommonRep rhs) noexcept
137+ -> ExplicitCommonRep {
138+ return ExplicitCommonRep{lhs.value * rhs.value };
139+ }
140+
141+ friend constexpr auto operator /(ExplicitCommonRep lhs,
142+ ExplicitCommonRep rhs) noexcept
143+ -> ExplicitCommonRep {
144+ return ExplicitCommonRep{lhs.value / rhs.value };
145+ }
146+
147+ friend constexpr auto operator ==(ExplicitCommonRep lhs,
148+ ExplicitCommonRep rhs) noexcept -> bool {
149+ return lhs.value == rhs.value ;
150+ }
151+ };
152+
112153} // namespace
113154
114155template <> struct mcpplibs ::primitives::underlying::traits<UserInteger> {
@@ -232,6 +273,52 @@ template <> struct mcpplibs::primitives::underlying::traits<NonNegativeInt> {
232273 }
233274};
234275
276+ template <> struct mcpplibs ::primitives::underlying::traits<ExplicitCommonLhs> {
277+ using value_type = ExplicitCommonLhs;
278+ using rep_type = ExplicitCommonLhs;
279+
280+ static constexpr bool enabled = true ;
281+ static constexpr auto kind = category::integer;
282+
283+ static constexpr rep_type to_rep (value_type value) noexcept { return value; }
284+
285+ static constexpr value_type from_rep (rep_type value) noexcept {
286+ return value;
287+ }
288+
289+ static constexpr bool is_valid_rep (rep_type) noexcept { return true ; }
290+ };
291+
292+ template <> struct mcpplibs ::primitives::underlying::traits<ExplicitCommonRhs> {
293+ using value_type = ExplicitCommonRhs;
294+ using rep_type = ExplicitCommonRhs;
295+
296+ static constexpr bool enabled = true ;
297+ static constexpr auto kind = category::integer;
298+
299+ static constexpr rep_type to_rep (value_type value) noexcept { return value; }
300+
301+ static constexpr value_type from_rep (rep_type value) noexcept {
302+ return value;
303+ }
304+
305+ static constexpr bool is_valid_rep (rep_type) noexcept { return true ; }
306+ };
307+
308+ template <>
309+ struct mcpplibs ::primitives::underlying::common_rep_traits<ExplicitCommonLhs,
310+ ExplicitCommonRhs> {
311+ using type = ExplicitCommonRep;
312+ static constexpr bool enabled = true ;
313+ };
314+
315+ template <>
316+ struct mcpplibs ::primitives::underlying::common_rep_traits<ExplicitCommonRhs,
317+ ExplicitCommonLhs> {
318+ using type = ExplicitCommonRep;
319+ static constexpr bool enabled = true ;
320+ };
321+
235322TEST (PrimitiveTraitsTest, StandardTypeConcepts) {
236323 EXPECT_TRUE ((mcpplibs::primitives::std_integer<int >));
237324 EXPECT_TRUE ((mcpplibs::primitives::std_integer<long long >));
@@ -339,6 +426,33 @@ TEST(PrimitiveTraitsTest,
339426 EXPECT_FALSE ((mcpplibs::primitives::underlying_type<MissingDivisionLike>));
340427}
341428
429+ TEST (PrimitiveTraitsTest, UnderlyingCommonRepDefaultsToStdCommonType) {
430+ static_assert (mcpplibs::primitives::has_common_rep<int , long long >);
431+ static_assert (std::same_as<mcpplibs::primitives::common_rep_t <int , long long >,
432+ long long >);
433+ SUCCEED ();
434+ }
435+
436+ TEST (PrimitiveTraitsTest, UnderlyingCommonRepCanBeCustomizedViaTraits) {
437+ static_assert (mcpplibs::primitives::has_common_rep<ExplicitCommonLhs,
438+ ExplicitCommonRhs>);
439+ static_assert (
440+ std::same_as<mcpplibs::primitives::common_rep_t <ExplicitCommonLhs,
441+ ExplicitCommonRhs>,
442+ ExplicitCommonRep>);
443+
444+ using handler_t = mcpplibs::primitives::policy::type::handler<
445+ mcpplibs::primitives::policy::type::transparent,
446+ mcpplibs::primitives::operations::Addition, ExplicitCommonLhs,
447+ ExplicitCommonRhs>;
448+
449+ static_assert (handler_t ::enabled);
450+ static_assert (handler_t ::allowed);
451+ static_assert (
452+ std::same_as<typename handler_t ::common_rep, ExplicitCommonRep>);
453+ SUCCEED ();
454+ }
455+
342456int main (int argc, char **argv) {
343457 testing::InitGoogleTest (&argc, argv);
344458 return RUN_ALL_TESTS ();
0 commit comments