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:
parent
c07e92e42d
commit
359515e06e
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user