-
Notifications
You must be signed in to change notification settings - Fork 37
Description
I tried to add a modifier, that accesses more functionality.
I program a lot with the Qt Framework and though how to make a typical line:
int foo = 0;
qDebug() << foo;available for a strong typed int.
A simple
using myint = strong::type<int, struct my_int_>;
myint foo{0};
qDebug() << foo;does not work, it won't compile because QDebug does not know anything about myint.
One way would be to convert it back to its base type
using myint = strong::type<int, struct my_int_>;
myint foo{0};
qDebug() << (int)foo;but this won't work, as the conversion to int has to be added as a modifier:
using myint = strong::type<int, struct my_int_, strong::convertible_to<int>>;
myint foo{0};
qDebug() << (int)foo;However, this does not
- look nice and
- if I change the underlying type to something more appropriate for the strong type, it might even not be convertable to
intanymore!
I could get rid of the (int) C-style converter if I'd use the modifier: strong::implicitly_convertible_to<Ts...> but this only helps for the first problem. And it would feel like washing away the "strong" in Strong Types ...
Looking at the documentation of how QDebug in Qt works I tried to add a new modifier: qdebuggable.
I would like to kindly request comments from you, if the modifier is appropriate, to what I want to reach:
#pragma once
#include <strong_type/type.hpp>
#include <QDebug>
namespace strong
{
struct qdebuggable
{
template <typename T, typename = void>
class modifier {
static_assert(impl::always_false<T>,
"Underlying type must be qdebuggable");
};
};
template <typename T, typename Tag, typename ... M>
class qdebuggable::modifier<
::strong::type<T, Tag, M...>,
impl::void_t<decltype(operator<<(std::declval<QDebug>(), std::declval<const T&>()))>
>
{
using type = ::strong::type<T, Tag, M...>;
public:
friend
auto
operator<<(
QDebug dbg,
const type& value)
noexcept(noexcept(operator<<(std::declval<QDebug>(), std::declval<const T&>())))
-> decltype(operator<<(std::declval<QDebug>(), std::declval<const T&>()))
{
dbg << value_of(value);
return dbg;
}
};
}I tried it with some base types that are supported by QDebug directly and also by User Defined Types as base type where a QDebug stream operator was added to.
As the QLoggingCategory also relies on QDebug mechanism all Qt Debugging seems to work fine.
The Qt Framwork also offers some similar patterns with QDataStream and QTextStream. Probably there are more...
But befor I sit on these, I'd like to be sure that this first modifier is "right".
Thanks.