/usr/include/boost/hana/experimental
Edit: /usr/include/boost/hana/experimental/printable.hpp (8329B)
/*
@file
Defines `boost::hana::experimental::print`.
@copyright Louis Dionne 2013-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_HANA_EXPERIMENTAL_PRINTABLE_HPP
#define BOOST_HANA_EXPERIMENTAL_PRINTABLE_HPP
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
// models for different containers
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
BOOST_HANA_NAMESPACE_BEGIN namespace experimental {
template
struct Printable;
//! @cond
template
struct print_impl : print_impl> { };
template
struct print_impl> : hana::default_ {
template
static constexpr auto apply(Args&& ...) = delete;
};
//! @endcond
//! @ingroup group-experimental
//! Returns a string representation of the given object.
//!
//! This function is defined for most containers provided by Hana, and
//! also for objects that define an `operator<<` that can be used with
//! a `std::basic_ostream`. It can recursively print containers within
//! containers, but do not expect any kind of proper indentation.
//!
//! This function requires (the rest of) Boost to be available on the
//! system. It also requires RTTI to be enabled.
#ifdef BOOST_HANA_DOXYGEN_INVOKED
auto print = [](auto const& x) -> std::string {
return tag-dispatched;
};
#else
struct print_t {
template
std::string operator()(T const& t) const {
using Tag = typename hana::tag_of::type;
using Print = BOOST_HANA_DISPATCH_IF(print_impl,
hana::experimental::Printable::value
);
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::experimental::Printable::value,
"hana::experimental::print(t) requires 't' to be Printable");
#endif
return Print::apply(t);
}
};
constexpr print_t print{};
#endif
// Define the `Printable` concept
template
struct Printable {
using Tag = typename hana::tag_of::type;
static constexpr bool value = !hana::is_default>::value;
};
namespace print_detail {
inline std::string strip_type_junk(std::string const& str) {
return std::regex_replace(str, std::regex("(?:struct )?([a-z_]+::)*([a-z_]*)_t<((?:struct )?[a-z:<>_]*)>"), "$2<$3>");
}
}
// model for Sequences
template
struct print_impl::value>> {
template
static std::string apply(Xs const& xs) {
std::string result = "(";
auto comma_separated = hana::intersperse(xs, ", ");
hana::for_each(comma_separated, [&result](auto const& x) {
result += hana::experimental::print(x);
});
result += ")";
return result;
}
};
// model for OutputStreamable types
//! @cond
template
struct print_impl() << std::declval()
)>> {
template
static std::string apply(T const& t) {
std::ostringstream os;
os << t;
return os.str();
}
};
//! @endcond
// model for hana::optional
template <>
struct print_impl {
template
static std::string apply(O const& optional) {
return hana::maybe("nothing",
[](auto const& x) {
return "just(" + hana::experimental::print(x) + ")";
}, optional);
}
};
// model for hana::maps
template <>
struct print_impl {
template
static std::string apply(M const& map) {
std::string result = "{";
auto pairs = hana::transform(hana::to_tuple(map),
[](auto const& pair) {
return hana::experimental::print(hana::first(pair))
+ " => "
+ hana::experimental::print(hana::second(pair));
});
auto comma_separated = hana::intersperse(pairs, ", ");
hana::for_each(comma_separated, [&result](auto const& element) {
result += element;
});
result += "}";
return result;
}
};
// model for hana::metafunctions
template class F>
struct print_impl> {
template
static std::string apply(T const&) {
return print_detail::strip_type_junk(boost::core::demangle(typeid(T).name()));
}
};
// model for hana::metafunction_classes
template
struct print_impl> {
template
static std::string apply(T const&) {
return print_detail::strip_type_junk(boost::core::demangle(typeid(T).name()));
}
};
// model for Constants holding a `Printable`
template
struct print_impl::value &&
Printable::value
>> {
template
static std::string apply(T const&) {
constexpr auto value = hana::value();
return hana::experimental::print(value);
}
};
// model for Products
template
struct print_impl::value>> {
template
static std::string apply(T const& t) {
return '(' + hana::experimental::print(hana::first(t))
+ ", "
+ hana::experimental::print(hana::second(t)) + ')';
}
};
// model for hana::strings
template <>
struct print_impl {
template
static std::string apply(S const& s) {
return '"' + std::string{hana::to(s)} + '"';
}
};
// model for hana::sets
template <>
struct print_impl {
template
static std::string apply(S const& set) {
std::string result = "{";
auto as_tuple = hana::transform(hana::to_tuple(set),
hana::experimental::print);
auto comma_separated = hana::intersperse(as_tuple, ", ");
hana::for_each(comma_separated, [&result](auto const& element) {
result += element;
});
result += "}";
return result;
}
};
// model for hana::templates
template class F>
struct print_impl> {
template
static std::string apply(T const&) {
return print_detail::strip_type_junk(boost::core::demangle(typeid(T).name()));
}
};
// model for hana::types
template <>
struct print_impl {
template
static std::string apply(T const&) {
using Type = typename T::type;
return "type<" + boost::core::demangle(typeid(Type).name()) + '>';
}
};
} BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_EXPERIMENTAL_PRINTABLE_HPP