-
Notifications
You must be signed in to change notification settings - Fork 112
Utility::Debug: add std::ostream output operator call converter #88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 1 commit
6964c21
bcc6544
dfa849b
8b1e935
cf3f6fd
8b048e6
05cfb24
3b75172
be5dfa9
9abf7c3
b3129ed
07dad62
ccb7bcd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -103,9 +103,32 @@ template<class ...Args> Debug& operator<<(Debug& debug, const std::tuple<Args... | |
|
|
||
| namespace Implementation { | ||
|
|
||
| template<typename T> | ||
| typename std::add_lvalue_reference<T>::type declare_lvalue_reference() noexcept; | ||
|
|
||
| template<typename T> | ||
| struct has_ostream_operator { | ||
| private: | ||
| template<typename C> | ||
| static constexpr auto check(C *) -> | ||
| typename std::is_same< | ||
| decltype(declare_lvalue_reference<std::ostream>() << std::declval<C>()), | ||
| std::add_lvalue_reference<std::ostream>::type | ||
| >::type; | ||
|
|
||
| template<typename> | ||
| static constexpr std::false_type check(...); | ||
|
|
||
| public: | ||
| static constexpr bool value = decltype(check<T>(nullptr))::value; | ||
| }; | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's a (admittedly weirdly named) CORRADE_HAS_TYPE(className, typeExpression) macro that already contains the above functionality, but your variant seems to be a lot simpler than what I stole from somewhere back in the day :) If I fix the macro to have the second parameter variadic (so the comma doesn't break it), I think we could then reduce the above to be just this (containing the potentially hard-to-understand template magic in a single place): CORRADE_HAS_TYPE(HasOstreamOperator, typename std::is_same<
decltype(declareLvalueReference<std::ostream>() << std::declval<C>()),
std::add_lvalue_reference<std::ostream>::type
>::type)(Also adapting the naming to what Corrade uses for type traits.) I hope I didn't overlook something that would make this impossible tho.
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
CORRADE_HAS_TYPE(HasOstreamOperator, typename std::enable_if<std::is_same<
decltype(declareLvalueReference<std::ostream>() << std::declval<C>()),
std::add_lvalue_reference<std::ostream>::type
>::value>::type)I assume you have some way to test the infinite recursion already -- can you confirm? :)
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes! works perfectly. A very useful macro too |
||
|
|
||
| /* Used by Debug::operator<<(Implementation::DebugOstreamFallback&&) */ | ||
| struct DebugOstreamFallback { | ||
| template<class T> /*implicit*/ DebugOstreamFallback(const T& t): applier(&DebugOstreamFallback::applyImpl<T>), value(&t) {} | ||
| template< | ||
| class T, | ||
| typename = typename std::enable_if<has_ostream_operator<T>::value>::type | ||
| > /*implicit*/ DebugOstreamFallback(const T& t): applier(&DebugOstreamFallback::applyImpl<T>), value(&t) {} | ||
|
|
||
| void apply(std::ostream& s) const { | ||
| (this->*applier)(s); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.