Remove usage of stringstream and reformulate iteration on tuple elements

in order to  stop the iteration and account for the empty tuple case with
one single specialisation.
We loop at compile time from element 0 to element TUPLE_SIZE - 1
of the tuple. The running index is N which has as initial value
TUPLE_SIZE.
This commit is contained in:
Danilo Piparo 2016-02-04 15:16:37 +01:00 committed by sftnight
parent c07e92e42d
commit 359515e06e

View File

@ -197,7 +197,7 @@ namespace cling {
static const auto comma = ", ";
return comma;
}
template <>
const char *GetCommaOrEmpty<0>()
{
@ -205,47 +205,44 @@ namespace cling {
return empty;
}
template <class TUPLE, std::size_t N = 0>
// We loop at compile time from element 0 to element TUPLE_SIZE - 1
// of the tuple. The running index is N which has as initial value
// TUPLE_SIZE. We can therefore stop the iteration and account for the
// empty tuple case with one single specialisation.
template <class TUPLE,
std::size_t N = std::tuple_size<TUPLE>(),
std::size_t TUPLE_SIZE = std::tuple_size<TUPLE>()>
struct tuplePrinter {
static void print(TUPLE *t, std::ostringstream &ost)
static std::string print(TUPLE *t)
{
using Element_t = decltype(std::get<N>(*t));
ost << GetCommaOrEmpty<N>()
<< cling::printValue(&std::get<N>(*t));
// If N+1 is not smaller than the size of the tuple,
// reroute the call to the printing function to the
constexpr std::size_t elementNumber = TUPLE_SIZE - N;
using Element_t = decltype(std::get<elementNumber>(*t));
std::string ret;
ret += GetCommaOrEmpty<elementNumber>();
ret += cling::printValue(&std::get<elementNumber>(*t));
// If N+1 is not smaller than the size of the tuple,
// reroute the call to the printing function to the
// no-op specialisation to stop recursion.
constexpr std::size_t Np1 = N + 1;
constexpr std::size_t tupleSize = std::tuple_size<TUPLE>::value;
constexpr bool isLastEl = Np1<tupleSize;
using TupleType =
typename std::conditional <isLastEl, TUPLE, std::tuple<>>::type;
tuplePrinter<TupleType, Np1>::print((TupleType *)t, ost);
constexpr std::size_t Nm1 = N - 1;
ret += tuplePrinter<TUPLE, Nm1>::print((TUPLE *)t);
return ret;
}
};
// Special case: no op if last element reached
template <class TUPLE>
struct tuplePrinter<TUPLE, std::numeric_limits<std::size_t>::max()>
// Special case: no op if last element reached or empty tuple
template <class TUPLE, std::size_t TUPLE_SIZE>
struct tuplePrinter<TUPLE, 0, TUPLE_SIZE>
{
static void print(TUPLE *t, std::ostringstream &ost) {}
};
// Special case: no op if empty tuple
template <std::size_t N>
struct tuplePrinter<std::tuple<>, N>
{
static void print(std::tuple<> *t, std::ostringstream &ost) {}
static std::string print(TUPLE *t) {return "";}
};
template <class T>
std::string tuplePairPrintValue(T *val)
{
std::ostringstream ret;
ret << "{ ";
collectionPrinterInternal::tuplePrinter<T>::print(val, ret);
ret << " }";
return ret.str();
std::string ret("{ ");
ret += collectionPrinterInternal::tuplePrinter<T>::print(val);
ret += " }";
return ret;
}
}