Edit: /usr/include/boost/yap/print.hpp (10708B)
// Copyright (C) 2016-2018 T. Zachary Laine
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_YAP_PRINT_HPP_INCLUDED
#define BOOST_YAP_PRINT_HPP_INCLUDED
#include
#include
#include
#include
namespace boost { namespace yap {
/** Returns the char const * string for the spelling of the
C++ operator associated with \a kind. It returns the special values
"ref" and "term" for the non-operator kinds
expr_kind::expr_ref amd expr_kind::terminal,
respectively.*/
inline constexpr char const * op_string(expr_kind kind)
{
switch (kind) {
case expr_kind::expr_ref: return "ref";
case expr_kind::terminal: return "term";
case expr_kind::unary_plus: return "+";
case expr_kind::negate: return "-";
case expr_kind::dereference: return "*";
case expr_kind::complement: return "~";
case expr_kind::address_of: return "&";
case expr_kind::logical_not: return "!";
case expr_kind::pre_inc: return "++";
case expr_kind::pre_dec: return "--";
case expr_kind::post_inc: return "++(int)";
case expr_kind::post_dec: return "--(int)";
case expr_kind::shift_left: return "<<";
case expr_kind::shift_right: return ">>";
case expr_kind::multiplies: return "*";
case expr_kind::divides: return "/";
case expr_kind::modulus: return "%";
case expr_kind::plus: return "+";
case expr_kind::minus: return "-";
case expr_kind::less: return "<";
case expr_kind::greater: return ">";
case expr_kind::less_equal: return "<=";
case expr_kind::greater_equal: return ">=";
case expr_kind::equal_to: return "==";
case expr_kind::not_equal_to: return "!=";
case expr_kind::logical_or: return "||";
case expr_kind::logical_and: return "&&";
case expr_kind::bitwise_and: return "&";
case expr_kind::bitwise_or: return "|";
case expr_kind::bitwise_xor: return "^";
case expr_kind::comma: return ",";
case expr_kind::mem_ptr: return "->*";
case expr_kind::assign: return "=";
case expr_kind::shift_left_assign: return "<<=";
case expr_kind::shift_right_assign: return ">>=";
case expr_kind::multiplies_assign: return "*=";
case expr_kind::divides_assign: return "/=";
case expr_kind::modulus_assign: return "%=";
case expr_kind::plus_assign: return "+=";
case expr_kind::minus_assign: return "-=";
case expr_kind::bitwise_and_assign: return "&=";
case expr_kind::bitwise_or_assign: return "|=";
case expr_kind::bitwise_xor_assign: return "^=";
case expr_kind::subscript: return "[]";
case expr_kind::if_else: return "?:";
case expr_kind::call: return "()";
default: return "** ERROR: UNKNOWN OPERATOR! **";
}
}
namespace detail {
inline std::ostream & print_kind(std::ostream & os, expr_kind kind)
{
return os << op_string(kind);
}
template>
struct printer
{
std::ostream & operator()(std::ostream & os, T const &)
{
return os << "<>";
}
};
template
struct printer<
T,
void_t() << std::declval())>>
{
std::ostream & operator()(std::ostream & os, T const & x)
{
return os << x;
}
};
template
inline std::ostream & print_value(std::ostream & os, T const & x)
{
return printer{}(os, x);
}
template
inline std::ostream & print_value(std::ostream & os, hana::llong)
{
return os << I << "_p";
}
template
std::ostream & print_type(std::ostream & os, hana::tuple const &)
{
os << typeindex::type_id().pretty_name();
if (std::is_const>::value)
os << " const";
if (std::is_volatile>::value)
os << " volatile";
if (std::is_lvalue_reference::value)
os << " &";
if (std::is_rvalue_reference::value)
os << " &&";
return os;
}
template
bool is_const_expr_ref(T const &)
{
return false;
}
template class expr_template>
bool is_const_expr_ref(
expr_template> const &)
{
return true;
}
#ifdef BOOST_NO_CONSTEXPR_IF
template
struct print_impl
{
template
std::ostream & operator()(
std::ostream & os,
Expr const & expr,
int indent,
char const * indent_str,
bool is_ref = false,
bool is_const_ref = false)
{
for (int i = 0; i < indent; ++i) {
os << indent_str;
}
os << "expr<";
::boost::yap::detail::print_kind(os, Expr::kind);
os << ">";
if (is_const_ref)
os << " const &";
else if (is_ref)
os << " &";
os << "\n";
hana::for_each(
expr.elements,
[&os, indent, indent_str](auto const & element) {
using element_type = decltype(element);
constexpr expr_kind kind =
detail::remove_cv_ref_t::kind;
print_impl{}(os, element, indent + 1, indent_str);
});
return os;
}
};
template<>
struct print_impl
{
template
std::ostream & operator()(
std::ostream & os,
Expr const & expr,
int indent,
char const * indent_str,
bool is_ref = false,
bool is_const_ref = false)
{
using ref_type = decltype(::boost::yap::deref(expr));
constexpr expr_kind ref_kind =
detail::remove_cv_ref_t::kind;
print_impl{}(
os,
::boost::yap::deref(expr),
indent,
indent_str,
true,
::boost::yap::detail::is_const_expr_ref(expr));
return os;
}
};
template<>
struct print_impl
{
template
std::ostream & operator()(
std::ostream & os,
Expr const & expr,
int indent,
char const * indent_str,
bool is_ref = false,
bool is_const_ref = false)
{
for (int i = 0; i < indent; ++i) {
os << indent_str;
}
os << "term<";
::boost::yap::detail::print_type(os, expr.elements);
os << ">[=";
::boost::yap::detail::print_value(
os, ::boost::yap::value(expr));
os << "]";
if (is_const_ref)
os << " const &";
else if (is_ref)
os << " &";
os << "\n";
return os;
}
};
#else
template
std::ostream & print_impl(
std::ostream & os,
Expr const & expr,
int indent,
char const * indent_str,
bool is_ref = false,
bool is_const_ref = false)
{
if constexpr (Expr::kind == expr_kind::expr_ref) {
print_impl(
os,
::boost::yap::deref(expr),
indent,
indent_str,
true,
::boost::yap::detail::is_const_expr_ref(expr));
} else {
for (int i = 0; i < indent; ++i) {
os << indent_str;
}
if constexpr (Expr::kind == expr_kind::terminal) {
os << "term<";
::boost::yap::detail::print_type(os, expr.elements);
os << ">[=";
::boost::yap::detail::print_value(
os, ::boost::yap::value(expr));
os << "]";
if (is_const_ref)
os << " const &";
else if (is_ref)
os << " &";
os << "\n";
} else {
os << "expr<";
::boost::yap::detail::print_kind(os, Expr::kind);
os << ">";
if (is_const_ref)
os << " const &";
else if (is_ref)
os << " &";
os << "\n";
hana::for_each(
expr.elements,
[&os, indent, indent_str](auto const & element) {
::boost::yap::detail::print_impl(
os, element, indent + 1, indent_str);
});
}
}
return os;
}
#endif // BOOST_NO_CONSTEXPR_IF
}
/** Prints expression \a expr to stream \a os. Returns \a os. */
template
std::ostream & print(std::ostream & os, Expr const & expr)
{
#ifdef BOOST_NO_CONSTEXPR_IF
return detail::print_impl::kind>{}(
os, expr, 0, " ");
#else
return detail::print_impl(os, expr, 0, " ");
#endif
}
}}
#endif