/** @file cond.hpp * * author: Roland Conybeare **/ #pragma once #include "ppdetail_atomic.hpp" #include #include namespace xo { /** @class cond_impl * @brief conditional stream inserter implementation * * @tparam T type printed when condition is true * @tparam U type printed when condition is false **/ template struct cond_impl { public: cond_impl(bool condition, const T & if_true, const U & if_false) : condition_{condition}, if_true_{if_true}, if_false_{if_false} {} bool condition() const { return condition_; } const T & if_true() const { return if_true_; } const U & if_false() const { return if_false_; } private: bool condition_; T if_true_; U if_false_; }; /** Create conditional stream inserter. * * @param condition when true, print @p if_true; otherwise print @p if_false * @param if_true value to print when condition is true * @param if_false value to print when condition is false * * Example: * @code * std::cout << cond(ptr, xtag("ptr", *ptr), "nullptr"); * @endcode **/ template auto cond(bool condition, T && if_true, U && if_false) { return cond_impl, std::decay_t> (condition, std::forward(if_true), std::forward(if_false)); } /** Stream insertion operator for cond_impl **/ template inline std::ostream & operator<<(std::ostream & os, const cond_impl & c) { if (c.condition()) os << c.if_true(); else os << c.if_false(); return os; } #ifndef ppdetail_atomic namespace print { /** Pretty-printing support for cond_impl **/ template struct ppdetail> { using target_type = cond_impl; static bool print_pretty(const ppindentinfo & ppii, const target_type & c) { if (c.condition()) return ppdetail::print_pretty(ppii, c.if_true()); else return ppdetail::print_pretty(ppii, c.if_false()); } }; } #endif } /* end cond.hpp */