2
0
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:
jofaber
2025-12-15 18:21:06 +01:00
parent 2ee401927f
commit dd96c80ddc
5 changed files with 132 additions and 54 deletions

View File

@@ -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);
}

View File

@@ -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>

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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