From 40f63c24aaa8b17f240980bc816904378ca6ba2e Mon Sep 17 00:00:00 2001 From: Ivan Smirnov Date: Fri, 28 Oct 2016 02:07:00 +0300 Subject: [PATCH] Printers moved to separate file --- array.h | 4 +- printers.h | 144 +++++++++++++++++++++++++++++++++++++++++++++++++++++ repr.h | 137 -------------------------------------------------- 3 files changed, 146 insertions(+), 139 deletions(-) create mode 100644 printers.h diff --git a/array.h b/array.h index 6bf216e..6a92f6f 100644 --- a/array.h +++ b/array.h @@ -4,12 +4,12 @@ #include "common.h" #include "random.h" -#include "repr.h" +#include "printers.h" namespace impl { template -class GenericArray : public Repr>, public std::vector { +class GenericArray : public ReprProxy>, public std::vector { public: typedef std::vector Base; diff --git a/printers.h b/printers.h new file mode 100644 index 0000000..a0f2d50 --- /dev/null +++ b/printers.h @@ -0,0 +1,144 @@ +#pragma once + +#include + +#include "repr.h" + +namespace impl { + +namespace detail { + +#define JNGEN_DEFINE_FUNCTION_CHECKER(name, expr)\ +template\ +class Has ## name ## Helper: public std::false_type {};\ +\ +template\ +class Has ## name ## Helper : public std::true_type {};\ + +#define JNGEN_HAS_FUNCTION(name)\ + detail::Has ## name ## Helper::value + +JNGEN_DEFINE_FUNCTION_CHECKER( + OstreamMethod, + std::declval().operator<< (std::declval()) +) + +JNGEN_DEFINE_FUNCTION_CHECKER( + OstreamFreeFunction, + std::operator<<(std::declval(), std::declval()) +) + +JNGEN_DEFINE_FUNCTION_CHECKER( + Plus, + std::declval() + 1 +) + +#define JNGEN_HAS_OSTREAM()\ + (JNGEN_HAS_FUNCTION(OstreamMethod) ||\ + JNGEN_HAS_FUNCTION(OstreamFreeFunction)) + +template +struct VectorDepth { + constexpr static int value = 0; +}; + +template class C> +struct VectorDepth> { + constexpr static int value = + std::is_base_of< + std::vector, + C + >::value ? VectorDepth::value + 1 : 0; +}; + +} // namespace detail + +#define JNGEN_DECLARE_PRINTER(constraint, priority)\ +template\ +auto printValue(\ + std::ostream& out, const T& t, const OutputModifier& mod, PTag)\ + -> typename std::enable_if::type + +#define JNGEN_DECLARE_SIMPLE_PRINTER(type, priority)\ +void printValue(std::ostream& out, const type& t,\ + const OutputModifier& mod, PTag) + +#define JNGEN_PRINT(value)\ +printValue(out, value, mod, PTagMax{}) + +JNGEN_DECLARE_PRINTER(!JNGEN_HAS_OSTREAM(), 0) +{ + // can't just write 'false' here because assertion always fails + static_assert(!std::is_same::value, "operator<< is undefined"); +} + +JNGEN_DECLARE_PRINTER(JNGEN_HAS_OSTREAM(), 1) +{ + (void)mod; + out << t; +} + +JNGEN_DECLARE_PRINTER( + JNGEN_HAS_OSTREAM() && JNGEN_HAS_FUNCTION(Plus), 2) +{ + out << t + mod.addition; +} + + +JNGEN_DECLARE_PRINTER(detail::VectorDepth::value == 1, 3) +{ + if (mod.printN) { + out << t.size() << "\n"; + } + bool first = true; + for (const auto& x: t) { + if (first) { + first = false; + } else { + out << " "; + } + JNGEN_PRINT(x); + } +} + +JNGEN_DECLARE_PRINTER(detail::VectorDepth::value == 1 && + std::tuple_size::value == 1, 4) +{ + if (mod.printN) { + out << t.size() << "\n"; + } + + for (const auto& x: t) { + JNGEN_PRINT(x); + } +} + +JNGEN_DECLARE_PRINTER(detail::VectorDepth::value == 2, 4) +{ + if (mod.printN) { + out << t.size() << "\n"; + } + for (const auto& x: t) { + JNGEN_PRINT(x); + out << "\n"; + } +} + +// http://stackoverflow.com/a/19841470/2159939 +#define JNGEN_COMMA , + +template +JNGEN_DECLARE_SIMPLE_PRINTER(std::pair, 3) +{ + JNGEN_PRINT(t.first); + out << " "; + JNGEN_PRINT(t.second); +} + +#undef JNGEN_COMMA + +} // namespace impl diff --git a/repr.h b/repr.h index 711cdcd..2c86645 100644 --- a/repr.h +++ b/repr.h @@ -112,148 +112,11 @@ class ReprProxy { } }; - - -namespace detail { - -#define JNGEN_DEFINE_FUNCTION_CHECKER(name, expr)\ -template\ -class Has ## name ## Helper: public std::false_type {};\ -\ -template\ -class Has ## name ## Helper : public std::true_type {};\ - -#define JNGEN_HAS_FUNCTION(name)\ - detail::Has ## name ## Helper::value - -JNGEN_DEFINE_FUNCTION_CHECKER( - OstreamMethod, - std::declval().operator<< (std::declval()) -) - -JNGEN_DEFINE_FUNCTION_CHECKER( - OstreamFreeFunction, - std::operator<<(std::declval(), std::declval()) -) - -JNGEN_DEFINE_FUNCTION_CHECKER( - Plus, - std::declval() + 1 -) - -#define JNGEN_HAS_OSTREAM()\ - (JNGEN_HAS_FUNCTION(OstreamMethod) ||\ - JNGEN_HAS_FUNCTION(OstreamFreeFunction)) - -template -struct VectorDepth { - constexpr static int value = 0; -}; - -template class C> -struct VectorDepth> { - constexpr static int value = - std::is_base_of< - std::vector, - C - >::value ? VectorDepth::value + 1 : 0; -}; - -} // namespace detail - -#define JNGEN_DECLARE_PRINTER(constraint, priority)\ -template\ -auto printValue(\ - std::ostream& out, const T& t, const OutputModifier& mod, PTag)\ - -> typename std::enable_if::type - -#define JNGEN_DECLARE_SIMPLE_PRINTER(type, priority)\ -void printValue(std::ostream& out, const type& t,\ - const OutputModifier& mod, PTag) - -#define JNGEN_PRINT(value)\ -printValue(out, value, mod, PTagMax{}) - -JNGEN_DECLARE_PRINTER(!JNGEN_HAS_OSTREAM(), 0) -{ - // can't just write 'false' here because assertion always fails - static_assert(!std::is_same::value, "operator<< is undefined"); -} - -JNGEN_DECLARE_PRINTER(JNGEN_HAS_OSTREAM(), 1) -{ - (void)mod; - out << t; -} - -JNGEN_DECLARE_PRINTER( - JNGEN_HAS_OSTREAM() && JNGEN_HAS_FUNCTION(Plus), 2) -{ - out << t + mod.addition; -} - - -JNGEN_DECLARE_PRINTER(detail::VectorDepth::value == 1, 3) -{ - if (mod.printN) { - out << t.size() << "\n"; - } - bool first = true; - for (const auto& x: t) { - if (first) { - first = false; - } else { - out << " "; - } - JNGEN_PRINT(x); - } -} - -JNGEN_DECLARE_PRINTER(detail::VectorDepth::value == 1 && - std::tuple_size::value == 1, 4) -{ - if (mod.printN) { - out << t.size() << "\n"; - } - - for (const auto& x: t) { - JNGEN_PRINT(x); - } -} - -JNGEN_DECLARE_PRINTER(detail::VectorDepth::value == 2, 4) -{ - if (mod.printN) { - out << t.size() << "\n"; - } - for (const auto& x: t) { - JNGEN_PRINT(x); - out << "\n"; - } -} - template Repr repr(const T& t) { return Repr(t); } -// http://stackoverflow.com/a/19841470/2159939 -#define JNGEN_COMMA , - -template -JNGEN_DECLARE_SIMPLE_PRINTER(std::pair, 3) -{ - JNGEN_PRINT(t.first); - out << " "; - JNGEN_PRINT(t.second); -} - -#undef JNGEN_COMMA - } // namespace impl using impl::repr;