<commit_before>//--------------------------------------------------------------------*- C++ -*-
// CLING - the C++ LLVM-based InterpreterG :)
// author:  <NAME> <<EMAIL>>
// author:  <NAME> <<EMAIL>>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------
#ifndef CLING_RUNTIME_PRINT_VALUE_H
#define CLING_RUNTIME_PRINT_VALUE_H

#if !defined(__CLING__)
#error "This file must not be included by compiled programs."
#endif

#include <string>
#include <tuple>
#include <type_traits>

namespace cling {

#ifdef _WIN32
  // FIXME: Interpreter currently needs to construct the first std::string
  namespace horriblehack { static const std::string kRealyyBad; }
#endif

  class Value;

  // General fallback - prints the address
  std::string printValue(const void *ptr);

  // Fallback for e.g. vector<bool>'s bit iterator:
  template <class T,
    class = typename std::enable_if<!std::is_pointer<T>::value>::type>
  std::string printValue(const T& val) { return "{not representable}"; }

  // void pointer
  std::string printValue(const void **ptr);

  // Bool
  std::string printValue(const bool *val);

  // Chars
  std::string printValue(const char *val);

  std::string printValue(const signed char *val);

  std::string printValue(const unsigned char *val);

  std::string printValue(const char16_t *val);

  std::string printValue(const char32_t *val);

  std::string printValue(const wchar_t *val);

  // Ints
  std::string printValue(const short *val);

  std::string printValue(const unsigned short *val);

  std::string printValue(const int *val);

  std::string printValue(const unsigned int *val);

  std::string printValue(const long *val);

  std::string printValue(const unsigned long *val);

  std::string printValue(const long long *val);

  std::string printValue(const unsigned long long *val);

  // Reals
  std::string printValue(const float *val);

  std::string printValue(const double *val);

  std::string printValue(const long double *val);

  // Char pointers
  std::string printValue(const char *const *val);

  std::string printValue(const char **val);

  // std::string
  std::string printValue(const std::string *val);

  std::string printValue(const std::wstring *val);

  std::string printValue(const std::u16string *val);

  std::string printValue(const std::u32string *val);

  // constant unicode strings, i.e. u"String"
  template <typename T>
  std::string toUTF8(const T* const Src, size_t N, const char Prefix = 0);

  template <size_t N>
  std::string printValue(char16_t const (*val)[N]) {
    return toUTF8(reinterpret_cast<const char16_t * const>(val), N, 'u');
  }

  template <size_t N>
  std::string printValue(char32_t const (*val)[N]) {
    return toUTF8(reinterpret_cast<const char32_t * const>(val), N, 'U');
  }

  template <size_t N>
  std::string printValue(wchar_t const (*val)[N]) {
#ifdef _WIN32
    return toUTF8(reinterpret_cast<const char16_t * const>(val), N, 'L');
#else
    return toUTF8(reinterpret_cast<const char32_t * const>(val), N, 'L');
#endif
  }

  template <size_t N>
  std::string printValue(char const (*val)[N]) {
    return toUTF8(reinterpret_cast<const char * const>(val), N, 1);
  }

  // cling::Value
  std::string printValue(const Value *value);

  namespace valuePrinterInternal {
    extern const char* const kEmptyCollection;
  }

  // Collections internal
  namespace collectionPrinterInternal {
    // Maps
    template<typename Pair>
    std::string printPair(const Pair& P) {
      return printValue(&P->first) + " => " + printValue(&P->second);
    }
    
    template<typename CollectionType>
    auto printValue_impl(const CollectionType *obj, short)
    -> decltype(
    ++(obj->begin()), obj->end(),
        obj->begin()->first, obj->begin()->second,
        std::string())
    {
      auto iter = obj->begin();
      auto iterEnd = obj->end();
      if (iter == iterEnd)
        return valuePrinterInternal::kEmptyCollection;

      std::string str("{ ");
      str += printPair(iter);
      while (++iter != iterEnd) {
        str += ", ";
        str += printPair(iter);
      }
      return str + " }";
    }

    // Vector, set, deque etc.
    template<typename CollectionType>
    auto printValue_impl(const CollectionType *obj, int)
    -> decltype(
    ++(obj->begin()), obj->end(),
        *(obj->begin()),  &(*(obj->begin())),
        std::string())
    {
      auto iter = obj->begin();
      auto iterEnd = obj->end();
      if (iter == iterEnd)
        return valuePrinterInternal::kEmptyCollection;

      std::string str("{ ");
      str += printValue(&(*iter));
      while (++iter != iterEnd) {
        str += ", ";
        str += printValue(&(*iter));
      }
      return str + " }";
    }

    // As above, but without ability to take address of elements.
    template<typename CollectionType>
    auto printValue_impl(const CollectionType *obj, long)
    -> decltype(
    ++(obj->begin()), obj->end(),
        *(obj->begin()),
        std::string())
     {
      auto iter = obj->begin();
      auto iterEnd = obj->end();
      if (iter == iterEnd)
        return valuePrinterInternal::kEmptyCollection;

      std::string str("{ ");
      const auto value0 = (*iter);
      str += printValue(&value0);
      while (++iter != iterEnd) {
        const auto valueN = (*iter);
        str += ", ";
        str += printValue(&valueN);
      }
      return str + " }";
     }
  }

  // Collections
  template<typename CollectionType>
  auto printValue(const CollectionType *obj)
  -> decltype(collectionPrinterInternal::printValue_impl(obj, 0), std::string())
  {
    // short -> int -> long = priority order
    return collectionPrinterInternal::printValue_impl(obj, (short)0);
  }

  // Arrays
  template<typename T, size_t N>
  std::string printValue(const T (*obj)[N]) {
    if (N == 0)
      return valuePrinterInternal::kEmptyCollection;

    std::string str = "{ ";
    str += printValue(*obj + 0);
    for (size_t i = 1; i < N; ++i) {
      str += ", ";
      str += printValue(*obj + i);
    }
    return str + " }";
  }

  // Tuples
  template <class... ARGS>
  std::string printValue(std::tuple<ARGS...> *);

  namespace collectionPrinterInternal {

    template <std::size_t N>
    const char *GetCommaOrEmpty()
    {
      static const auto comma = ", ";
      return comma;
    }

    template <>
    const char *GetCommaOrEmpty<0>()
    {
      static const auto empty = "";
      return empty;
    }

    // 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 std::string print(TUPLE *t)
      {
        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 Nm1 = N - 1;
        ret += tuplePrinter<TUPLE, Nm1>::print((TUPLE *)t);
        return ret;
      }
    };

    // 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 std::string print(TUPLE *t) {return "";}
    };

    template <class T>
    std::string tuplePairPrintValue(T *val)
    {
      std::string ret("{ ");
      ret += collectionPrinterInternal::tuplePrinter<T>::print(val);
      ret += " }";
      return ret;
    }
  }

  template <class... ARGS>
  std::string printValue(std::tuple<ARGS...> *val)
  {
    using T = std::tuple<ARGS...>;
    if (std::tuple_size<T>::value == 0)
      return valuePrinterInternal::kEmptyCollection;
    return collectionPrinterInternal::tuplePairPrintValue<T>(val);
  }

  template <class... ARGS>
  std::string printValue(std::pair<ARGS...> *val)
  {
    using T = std::pair<ARGS...>;
    return collectionPrinterInternal::tuplePairPrintValue<T>(val);
  }
}

#endif
<commit_msg>Windows: Remove string hack. One of the new exports seems to do the trick.<commit_after>//--------------------------------------------------------------------*- C++ -*-
// CLING - the C++ LLVM-based InterpreterG :)
// author:  <NAME> <<EMAIL>>
// author:  <NAME> <<EMAIL>>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------
#ifndef CLING_RUNTIME_PRINT_VALUE_H
#define CLING_RUNTIME_PRINT_VALUE_H

#if !defined(__CLING__)
#error "This file must not be included by compiled programs."
#endif

#include <string>
#include <tuple>
#include <type_traits>

namespace cling {

  class Value;

  // General fallback - prints the address
  std::string printValue(const void *ptr);

  // Fallback for e.g. vector<bool>'s bit iterator:
  template <class T,
    class = typename std::enable_if<!std::is_pointer<T>::value>::type>
  std::string printValue(const T& val) { return "{not representable}"; }

  // void pointer
  std::string printValue(const void **ptr);

  // Bool
  std::string printValue(const bool *val);

  // Chars
  std::string printValue(const char *val);

  std::string printValue(const signed char *val);

  std::string printValue(const unsigned char *val);

  std::string printValue(const char16_t *val);

  std::string printValue(const char32_t *val);

  std::string printValue(const wchar_t *val);

  // Ints
  std::string printValue(const short *val);

  std::string printValue(const unsigned short *val);

  std::string printValue(const int *val);

  std::string printValue(const unsigned int *val);

  std::string printValue(const long *val);

  std::string printValue(const unsigned long *val);

  std::string printValue(const long long *val);

  std::string printValue(const unsigned long long *val);

  // Reals
  std::string printValue(const float *val);

  std::string printValue(const double *val);

  std::string printValue(const long double *val);

  // Char pointers
  std::string printValue(const char *const *val);

  std::string printValue(const char **val);

  // std::string
  std::string printValue(const std::string *val);

  std::string printValue(const std::wstring *val);

  std::string printValue(const std::u16string *val);

  std::string printValue(const std::u32string *val);

  // constant unicode strings, i.e. u"String"
  template <typename T>
  std::string toUTF8(const T* const Src, size_t N, const char Prefix = 0);

  template <size_t N>
  std::string printValue(char16_t const (*val)[N]) {
    return toUTF8(reinterpret_cast<const char16_t * const>(val), N, 'u');
  }

  template <size_t N>
  std::string printValue(char32_t const (*val)[N]) {
    return toUTF8(reinterpret_cast<const char32_t * const>(val), N, 'U');
  }

  template <size_t N>
  std::string printValue(wchar_t const (*val)[N]) {
#ifdef _WIN32
    return toUTF8(reinterpret_cast<const char16_t * const>(val), N, 'L');
#else
    return toUTF8(reinterpret_cast<const char32_t * const>(val), N, 'L');
#endif
  }

  template <size_t N>
  std::string printValue(char const (*val)[N]) {
    return toUTF8(reinterpret_cast<const char * const>(val), N, 1);
  }

  // cling::Value
  std::string printValue(const Value *value);

  namespace valuePrinterInternal {
    extern const char* const kEmptyCollection;
  }

  // Collections internal
  namespace collectionPrinterInternal {
    // Maps
    template<typename Pair>
    std::string printPair(const Pair& P) {
      return printValue(&P->first) + " => " + printValue(&P->second);
    }
    
    template<typename CollectionType>
    auto printValue_impl(const CollectionType *obj, short)
    -> decltype(
    ++(obj->begin()), obj->end(),
        obj->begin()->first, obj->begin()->second,
        std::string())
    {
      auto iter = obj->begin();
      auto iterEnd = obj->end();
      if (iter == iterEnd)
        return valuePrinterInternal::kEmptyCollection;

      std::string str("{ ");
      str += printPair(iter);
      while (++iter != iterEnd) {
        str += ", ";
        str += printPair(iter);
      }
      return str + " }";
    }

    // Vector, set, deque etc.
    template<typename CollectionType>
    auto printValue_impl(const CollectionType *obj, int)
    -> decltype(
    ++(obj->begin()), obj->end(),
        *(obj->begin()),  &(*(obj->begin())),
        std::string())
    {
      auto iter = obj->begin();
      auto iterEnd = obj->end();
      if (iter == iterEnd)
        return valuePrinterInternal::kEmptyCollection;

      std::string str("{ ");
      str += printValue(&(*iter));
      while (++iter != iterEnd) {
        str += ", ";
        str += printValue(&(*iter));
      }
      return str + " }";
    }

    // As above, but without ability to take address of elements.
    template<typename CollectionType>
    auto printValue_impl(const CollectionType *obj, long)
    -> decltype(
    ++(obj->begin()), obj->end(),
        *(obj->begin()),
        std::string())
     {
      auto iter = obj->begin();
      auto iterEnd = obj->end();
      if (iter == iterEnd)
        return valuePrinterInternal::kEmptyCollection;

      std::string str("{ ");
      const auto value0 = (*iter);
      str += printValue(&value0);
      while (++iter != iterEnd) {
        const auto valueN = (*iter);
        str += ", ";
        str += printValue(&valueN);
      }
      return str + " }";
     }
  }

  // Collections
  template<typename CollectionType>
  auto printValue(const CollectionType *obj)
  -> decltype(collectionPrinterInternal::printValue_impl(obj, 0), std::string())
  {
    // short -> int -> long = priority order
    return collectionPrinterInternal::printValue_impl(obj, (short)0);
  }

  // Arrays
  template<typename T, size_t N>
  std::string printValue(const T (*obj)[N]) {
    if (N == 0)
      return valuePrinterInternal::kEmptyCollection;

    std::string str = "{ ";
    str += printValue(*obj + 0);
    for (size_t i = 1; i < N; ++i) {
      str += ", ";
      str += printValue(*obj + i);
    }
    return str + " }";
  }

  // Tuples
  template <class... ARGS>
  std::string printValue(std::tuple<ARGS...> *);

  namespace collectionPrinterInternal {

    template <std::size_t N>
    const char *GetCommaOrEmpty()
    {
      static const auto comma = ", ";
      return comma;
    }

    template <>
    const char *GetCommaOrEmpty<0>()
    {
      static const auto empty = "";
      return empty;
    }

    // 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 std::string print(TUPLE *t)
      {
        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 Nm1 = N - 1;
        ret += tuplePrinter<TUPLE, Nm1>::print((TUPLE *)t);
        return ret;
      }
    };

    // 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 std::string print(TUPLE *t) {return "";}
    };

    template <class T>
    std::string tuplePairPrintValue(T *val)
    {
      std::string ret("{ ");
      ret += collectionPrinterInternal::tuplePrinter<T>::print(val);
      ret += " }";
      return ret;
    }
  }

  template <class... ARGS>
  std::string printValue(std::tuple<ARGS...> *val)
  {
    using T = std::tuple<ARGS...>;
    if (std::tuple_size<T>::value == 0)
      return valuePrinterInternal::kEmptyCollection;
    return collectionPrinterInternal::tuplePairPrintValue<T>(val);
  }

  template <class... ARGS>
  std::string printValue(std::pair<ARGS...> *val)
  {
    using T = std::pair<ARGS...>;
    return collectionPrinterInternal::tuplePairPrintValue<T>(val);
  }
}

#endif

{'fraction_non_alphanumeric': 0.15918865512030686, 'fraction_numerical': 0.0054632105079623385, 'mean_word_length': 2.877196935556557, 'pattern_counts': {'":': 0, '<': 113, '<?xml version=': 0, '>': 167, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6271371', 'n_tokens_mistral': 5409, 'n_tokens_neox': 5226, 'n_words': 1443}