Program Listing for File wstring.hpp

Return to documentation for file (SeQuant/core/wstring.hpp)

//
// Created by Eduard Valeyev on 2019-02-11.
//

#ifndef SEQUANT_WSTRING_HPP
#define SEQUANT_WSTRING_HPP

#include <SeQuant/core/utility/macros.hpp>
#include <SeQuant/core/utility/string.hpp>

#include <cmath>
#include <concepts>
#include <string>
#include <string_view>
#include <type_traits>

#include <boost/locale/encoding_utf.hpp>

namespace sequant {

std::wstring to_wstring(meta::integral auto t) { return std::to_wstring(t); }

std::wstring to_wstring(std::floating_point auto t) {
  if (std::floor(t) == t)
    return std::to_wstring(static_cast<long long>(t));
  else
    return std::to_wstring(t);
}

template <basic_string_convertible S>
std::string to_string(S&& str_utf8) {
  auto str_utf8_view = to_basic_string_view(std::forward<S>(str_utf8));
  using boost::locale::conv::utf_to_utf;
  return utf_to_utf<char>(str_utf8_view.data(),
                          str_utf8_view.data() + str_utf8_view.size());
}

inline std::string to_string(std::string&& str_utf8) {
  return std::move(str_utf8);
}

template <basic_string_convertible S>
std::wstring to_wstring(S&& str_utf8) {
  auto str_utf8_view = to_basic_string_view(std::forward<S>(str_utf8));
  using boost::locale::conv::utf_to_utf;
  return utf_to_utf<wchar_t>(str_utf8_view.data(),
                             str_utf8_view.data() + str_utf8_view.size());
}

inline std::wstring to_wstring(std::wstring&& str_utf8) {
  return std::move(str_utf8);
}

namespace detail {

template <typename Char, std::size_t NChar, std::size_t NWChar,
          std::size_t NChar8, std::size_t NChar16, std::size_t NChar32>
constexpr decltype(auto) select_string_literal(
    const char (&str)[NChar], const wchar_t (&wstr)[NWChar],
    const char8_t (&u8str)[NChar8], const char16_t (&u16str)[NChar16],
    const char32_t (&u32str)[NChar32]) {
  if constexpr (std::is_same_v<Char, char>)
    return str;
  else if constexpr (std::is_same_v<Char, wchar_t>)
    return wstr;
  else if constexpr (std::is_same_v<Char, char8_t>)
    return u8str;
  else if constexpr (std::is_same_v<Char, char16_t>)
    return u16str;
  else if constexpr (std::is_same_v<Char, char32_t>)
    return u32str;

  SEQUANT_ABORT("Unhandled character type");
}
}  // namespace detail

#define SQ_STRLIT(code_unit, char_string_literal)                  \
  detail::select_string_literal<code_unit>(                        \
      char_string_literal, SEQUANT_CONCAT(L, char_string_literal), \
      SEQUANT_CONCAT(u8, char_string_literal),                     \
      SEQUANT_CONCAT(u, char_string_literal),                      \
      SEQUANT_CONCAT(U, char_string_literal))

}  // namespace sequant

#endif  // SEQUANT_WSTRING_HPP