/*-----------------------------------------------------------------------------+ Copyright (c) 2007-2009: Joachim Faulhaber +------------------------------------------------------------------------------+ Copyright (c) 1999-2006: Cortex Software GmbH, Kantstrasse 57, Berlin +------------------------------------------------------------------------------+ Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENCE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +-----------------------------------------------------------------------------*/ #ifndef BOOST_ICL_TO_STRING_HPP_JOFA_000712 #define BOOST_ICL_TO_STRING_HPP_JOFA_000712 #include #include #include #include #include #include namespace boost{ namespace icl { // Helper: detect streamability: whether "std::declval() << std::declval()" // is a valid expression. template struct is_streamable : std::false_type {}; template struct is_streamable() << std::declval()))> : std::true_type {}; // Helper: detect iterable (has begin/end via ADL or std::begin/std::end) template struct is_iterable : std::false_type {}; template struct is_iterable()), std::end(std::declval())))> : std::true_type {}; // convenience alias template using enable_if_t = typename std::enable_if::type; /// Primary template: fallback for unprintable types template struct to_string { static std::string apply(const Type&) { return std::string(""); } }; // Specialization for types that are streamable template struct to_string::value> > { static std::string apply(const Type& value) { std::stringstream repr; repr << value; return repr.str(); } }; // Specialization for iterable types that are not streamable // (we print their elements using recursive to_string) template struct to_string::value && is_iterable::value> > { static std::string apply(const Type& value) { std::stringstream repr; repr << "{"; auto it = std::begin(value); auto end = std::end(value); bool first = true; for (; it != end; ++it) { if (!first) repr << ", "; first = false; // element may be a reference type; pass by const-ref using ElemT = typename std::decay::type; repr << boost::icl::to_string::apply(*it); } repr << "}"; return repr.str(); } }; }} // namespace boost::icl #endif // BOOST_ICL_TO_STRING_HPP_JOFA_000712