I would like to have a nice way to enable functionality(e.g. ++, *=, /) of my strong types(e.g. StockPrice, Count).
I don't like using inheritance for that (CRTP/mixins), I understand some may like it but I prefer to not use inheritance for this use case.
So I have code like this:
template<class, template<class...> class>
inline constexpr bool is_specialization = false;
template<template<class...> class T, class... Args>
inline constexpr bool is_specialization<T<Args...>, T> = true;
template<typename Underlying, typename TagType>
struct StrongT{
Underlying val;
using Tag = TagType;
};
template<typename T>
concept addable = is_specialization<T, StrongT> && requires (T& t){
typename T::Tag::addable_trait;
};
struct IndexTag{
using addable_trait = int;
};
using Index = StrongT<size_t, IndexTag>;
struct NanosTag{
using addable_trait = int;
};
using Nanos = StrongT<size_t, struct NanosTag>;
template<addable T>
T operator + (const T& a, const T& b){
return T{a.val+b.val};
}
I like it since I can list my "traits" in tag struct, but I dislike it since it is a bit spammy. I can not declare tag struct inline like this:
using Nanos = StrongT<size_t, struct NanosTag{/*...*/}>;
So is there way to do what I want in a shorter way, without using inheritance?
note: I only have one trait/concept here, obviously I want many traits supported, e.g. comparable/incrementable...
How about something like
// Different capability tags
struct Addable{};
struct PreIncrementable{};
// ...
template <typename Underlying,
typename TagType,
typename... CapabilityTags>
struct StrongT
{
Underlying val;
using Tag = TagType;
friend StrongT operator+(const StrongT& lhs, const StrongT& rhs)
requires((std::is_same_v<Addable, CapabilityTags> || ...))
{
return T{lhs.val + rhs.val};
}
StrongT& operator++()
requires((std::is_same_v<PreIncrementable, CapabilityTags> || ...))
{
++val;
return *this;
}
//...
};
and then
struct NanosTag;
using Nanos = StrongT<size_t, NanosTag, Addable /*, ..*/>;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With