mirror of
https://github.com/boostorg/icl.git
synced 2026-01-19 16:22:18 +00:00
Fixed type_to_string template for Unary and Binary cases to comply c++11 and higher. Added co_equal_fwd.hpp and got default values right. Replaced deprecated sprintf in toytime.
This commit is contained in:
@@ -40,9 +40,9 @@ public:
|
||||
|
||||
std::string as_string()const
|
||||
{
|
||||
const int MAX_TIMESTING_LEN = 256;
|
||||
char repr[MAX_TIMESTING_LEN];
|
||||
sprintf(repr, "%3s:%02d:%02d", getDayString().c_str(), getHours(), getMinutes());
|
||||
const int max_timestring_len = 256;
|
||||
char repr[max_timestring_len];
|
||||
snprintf(repr, max_timestring_len, "%3s:%02d:%02d", getDayString().c_str(), getHours(), getMinutes());
|
||||
return std::string(repr);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ Copyright (c) 2010-2010: Joachim Faulhaber
|
||||
#include <boost/icl/type_traits/is_key_container_of.hpp>
|
||||
#include <boost/icl/type_traits/is_combinable.hpp>
|
||||
#include <boost/icl/detail/subset_comparer.hpp>
|
||||
#include <boost/icl/detail/associated_value.hpp>
|
||||
#include <boost/icl/concept/element_set.hpp>
|
||||
#include <boost/icl/concept/element_map.hpp>
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ typename enable_if< mpl::and_< is_key_compare_equal<Type,CoType>
|
||||
, mpl::and_<is_map<Type>, is_map<CoType> > >,
|
||||
bool>::type
|
||||
co_equal(typename Type::const_iterator left_, typename CoType::const_iterator right_,
|
||||
const Type* = 0, const CoType* = 0)
|
||||
const Type*, const CoType*)
|
||||
{
|
||||
return co_value<Type>(left_) == co_value<CoType>(right_);
|
||||
}
|
||||
@@ -31,7 +31,7 @@ typename enable_if< mpl::and_< is_key_compare_equal<Type,CoType>
|
||||
, mpl::not_<mpl::and_<is_map<Type>, is_map<CoType> > > >,
|
||||
bool>::type
|
||||
co_equal(typename Type::const_iterator, typename CoType::const_iterator,
|
||||
const Type* = 0, const CoType* = 0)
|
||||
const Type*, const CoType*)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -8,26 +8,54 @@ Copyright (c) 1999-2006: Cortex Software GmbH, Kantstrasse 57, Berlin
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
+-----------------------------------------------------------------------------*/
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Function-templates for discrete Datatypes like int, unsigned or
|
||||
any class that provides a ++ operator c.f. iterators
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef BOOST_ICL_TO_STRING_HPP_JOFA_000712
|
||||
#define BOOST_ICL_TO_STRING_HPP_JOFA_000712
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <iterator>
|
||||
|
||||
namespace boost{ namespace icl
|
||||
{
|
||||
|
||||
/// Static class template for the string representation of values
|
||||
template <class Type>
|
||||
// Helper: detect streamability: whether "std::declval<std::ostream&>() << std::declval<T>()"
|
||||
// is a valid expression.
|
||||
template <class T, class = void>
|
||||
struct is_streamable : std::false_type {};
|
||||
|
||||
template <class T>
|
||||
struct is_streamable<T, decltype(void(std::declval<std::ostream&>() << std::declval<T>()))>
|
||||
: std::true_type {};
|
||||
|
||||
// Helper: detect iterable (has begin/end via ADL or std::begin/std::end)
|
||||
template <class T, class = void>
|
||||
struct is_iterable : std::false_type {};
|
||||
|
||||
template <class T>
|
||||
struct is_iterable<T, decltype(void(std::begin(std::declval<T>()), std::end(std::declval<T>())))>
|
||||
: std::true_type {};
|
||||
|
||||
// convenience alias
|
||||
template <bool B>
|
||||
using enable_if_t = typename std::enable_if<B, void>::type;
|
||||
|
||||
/// Primary template: fallback for unprintable types
|
||||
template <class Type, class Enable = void>
|
||||
struct to_string
|
||||
{
|
||||
/** Converts all values of types to std::string that implement an operator << */
|
||||
static std::string apply(const Type&)
|
||||
{
|
||||
return std::string("<unprintable>");
|
||||
}
|
||||
};
|
||||
|
||||
// Specialization for types that are streamable
|
||||
template <class Type>
|
||||
struct to_string<Type, enable_if_t<is_streamable<Type>::value> >
|
||||
{
|
||||
static std::string apply(const Type& value)
|
||||
{
|
||||
std::stringstream repr;
|
||||
@@ -36,8 +64,33 @@ struct to_string
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace boost icl
|
||||
// Specialization for iterable types that are not streamable
|
||||
// (we print their elements using recursive to_string)
|
||||
template <class Type>
|
||||
struct to_string<Type, enable_if_t<!is_streamable<Type>::value && is_iterable<Type>::value> >
|
||||
{
|
||||
static std::string apply(const Type& value)
|
||||
{
|
||||
std::stringstream repr;
|
||||
repr << "{";
|
||||
|
||||
#endif
|
||||
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<decltype(*it)>::type;
|
||||
repr << boost::icl::to_string<ElemT>::apply(*it);
|
||||
}
|
||||
|
||||
repr << "}";
|
||||
return repr.str();
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace boost::icl
|
||||
|
||||
#endif // BOOST_ICL_TO_STRING_HPP_JOFA_000712
|
||||
@@ -12,80 +12,104 @@ Copyright (c) 2007-2009: Joachim Faulhaber
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/type_traits/is_float.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
|
||||
namespace boost{ namespace icl
|
||||
{
|
||||
//--------------------------------------------------------------------------
|
||||
template<class Type>
|
||||
// Primary template: note the additional defaulted Enable parameter so we can SFINAE
|
||||
template<class Type, class Enable = void>
|
||||
struct type_to_string
|
||||
{
|
||||
/** Convert the type to it's typestring */
|
||||
/** Convert the type to its typestring */
|
||||
static std::string apply();
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
template<>inline std::string type_to_string<bool>::apply() { return "bool"; }
|
||||
template<>inline std::string type_to_string<char>::apply() { return "char"; }
|
||||
template<>inline std::string type_to_string<short>::apply(){ return "short"; }
|
||||
template<>inline std::string type_to_string<int>::apply() { return "int"; }
|
||||
template<>inline std::string type_to_string<long>::apply() { return "long"; }
|
||||
template<>inline std::string type_to_string<long long>::apply(){ return "Long"; }
|
||||
// Explicit specializations for builtins (Enable defaults to void)
|
||||
template<> inline std::string type_to_string<bool, void>::apply() { return "bool"; }
|
||||
template<> inline std::string type_to_string<char, void>::apply() { return "char"; }
|
||||
template<> inline std::string type_to_string<short, void>::apply(){ return "short"; }
|
||||
template<> inline std::string type_to_string<int, void>::apply() { return "int"; }
|
||||
template<> inline std::string type_to_string<long, void>::apply() { return "long"; }
|
||||
template<> inline std::string type_to_string<long long, void>::apply(){ return "Long"; }
|
||||
|
||||
template<>inline std::string type_to_string<unsigned char>::apply(){ return "char+"; }
|
||||
template<>inline std::string type_to_string<unsigned short>::apply(){ return "short+"; }
|
||||
template<>inline std::string type_to_string<unsigned int>::apply() { return "int+"; }
|
||||
template<>inline std::string type_to_string<unsigned long>::apply() { return "long+"; }
|
||||
template<>inline std::string type_to_string<unsigned long long>::apply(){ return "Long+"; }
|
||||
template<> inline std::string type_to_string<unsigned char, void>::apply(){ return "char+"; }
|
||||
template<> inline std::string type_to_string<unsigned short, void>::apply(){ return "short+"; }
|
||||
template<> inline std::string type_to_string<unsigned int, void>::apply() { return "int+"; }
|
||||
template<> inline std::string type_to_string<unsigned long, void>::apply() { return "long+"; }
|
||||
template<> inline std::string type_to_string<unsigned long long, void>::apply(){ return "Long+"; }
|
||||
|
||||
template<>inline std::string type_to_string<float>::apply() { return "flt"; }
|
||||
template<>inline std::string type_to_string<double>::apply() { return "dbl"; }
|
||||
template<> inline std::string type_to_string<float, void>::apply() { return "flt"; }
|
||||
template<> inline std::string type_to_string<double, void>::apply() { return "dbl"; }
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
template<template<class> class Templ>
|
||||
template<template<class...> class Templ>
|
||||
struct unary_template_to_string
|
||||
{
|
||||
static std::string apply();
|
||||
};
|
||||
|
||||
template <template<class>class Unary, class Type>
|
||||
struct type_to_string<Unary<Type> >
|
||||
{
|
||||
static std::string to_string()
|
||||
{
|
||||
return unary_template_to_string<Unary>::apply()+"<"+type_to_string<Type>::apply()+">";
|
||||
}
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
template<template<class,class>class Templ>
|
||||
template<template<class...> class Templ>
|
||||
struct binary_template_to_string
|
||||
{
|
||||
static std::string apply();
|
||||
};
|
||||
|
||||
template <template<class Type1, class Type2>class Binary, class Type1, class Type2>
|
||||
struct type_to_string<Binary<Type1, Type2> >
|
||||
// ---------------------------------------------------------------------------
|
||||
template<>
|
||||
struct type_to_string<std::string, void>
|
||||
{
|
||||
static std::string apply() { return "string"; }
|
||||
};
|
||||
|
||||
// =======================================================================
|
||||
// Constrained partial specializations:
|
||||
// - unary: matches only when the template instantiation has exactly 1 type parameter
|
||||
// - binary: matches only when the template instantiation has exactly 2 type parameters
|
||||
//
|
||||
// These use template<template<class...> class ...> + sizeof...(Args) to SFINAE-out
|
||||
// matches for templates with different number of type-parameters (including those
|
||||
// that have additional defaulted parameters).
|
||||
// =======================================================================
|
||||
|
||||
// unary: exactly one type parameter (C++11-compatible enable_if)
|
||||
template< template<class...> class Unary, class... Args >
|
||||
struct type_to_string< Unary<Args...>,
|
||||
typename std::enable_if< (sizeof...(Args) == 1), void >::type
|
||||
>
|
||||
{
|
||||
using First = typename std::tuple_element<0, std::tuple<Args...> >::type;
|
||||
|
||||
static std::string apply()
|
||||
{
|
||||
return binary_template_to_string<Binary>::apply()+
|
||||
"<"+type_to_string<Type1>::apply()+","+type_to_string<Type2>::apply()+">";
|
||||
{
|
||||
return unary_template_to_string<Unary>::apply()
|
||||
+ "<" + type_to_string<First>::apply() + ">";
|
||||
}
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
template<>
|
||||
struct type_to_string<std::string>
|
||||
// binary: exactly two type parameters (C++11-compatible enable_if)
|
||||
template< template<class...> class Binary, class... Args >
|
||||
struct type_to_string< Binary<Args...>,
|
||||
typename std::enable_if< (sizeof...(Args) == 2), void >::type
|
||||
>
|
||||
{
|
||||
static std::string apply() { return "string"; }
|
||||
using First = typename std::tuple_element<0, std::tuple<Args...> >::type;
|
||||
using Second = typename std::tuple_element<1, std::tuple<Args...> >::type;
|
||||
|
||||
static std::string apply()
|
||||
{
|
||||
return binary_template_to_string<Binary>::apply()
|
||||
+ "<" + type_to_string<First>::apply()
|
||||
+ "," + type_to_string<Second>::apply() + ">";
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace boost icl
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user