Yusong Gaoinitial released0d49a92 years agoHistory
3346 lines · 102.1 KB · C++
RawDownload
//// Copyright (c) 2019-2021 Kris Jusiak (kris at jusiak dot net)//// Distributed under the Boost Software License, Version 1.0.// (See accompanying file LICENSE_1_0.txt or copy at// http://www.boost.org/LICENSE_1_0.txt)//#if defined(__cpp_modules) && !defined(BOOST_UT_DISABLE_MODULE)export module boost.ut;export import std;#define BOOST_UT_EXPORT export#else#pragma once#define BOOST_UT_EXPORT#endif #if __has_include(<iso646.h>)#include <iso646.h>  // and, or, not, ...#endif #include <version>#if defined(_MSC_VER)  #pragma push_macro("min")  #pragma push_macro("max")  #undef min  #undef max#endif// Before libc++ 17 had experimental support for format and it required a// special build flag. Currently libc++ has not implemented all C++20 chrono// improvements. Therefore doesn't define __cpp_lib_format, instead query the// library version to detect the support status.//// MSVC STL and libstdc++ provide __cpp_lib_format.#if defined(__cpp_lib_format) or \    (defined(_LIBCPP_VERSION) and _LIBCPP_VERSION >= 170000)#define BOOST_UT_HAS_FORMAT#endif #if not defined(__cpp_rvalue_references)#error "[Boost::ext].UT requires support for rvalue references";#elif not defined(__cpp_decltype)#error "[Boost::ext].UT requires support for decltype";#elif not defined(__cpp_return_type_deduction)#error "[Boost::ext].UT requires support for return type deduction";#elif not defined(__cpp_deduction_guides)#error "[Boost::ext].UT requires support for return deduction guides";#elif not defined(__cpp_generic_lambdas)#error "[Boost::ext].UT requires support for generic lambdas";#elif not defined(__cpp_constexpr)#error "[Boost::ext].UT requires support for constexpr";#elif not defined(__cpp_alias_templates)#error "[Boost::ext].UT requires support for alias templates";#elif not defined(__cpp_variadic_templates)#error "[Boost::ext].UT requires support for variadic templates";#elif not defined(__cpp_fold_expressions)#error "[Boost::ext].UT requires support for return fold expressions";#elif not defined(__cpp_static_assert)#error "[Boost::ext].UT requires support for static assert";#else#define BOOST_UT_VERSION 2'0'1 #if defined(__has_builtin) and defined(__GNUC__) and (__GNUC__ < 10) and \    not defined(__clang__)#undef __has_builtin#endif #if not defined(__has_builtin)#if defined(__GNUC__) and (__GNUC__ >= 9)#define __has___builtin_FILE 1#define __has___builtin_LINE 1#endif#define __has_builtin(...) __has_##__VA_ARGS__#endif #include <algorithm>#include <array>#include <chrono>#include <concepts>#include <cstdint>#include <functional>#include <iostream>#include <memory>#include <optional>#include <sstream>#include <stack>#include <string_view>#include <type_traits>#include <unordered_map>#include <utility>#include <variant>#include <vector>#include <fstream>#if __has_include(<unistd.h>) and __has_include(<sys/wait.h>)#include <sys/wait.h>#include <unistd.h>#endif#if defined(__cpp_exceptions)#include <exception>#endif #if __has_include(<format>)#include <format>#endif#if __has_include(<source_location>)#include <source_location>#endif struct unique_name_for_auto_detect_prefix_and_suffix_lenght_0123456789_struct_ {}; BOOST_UT_EXPORTnamespace boost::inline ext::ut::inline v2_0_1 {namespace utility {template <class>class function;template <class R, class... TArgs>class function<R(TArgs...)> { public:  constexpr function() = default;  template <class T>  constexpr /*explicit(false)*/ function(T data)      : invoke_{invoke_impl<T>},        destroy_{destroy_impl<T>},        data_{new T{static_cast<T&&>(data)}} {}  constexpr function(function&& other) noexcept      : invoke_{static_cast<decltype(other.invoke_)&&>(other.invoke_)},        destroy_{static_cast<decltype(other.destroy_)&&>(other.destroy_)},        data_{static_cast<decltype(other.data_)&&>(other.data_)} {    other.data_ = {};  }  constexpr function(const function&) = delete;  ~function() { destroy_(data_); }   constexpr function& operator=(const function&) = delete;  constexpr function& operator=(function&&) = delete;  [[nodiscard]] constexpr auto operator()(TArgs... args) -> R {    return invoke_(data_, args...);  }  [[nodiscard]] constexpr auto operator()(TArgs... args) const -> R {    return invoke_(data_, args...);  }  private:  template <class T>  [[nodiscard]] static auto invoke_impl(void* data, TArgs... args) -> R {    return (*static_cast<T*>(data))(args...);  }   template <class T>  static auto destroy_impl(void* data) -> void {    delete static_cast<T*>(data);  }   R (*invoke_)(void*, TArgs...){};  void (*destroy_)(void*){};  void* data_{};}; [[nodiscard]] inline auto is_match(std::string_view input,                                   std::string_view pattern) -> bool {  if (std::empty(pattern)) {    return std::empty(input);  }   if (std::empty(input)) {    return pattern[0] == '*' ? is_match(input, pattern.substr(1)) : false;  }   if (pattern[0] != '?' and pattern[0] != '*' and pattern[0] != input[0]) {    return false;  }   if (pattern[0] == '*') {    for (decltype(std::size(input)) i = 0u; i <= std::size(input); ++i) {      if (is_match(input.substr(i), pattern.substr(1))) {        return true;      }    }    return false;  }   return is_match(input.substr(1), pattern.substr(1));} template <class TPattern, class TStr>[[nodiscard]] constexpr auto match(const TPattern& pattern, const TStr& str)    -> std::vector<TStr> {  std::vector<TStr> groups{};  auto pi = 0u;  auto si = 0u;   const auto matcher = [&](char b, char e, char c = 0) {    const auto match = si;    while (str[si] and str[si] != b and str[si] != c) {      ++si;    }    groups.emplace_back(str.substr(match, si - match));    while (pattern[pi] and pattern[pi] != e) {      ++pi;    }    pi++;  };   while (pi < std::size(pattern) && si < std::size(str)) {    if (pattern[pi] == '\'' and str[si] == '\'' and pattern[pi + 1] == '{') {      ++si;      matcher('\'', '}');    } else if (pattern[pi] == '{') {      matcher(' ', '}', ',');    } else if (pattern[pi] != str[si]) {      return {};    }    ++pi;    ++si;  }   if (si < str.size() or pi < std::size(pattern)) {    return {};  }   return groups;} template <class T = std::string_view, class TDelim>[[nodiscard]] inline auto split(T input, TDelim delim) -> std::vector<T> {  std::vector<T> output{};  std::size_t first{};  while (first < std::size(input)) {    const auto second = input.find_first_of(delim, first);    if (first != second) {      output.emplace_back(input.substr(first, second - first));    }    if (second == T::npos) {      break;    }    first = second + 1;  }  return output;}constexpr auto regex_match(const char *str, const char *pattern) -> bool {  if (*pattern == '\0' && *str == '\0') return true;  if (*pattern == '\0' && *str != '\0') return false;  if (*str == '\0' && *pattern != '\0') return false;  if (*pattern == '.') {    return regex_match(str+1, pattern+1);  }  if (*pattern == *str) {    return regex_match(str+1, pattern+1);  }  return false;}}  // namespace utility namespace reflection {#if defined(__cpp_lib_source_location)using source_location = std::source_location;#elseclass source_location { public:  [[nodiscard]] static constexpr auto current(#if (__has_builtin(__builtin_FILE) and __has_builtin(__builtin_LINE))      const char* file = __builtin_FILE(), int line = __builtin_LINE()#else      const char* file = "unknown", int line = {}#endif          ) noexcept {    source_location sl{};    sl.file_ = file;    sl.line_ = line;    return sl;  }  [[nodiscard]] constexpr auto file_name() const noexcept { return file_; }  [[nodiscard]] constexpr auto line() const noexcept { return line_; }  private:  const char* file_{"unknown"};  int line_{};};#endifnamespace detail {template <typename TargetType>[[nodiscard]] constexpr auto get_template_function_name_use_type()    -> const std::string_view {// for over compiler need over macros#if defined(_MSC_VER) && !defined(__clang__)  return {&__FUNCSIG__[0], sizeof(__FUNCSIG__)};#else  return {&__PRETTY_FUNCTION__[0], sizeof(__PRETTY_FUNCTION__)};#endif} // decay allows you to highlight a cleaner nametemplate <typename TargetType>[[nodiscard]] constexpr auto get_template_function_name_use_decay_type()    -> const std::string_view {  return get_template_function_name_use_type<std::decay_t<TargetType>>();} inline constexpr const std::string_view raw_type_name =    get_template_function_name_use_decay_type<        unique_name_for_auto_detect_prefix_and_suffix_lenght_0123456789_struct_>(); inline constexpr const std::size_t raw_length = raw_type_name.length();inline constexpr const std::string_view need_name =#if defined(_MSC_VER) and not defined(__clang__)    "struct "    "unique_name_for_auto_detect_prefix_and_suffix_lenght_0123456789_struct_";#else    "unique_name_for_auto_detect_prefix_and_suffix_lenght_0123456789_struct_";#endifinline constexpr const std::size_t need_length = need_name.length();static_assert(need_length <= raw_length,              "Auto find prefix and suffix lenght broken error 1");inline constexpr const std::size_t prefix_length =    raw_type_name.find(need_name);static_assert(prefix_length != std::string_view::npos,              "Auto find prefix and suffix lenght broken error 2");static_assert(prefix_length <= raw_length,              "Auto find prefix and suffix lenght broken error 3");inline constexpr const std::size_t tail_lenght = raw_length - prefix_length;static_assert(need_length <= tail_lenght,              "Auto find prefix and suffix lenght broken error 4");inline constexpr const std::size_t suffix_length = tail_lenght - need_length; }  // namespace detail template <typename TargetType>[[nodiscard]] constexpr auto type_name() -> const std::string_view {  const std::string_view raw_type_name =      detail::get_template_function_name_use_type<TargetType>();  const std::size_t end = raw_type_name.length() - detail::suffix_length;  const std::size_t len = end - detail::prefix_length;  std::string_view result = raw_type_name.substr(detail::prefix_length, len);  return result;} // decay allows you to highlight a cleaner nametemplate <typename TargetType>[[nodiscard]] constexpr auto decay_type_name() -> const std::string_view {  const std::string_view raw_type_name =      detail::get_template_function_name_use_decay_type<TargetType>();  const std::size_t end = raw_type_name.length() - detail::suffix_length;  const std::size_t len = end - detail::prefix_length;  std::string_view result = raw_type_name.substr(detail::prefix_length, len);  return result;}}  // namespace reflection namespace math {template <class T>[[nodiscard]] constexpr auto abs(const T t) -> T {  return t < T{} ? -t : t;} template <class T, class U>[[nodiscard]] constexpr auto abs_diff(const T t, const U u)    -> decltype(t < u ? u - t : t - u) {  return t < u ? u - t : t - u;} template <class T>[[nodiscard]] constexpr auto min_value(const T& lhs, const T& rhs) -> const T& {  return (rhs < lhs) ? rhs : lhs;} template <class T, class TExp>[[nodiscard]] constexpr auto pow(const T base, const TExp exp) -> T {  return exp ? T(base * pow(base, exp - TExp(1))) : T(1);} template <class T, char... Cs>[[nodiscard]] constexpr auto num() -> T {  static_assert(      ((Cs == '.' or Cs == '\'' or (Cs >= '0' and Cs <= '9')) and ...));  T result{};  for (const char c : std::array{Cs...}) {    if (c == '.') {      break;    }    if (c >= '0' and c <= '9') {      result = result * T(10) + T(c - '0');    }  }  return result;} template <class T, char... Cs>[[nodiscard]] constexpr auto den() -> T {  constexpr const std::array cs{Cs...};  T result{};  auto i = 0u;  while (cs[i++] != '.') {  }   for (auto j = i; j < sizeof...(Cs); ++j) {    result += pow(T(10), sizeof...(Cs) - j) * T(cs[j] - '0');  }  return result;} template <class T, char... Cs>[[nodiscard]] constexpr auto den_size() -> T {  constexpr const std::array cs{Cs...};  T i{};  while (cs[i++] != '.') {  }   return T(sizeof...(Cs)) - i + T(1);} template <class T, class TValue>[[nodiscard]] constexpr auto den_size(TValue value) -> T {  constexpr auto precision = TValue(1e-7);  T result{};  TValue tmp{};  do {    value *= 10;    tmp = value - T(value);    ++result;  } while (tmp > precision);   return result;} }  // namespace math namespace type_traits {template <class...>struct list {}; template <class T, class...>struct identity {  using type = T;}; template <class T>struct function_traits : function_traits<decltype(&T::operator())> {}; template <class R, class... TArgs>struct function_traits<R (*)(TArgs...)> {  using result_type = R;  using args = list<TArgs...>;}; template <class R, class... TArgs>struct function_traits<R(TArgs...)> {  using result_type = R;  using args = list<TArgs...>;}; template <class R, class T, class... TArgs>struct function_traits<R (T::*)(TArgs...)> {  using result_type = R;  using args = list<TArgs...>;}; template <class R, class T, class... TArgs>struct function_traits<R (T::*)(TArgs...) const> {  using result_type = R;  using args = list<TArgs...>;}; template <class T>T&& declval();template <class... Ts, class TExpr>constexpr auto is_valid(TExpr expr)    -> decltype(expr(declval<Ts...>()), bool()) {  return true;}template <class...>constexpr auto is_valid(...) -> bool {  return false;} template <class T>inline constexpr auto is_range_v =    is_valid<T>([](auto t) -> decltype(t.begin(), t.end(), void()) {}); template <class T>inline constexpr auto has_user_print = is_valid<T>(    [](auto t) -> decltype(void(declval<std::ostringstream&>() << t)) {}); template <class T, class = void>struct has_static_member_object_value : std::false_type {}; template <class T>struct has_static_member_object_value<T,                                      std::void_t<decltype(declval<T>().value)>>    : std::bool_constant<!std::is_member_pointer_v<decltype(&T::value)> &&                         !std::is_function_v<decltype(T::value)>> {}; template <class T>inline constexpr bool has_static_member_object_value_v =    has_static_member_object_value<T>::value; template <class T, class = void>struct has_static_member_object_epsilon : std::false_type {}; template <class T>struct has_static_member_object_epsilon<

Lines 1–500 of 3346.