git repos / blockattack-game

blame: source/misc/embedded_libs/fmt-8.1.1/test/ranges-test.cc

normal view · raw

f8deb5b9 Poul Sander 2022-01-15 13:55 1
// Formatting library for C++ - the core API
f8deb5b9 Poul Sander 2022-01-15 13:55 2
//
f8deb5b9 Poul Sander 2022-01-15 13:55 3
// Copyright (c) 2012 - present, Victor Zverovich
f8deb5b9 Poul Sander 2022-01-15 13:55 4
// All rights reserved.
f8deb5b9 Poul Sander 2022-01-15 13:55 5
//
f8deb5b9 Poul Sander 2022-01-15 13:55 6
// For the license information refer to format.h.
f8deb5b9 Poul Sander 2022-01-15 13:55 7
//
f8deb5b9 Poul Sander 2022-01-15 13:55 8
// Copyright (c) 2018 - present, Remotion (Igor Schulz)
f8deb5b9 Poul Sander 2022-01-15 13:55 9
// All Rights Reserved
f8deb5b9 Poul Sander 2022-01-15 13:55 10
// {fmt} support for ranges, containers and types tuple interface.
f8deb5b9 Poul Sander 2022-01-15 13:55 11
f8deb5b9 Poul Sander 2022-01-15 13:55 12
#include "fmt/ranges.h"
f8deb5b9 Poul Sander 2022-01-15 13:55 13
f8deb5b9 Poul Sander 2022-01-15 13:55 14
#include <map>
f8deb5b9 Poul Sander 2022-01-15 13:55 15
#include <string>
f8deb5b9 Poul Sander 2022-01-15 13:55 16
#include <vector>
f8deb5b9 Poul Sander 2022-01-15 13:55 17
f8deb5b9 Poul Sander 2022-01-15 13:55 18
#include "gtest/gtest.h"
f8deb5b9 Poul Sander 2022-01-15 13:55 19
f8deb5b9 Poul Sander 2022-01-15 13:55 20
#if !FMT_GCC_VERSION || FMT_GCC_VERSION >= 601
f8deb5b9 Poul Sander 2022-01-15 13:55 21
#  define FMT_RANGES_TEST_ENABLE_C_STYLE_ARRAY
f8deb5b9 Poul Sander 2022-01-15 13:55 22
#endif
f8deb5b9 Poul Sander 2022-01-15 13:55 23
f8deb5b9 Poul Sander 2022-01-15 13:55 24
#if !FMT_MSC_VER || FMT_MSC_VER > 1910
f8deb5b9 Poul Sander 2022-01-15 13:55 25
#  define FMT_RANGES_TEST_ENABLE_JOIN
f8deb5b9 Poul Sander 2022-01-15 13:55 26
#  define FMT_RANGES_TEST_ENABLE_FORMAT_STRUCT
f8deb5b9 Poul Sander 2022-01-15 13:55 27
#endif
f8deb5b9 Poul Sander 2022-01-15 13:55 28
f8deb5b9 Poul Sander 2022-01-15 13:55 29
#ifdef FMT_RANGES_TEST_ENABLE_C_STYLE_ARRAY
f8deb5b9 Poul Sander 2022-01-15 13:55 30
TEST(ranges_test, format_array) {
f8deb5b9 Poul Sander 2022-01-15 13:55 31
  int arr[] = {1, 2, 3, 5, 7, 11};
f8deb5b9 Poul Sander 2022-01-15 13:55 32
  EXPECT_EQ(fmt::format("{}", arr), "[1, 2, 3, 5, 7, 11]");
f8deb5b9 Poul Sander 2022-01-15 13:55 33
}
f8deb5b9 Poul Sander 2022-01-15 13:55 34
f8deb5b9 Poul Sander 2022-01-15 13:55 35
TEST(ranges_test, format_2d_array) {
f8deb5b9 Poul Sander 2022-01-15 13:55 36
  int arr[][2] = {{1, 2}, {3, 5}, {7, 11}};
f8deb5b9 Poul Sander 2022-01-15 13:55 37
  EXPECT_EQ(fmt::format("{}", arr), "[[1, 2], [3, 5], [7, 11]]");
f8deb5b9 Poul Sander 2022-01-15 13:55 38
}
f8deb5b9 Poul Sander 2022-01-15 13:55 39
f8deb5b9 Poul Sander 2022-01-15 13:55 40
TEST(ranges_test, format_array_of_literals) {
f8deb5b9 Poul Sander 2022-01-15 13:55 41
  const char* arr[] = {"1234", "abcd"};
f8deb5b9 Poul Sander 2022-01-15 13:55 42
  EXPECT_EQ(fmt::format("{}", arr), "[\"1234\", \"abcd\"]");
f8deb5b9 Poul Sander 2022-01-15 13:55 43
}
f8deb5b9 Poul Sander 2022-01-15 13:55 44
#endif  // FMT_RANGES_TEST_ENABLE_C_STYLE_ARRAY
f8deb5b9 Poul Sander 2022-01-15 13:55 45
f8deb5b9 Poul Sander 2022-01-15 13:55 46
TEST(ranges_test, format_vector) {
f8deb5b9 Poul Sander 2022-01-15 13:55 47
  auto v = std::vector<int>{1, 2, 3, 5, 7, 11};
f8deb5b9 Poul Sander 2022-01-15 13:55 48
  EXPECT_EQ(fmt::format("{}", v), "[1, 2, 3, 5, 7, 11]");
f8deb5b9 Poul Sander 2022-01-15 13:55 49
}
f8deb5b9 Poul Sander 2022-01-15 13:55 50
f8deb5b9 Poul Sander 2022-01-15 13:55 51
TEST(ranges_test, format_vector2) {
f8deb5b9 Poul Sander 2022-01-15 13:55 52
  auto v = std::vector<std::vector<int>>{{1, 2}, {3, 5}, {7, 11}};
f8deb5b9 Poul Sander 2022-01-15 13:55 53
  EXPECT_EQ(fmt::format("{}", v), "[[1, 2], [3, 5], [7, 11]]");
f8deb5b9 Poul Sander 2022-01-15 13:55 54
}
f8deb5b9 Poul Sander 2022-01-15 13:55 55
f8deb5b9 Poul Sander 2022-01-15 13:55 56
TEST(ranges_test, format_map) {
f8deb5b9 Poul Sander 2022-01-15 13:55 57
  auto m = std::map<std::string, int>{{"one", 1}, {"two", 2}};
f8deb5b9 Poul Sander 2022-01-15 13:55 58
  EXPECT_EQ(fmt::format("{}", m), "{\"one\": 1, \"two\": 2}");
f8deb5b9 Poul Sander 2022-01-15 13:55 59
}
f8deb5b9 Poul Sander 2022-01-15 13:55 60
f8deb5b9 Poul Sander 2022-01-15 13:55 61
TEST(ranges_test, format_set) {
f8deb5b9 Poul Sander 2022-01-15 13:55 62
  EXPECT_EQ(fmt::format("{}", std::set<std::string>{"one", "two"}),
f8deb5b9 Poul Sander 2022-01-15 13:55 63
            "{\"one\", \"two\"}");
f8deb5b9 Poul Sander 2022-01-15 13:55 64
}
f8deb5b9 Poul Sander 2022-01-15 13:55 65
f8deb5b9 Poul Sander 2022-01-15 13:55 66
TEST(ranges_test, format_pair) {
f8deb5b9 Poul Sander 2022-01-15 13:55 67
  auto p = std::pair<int, float>(42, 1.5f);
f8deb5b9 Poul Sander 2022-01-15 13:55 68
  EXPECT_EQ(fmt::format("{}", p), "(42, 1.5)");
f8deb5b9 Poul Sander 2022-01-15 13:55 69
}
f8deb5b9 Poul Sander 2022-01-15 13:55 70
f8deb5b9 Poul Sander 2022-01-15 13:55 71
TEST(ranges_test, format_tuple) {
f8deb5b9 Poul Sander 2022-01-15 13:55 72
  auto t =
f8deb5b9 Poul Sander 2022-01-15 13:55 73
      std::tuple<int, float, std::string, char>(42, 1.5f, "this is tuple", 'i');
f8deb5b9 Poul Sander 2022-01-15 13:55 74
  EXPECT_EQ(fmt::format("{}", t), "(42, 1.5, \"this is tuple\", 'i')");
f8deb5b9 Poul Sander 2022-01-15 13:55 75
  EXPECT_EQ(fmt::format("{}", std::tuple<>()), "()");
f8deb5b9 Poul Sander 2022-01-15 13:55 76
}
f8deb5b9 Poul Sander 2022-01-15 13:55 77
f8deb5b9 Poul Sander 2022-01-15 13:55 78
#ifdef FMT_RANGES_TEST_ENABLE_FORMAT_STRUCT
f8deb5b9 Poul Sander 2022-01-15 13:55 79
struct tuple_like {
f8deb5b9 Poul Sander 2022-01-15 13:55 80
  int i;
f8deb5b9 Poul Sander 2022-01-15 13:55 81
  std::string str;
f8deb5b9 Poul Sander 2022-01-15 13:55 82
f8deb5b9 Poul Sander 2022-01-15 13:55 83
  template <size_t N> fmt::enable_if_t<N == 0, int> get() const noexcept {
f8deb5b9 Poul Sander 2022-01-15 13:55 84
    return i;
f8deb5b9 Poul Sander 2022-01-15 13:55 85
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 86
  template <size_t N>
f8deb5b9 Poul Sander 2022-01-15 13:55 87
  fmt::enable_if_t<N == 1, fmt::string_view> get() const noexcept {
f8deb5b9 Poul Sander 2022-01-15 13:55 88
    return str;
f8deb5b9 Poul Sander 2022-01-15 13:55 89
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 90
};
f8deb5b9 Poul Sander 2022-01-15 13:55 91
f8deb5b9 Poul Sander 2022-01-15 13:55 92
template <size_t N>
f8deb5b9 Poul Sander 2022-01-15 13:55 93
auto get(const tuple_like& t) noexcept -> decltype(t.get<N>()) {
f8deb5b9 Poul Sander 2022-01-15 13:55 94
  return t.get<N>();
f8deb5b9 Poul Sander 2022-01-15 13:55 95
}
f8deb5b9 Poul Sander 2022-01-15 13:55 96
f8deb5b9 Poul Sander 2022-01-15 13:55 97
namespace std {
f8deb5b9 Poul Sander 2022-01-15 13:55 98
template <>
f8deb5b9 Poul Sander 2022-01-15 13:55 99
struct tuple_size<tuple_like> : std::integral_constant<size_t, 2> {};
f8deb5b9 Poul Sander 2022-01-15 13:55 100
f8deb5b9 Poul Sander 2022-01-15 13:55 101
template <size_t N> struct tuple_element<N, tuple_like> {
f8deb5b9 Poul Sander 2022-01-15 13:55 102
  using type = decltype(std::declval<tuple_like>().get<N>());
f8deb5b9 Poul Sander 2022-01-15 13:55 103
};
f8deb5b9 Poul Sander 2022-01-15 13:55 104
}  // namespace std
f8deb5b9 Poul Sander 2022-01-15 13:55 105
f8deb5b9 Poul Sander 2022-01-15 13:55 106
TEST(ranges_test, format_struct) {
f8deb5b9 Poul Sander 2022-01-15 13:55 107
  auto t = tuple_like{42, "foo"};
f8deb5b9 Poul Sander 2022-01-15 13:55 108
  EXPECT_EQ(fmt::format("{}", t), "(42, \"foo\")");
f8deb5b9 Poul Sander 2022-01-15 13:55 109
}
f8deb5b9 Poul Sander 2022-01-15 13:55 110
#endif  // FMT_RANGES_TEST_ENABLE_FORMAT_STRUCT
f8deb5b9 Poul Sander 2022-01-15 13:55 111
f8deb5b9 Poul Sander 2022-01-15 13:55 112
TEST(ranges_test, format_to) {
f8deb5b9 Poul Sander 2022-01-15 13:55 113
  char buf[10];
f8deb5b9 Poul Sander 2022-01-15 13:55 114
  auto end = fmt::format_to(buf, "{}", std::vector<int>{1, 2, 3});
f8deb5b9 Poul Sander 2022-01-15 13:55 115
  *end = '\0';
f8deb5b9 Poul Sander 2022-01-15 13:55 116
  EXPECT_STREQ(buf, "[1, 2, 3]");
f8deb5b9 Poul Sander 2022-01-15 13:55 117
}
f8deb5b9 Poul Sander 2022-01-15 13:55 118
f8deb5b9 Poul Sander 2022-01-15 13:55 119
struct path_like {
f8deb5b9 Poul Sander 2022-01-15 13:55 120
  const path_like* begin() const;
f8deb5b9 Poul Sander 2022-01-15 13:55 121
  const path_like* end() const;
f8deb5b9 Poul Sander 2022-01-15 13:55 122
f8deb5b9 Poul Sander 2022-01-15 13:55 123
  operator std::string() const;
f8deb5b9 Poul Sander 2022-01-15 13:55 124
};
f8deb5b9 Poul Sander 2022-01-15 13:55 125
f8deb5b9 Poul Sander 2022-01-15 13:55 126
TEST(ranges_test, path_like) {
f8deb5b9 Poul Sander 2022-01-15 13:55 127
  EXPECT_FALSE((fmt::is_range<path_like, char>::value));
f8deb5b9 Poul Sander 2022-01-15 13:55 128
}
f8deb5b9 Poul Sander 2022-01-15 13:55 129
f8deb5b9 Poul Sander 2022-01-15 13:55 130
#ifdef FMT_USE_STRING_VIEW
f8deb5b9 Poul Sander 2022-01-15 13:55 131
struct string_like {
f8deb5b9 Poul Sander 2022-01-15 13:55 132
  const char* begin();
f8deb5b9 Poul Sander 2022-01-15 13:55 133
  const char* end();
f8deb5b9 Poul Sander 2022-01-15 13:55 134
  explicit operator fmt::string_view() const { return "foo"; }
f8deb5b9 Poul Sander 2022-01-15 13:55 135
  explicit operator std::string_view() const { return "foo"; }
f8deb5b9 Poul Sander 2022-01-15 13:55 136
};
f8deb5b9 Poul Sander 2022-01-15 13:55 137
f8deb5b9 Poul Sander 2022-01-15 13:55 138
TEST(ranges_test, format_string_like) {
f8deb5b9 Poul Sander 2022-01-15 13:55 139
  EXPECT_EQ(fmt::format("{}", string_like()), "foo");
f8deb5b9 Poul Sander 2022-01-15 13:55 140
}
f8deb5b9 Poul Sander 2022-01-15 13:55 141
#endif  // FMT_USE_STRING_VIEW
f8deb5b9 Poul Sander 2022-01-15 13:55 142
f8deb5b9 Poul Sander 2022-01-15 13:55 143
// A range that provides non-const only begin()/end() to test fmt::join handles
f8deb5b9 Poul Sander 2022-01-15 13:55 144
// that.
f8deb5b9 Poul Sander 2022-01-15 13:55 145
//
f8deb5b9 Poul Sander 2022-01-15 13:55 146
// Some ranges (e.g. those produced by range-v3's views::filter()) can cache
f8deb5b9 Poul Sander 2022-01-15 13:55 147
// information during iteration so they only provide non-const begin()/end().
f8deb5b9 Poul Sander 2022-01-15 13:55 148
template <typename T> class non_const_only_range {
f8deb5b9 Poul Sander 2022-01-15 13:55 149
 private:
f8deb5b9 Poul Sander 2022-01-15 13:55 150
  std::vector<T> vec;
f8deb5b9 Poul Sander 2022-01-15 13:55 151
f8deb5b9 Poul Sander 2022-01-15 13:55 152
 public:
f8deb5b9 Poul Sander 2022-01-15 13:55 153
  using const_iterator = typename ::std::vector<T>::const_iterator;
f8deb5b9 Poul Sander 2022-01-15 13:55 154
f8deb5b9 Poul Sander 2022-01-15 13:55 155
  template <typename... Args>
f8deb5b9 Poul Sander 2022-01-15 13:55 156
  explicit non_const_only_range(Args&&... args)
f8deb5b9 Poul Sander 2022-01-15 13:55 157
      : vec(std::forward<Args>(args)...) {}
f8deb5b9 Poul Sander 2022-01-15 13:55 158
f8deb5b9 Poul Sander 2022-01-15 13:55 159
  const_iterator begin() { return vec.begin(); }
f8deb5b9 Poul Sander 2022-01-15 13:55 160
  const_iterator end() { return vec.end(); }
f8deb5b9 Poul Sander 2022-01-15 13:55 161
};
f8deb5b9 Poul Sander 2022-01-15 13:55 162
f8deb5b9 Poul Sander 2022-01-15 13:55 163
template <typename T> class noncopyable_range {
f8deb5b9 Poul Sander 2022-01-15 13:55 164
 private:
f8deb5b9 Poul Sander 2022-01-15 13:55 165
  std::vector<T> vec;
f8deb5b9 Poul Sander 2022-01-15 13:55 166
f8deb5b9 Poul Sander 2022-01-15 13:55 167
 public:
f8deb5b9 Poul Sander 2022-01-15 13:55 168
  using const_iterator = typename ::std::vector<T>::const_iterator;
f8deb5b9 Poul Sander 2022-01-15 13:55 169
f8deb5b9 Poul Sander 2022-01-15 13:55 170
  template <typename... Args>
f8deb5b9 Poul Sander 2022-01-15 13:55 171
  explicit noncopyable_range(Args&&... args)
f8deb5b9 Poul Sander 2022-01-15 13:55 172
      : vec(std::forward<Args>(args)...) {}
f8deb5b9 Poul Sander 2022-01-15 13:55 173
f8deb5b9 Poul Sander 2022-01-15 13:55 174
  noncopyable_range(noncopyable_range const&) = delete;
f8deb5b9 Poul Sander 2022-01-15 13:55 175
  noncopyable_range(noncopyable_range&) = delete;
f8deb5b9 Poul Sander 2022-01-15 13:55 176
f8deb5b9 Poul Sander 2022-01-15 13:55 177
  const_iterator begin() const { return vec.begin(); }
f8deb5b9 Poul Sander 2022-01-15 13:55 178
  const_iterator end() const { return vec.end(); }
f8deb5b9 Poul Sander 2022-01-15 13:55 179
};
f8deb5b9 Poul Sander 2022-01-15 13:55 180
f8deb5b9 Poul Sander 2022-01-15 13:55 181
TEST(ranges_test, range) {
f8deb5b9 Poul Sander 2022-01-15 13:55 182
  noncopyable_range<int> w(3u, 0);
f8deb5b9 Poul Sander 2022-01-15 13:55 183
  EXPECT_EQ(fmt::format("{}", w), "[0, 0, 0]");
f8deb5b9 Poul Sander 2022-01-15 13:55 184
  EXPECT_EQ(fmt::format("{}", noncopyable_range<int>(3u, 0)), "[0, 0, 0]");
f8deb5b9 Poul Sander 2022-01-15 13:55 185
f8deb5b9 Poul Sander 2022-01-15 13:55 186
  non_const_only_range<int> x(3u, 0);
f8deb5b9 Poul Sander 2022-01-15 13:55 187
  EXPECT_EQ(fmt::format("{}", x), "[0, 0, 0]");
f8deb5b9 Poul Sander 2022-01-15 13:55 188
  EXPECT_EQ(fmt::format("{}", non_const_only_range<int>(3u, 0)), "[0, 0, 0]");
f8deb5b9 Poul Sander 2022-01-15 13:55 189
f8deb5b9 Poul Sander 2022-01-15 13:55 190
  auto y = std::vector<int>(3u, 0);
f8deb5b9 Poul Sander 2022-01-15 13:55 191
  EXPECT_EQ(fmt::format("{}", y), "[0, 0, 0]");
f8deb5b9 Poul Sander 2022-01-15 13:55 192
  EXPECT_EQ(fmt::format("{}", std::vector<int>(3u, 0)), "[0, 0, 0]");
f8deb5b9 Poul Sander 2022-01-15 13:55 193
f8deb5b9 Poul Sander 2022-01-15 13:55 194
  const auto z = std::vector<int>(3u, 0);
f8deb5b9 Poul Sander 2022-01-15 13:55 195
  EXPECT_EQ(fmt::format("{}", z), "[0, 0, 0]");
f8deb5b9 Poul Sander 2022-01-15 13:55 196
}
f8deb5b9 Poul Sander 2022-01-15 13:55 197
f8deb5b9 Poul Sander 2022-01-15 13:55 198
enum test_enum { foo };
f8deb5b9 Poul Sander 2022-01-15 13:55 199
f8deb5b9 Poul Sander 2022-01-15 13:55 200
TEST(ranges_test, enum_range) {
f8deb5b9 Poul Sander 2022-01-15 13:55 201
  auto v = std::vector<test_enum>{test_enum::foo};
f8deb5b9 Poul Sander 2022-01-15 13:55 202
  EXPECT_EQ(fmt::format("{}", v), "[0]");
f8deb5b9 Poul Sander 2022-01-15 13:55 203
}
f8deb5b9 Poul Sander 2022-01-15 13:55 204
f8deb5b9 Poul Sander 2022-01-15 13:55 205
#if !FMT_MSC_VER
f8deb5b9 Poul Sander 2022-01-15 13:55 206
struct unformattable {};
f8deb5b9 Poul Sander 2022-01-15 13:55 207
f8deb5b9 Poul Sander 2022-01-15 13:55 208
TEST(ranges_test, unformattable_range) {
f8deb5b9 Poul Sander 2022-01-15 13:55 209
  EXPECT_FALSE((fmt::has_formatter<std::vector<unformattable>,
f8deb5b9 Poul Sander 2022-01-15 13:55 210
                                   fmt::format_context>::value));
f8deb5b9 Poul Sander 2022-01-15 13:55 211
}
f8deb5b9 Poul Sander 2022-01-15 13:55 212
#endif
f8deb5b9 Poul Sander 2022-01-15 13:55 213
f8deb5b9 Poul Sander 2022-01-15 13:55 214
#ifdef FMT_RANGES_TEST_ENABLE_JOIN
f8deb5b9 Poul Sander 2022-01-15 13:55 215
TEST(ranges_test, join_tuple) {
f8deb5b9 Poul Sander 2022-01-15 13:55 216
  // Value tuple args.
f8deb5b9 Poul Sander 2022-01-15 13:55 217
  auto t1 = std::tuple<char, int, float>('a', 1, 2.0f);
f8deb5b9 Poul Sander 2022-01-15 13:55 218
  EXPECT_EQ(fmt::format("({})", fmt::join(t1, ", ")), "(a, 1, 2)");
f8deb5b9 Poul Sander 2022-01-15 13:55 219
f8deb5b9 Poul Sander 2022-01-15 13:55 220
  // Testing lvalue tuple args.
f8deb5b9 Poul Sander 2022-01-15 13:55 221
  int x = 4;
f8deb5b9 Poul Sander 2022-01-15 13:55 222
  auto t2 = std::tuple<char, int&>('b', x);
f8deb5b9 Poul Sander 2022-01-15 13:55 223
  EXPECT_EQ(fmt::format("{}", fmt::join(t2, " + ")), "b + 4");
f8deb5b9 Poul Sander 2022-01-15 13:55 224
f8deb5b9 Poul Sander 2022-01-15 13:55 225
  // Empty tuple.
f8deb5b9 Poul Sander 2022-01-15 13:55 226
  auto t3 = std::tuple<>();
f8deb5b9 Poul Sander 2022-01-15 13:55 227
  EXPECT_EQ(fmt::format("{}", fmt::join(t3, "|")), "");
f8deb5b9 Poul Sander 2022-01-15 13:55 228
f8deb5b9 Poul Sander 2022-01-15 13:55 229
  // Single element tuple.
f8deb5b9 Poul Sander 2022-01-15 13:55 230
  auto t4 = std::tuple<float>(4.0f);
f8deb5b9 Poul Sander 2022-01-15 13:55 231
  EXPECT_EQ(fmt::format("{}", fmt::join(t4, "/")), "4");
f8deb5b9 Poul Sander 2022-01-15 13:55 232
f8deb5b9 Poul Sander 2022-01-15 13:55 233
#  if FMT_TUPLE_JOIN_SPECIFIERS
f8deb5b9 Poul Sander 2022-01-15 13:55 234
  // Specs applied to each element.
f8deb5b9 Poul Sander 2022-01-15 13:55 235
  auto t5 = std::tuple<int, int, long>(-3, 100, 1);
f8deb5b9 Poul Sander 2022-01-15 13:55 236
  EXPECT_EQ(fmt::format("{:+03}", fmt::join(t5, ", ")), "-03, +100, +01");
f8deb5b9 Poul Sander 2022-01-15 13:55 237
f8deb5b9 Poul Sander 2022-01-15 13:55 238
  auto t6 = std::tuple<float, double, long double>(3, 3.14, 3.1415);
f8deb5b9 Poul Sander 2022-01-15 13:55 239
  EXPECT_EQ(fmt::format("{:5.5f}", fmt::join(t6, ", ")),
f8deb5b9 Poul Sander 2022-01-15 13:55 240
            "3.00000, 3.14000, 3.14150");
f8deb5b9 Poul Sander 2022-01-15 13:55 241
f8deb5b9 Poul Sander 2022-01-15 13:55 242
  // Testing lvalue tuple args.
f8deb5b9 Poul Sander 2022-01-15 13:55 243
  int y = -1;
f8deb5b9 Poul Sander 2022-01-15 13:55 244
  auto t7 = std::tuple<int, int&, const int&>(3, y, y);
f8deb5b9 Poul Sander 2022-01-15 13:55 245
  EXPECT_EQ(fmt::format("{:03}", fmt::join(t7, ", ")), "003, -01, -01");
f8deb5b9 Poul Sander 2022-01-15 13:55 246
#  endif
f8deb5b9 Poul Sander 2022-01-15 13:55 247
}
f8deb5b9 Poul Sander 2022-01-15 13:55 248
f8deb5b9 Poul Sander 2022-01-15 13:55 249
TEST(ranges_test, join_initializer_list) {
f8deb5b9 Poul Sander 2022-01-15 13:55 250
  EXPECT_EQ(fmt::format("{}", fmt::join({1, 2, 3}, ", ")), "1, 2, 3");
f8deb5b9 Poul Sander 2022-01-15 13:55 251
  EXPECT_EQ(fmt::format("{}", fmt::join({"fmt", "rocks", "!"}, " ")),
f8deb5b9 Poul Sander 2022-01-15 13:55 252
            "fmt rocks !");
f8deb5b9 Poul Sander 2022-01-15 13:55 253
}
f8deb5b9 Poul Sander 2022-01-15 13:55 254
f8deb5b9 Poul Sander 2022-01-15 13:55 255
struct zstring_sentinel {};
f8deb5b9 Poul Sander 2022-01-15 13:55 256
f8deb5b9 Poul Sander 2022-01-15 13:55 257
bool operator==(const char* p, zstring_sentinel) { return *p == '\0'; }
f8deb5b9 Poul Sander 2022-01-15 13:55 258
bool operator!=(const char* p, zstring_sentinel) { return *p != '\0'; }
f8deb5b9 Poul Sander 2022-01-15 13:55 259
f8deb5b9 Poul Sander 2022-01-15 13:55 260
struct zstring {
f8deb5b9 Poul Sander 2022-01-15 13:55 261
  const char* p;
f8deb5b9 Poul Sander 2022-01-15 13:55 262
  const char* begin() const { return p; }
f8deb5b9 Poul Sander 2022-01-15 13:55 263
  zstring_sentinel end() const { return {}; }
f8deb5b9 Poul Sander 2022-01-15 13:55 264
};
f8deb5b9 Poul Sander 2022-01-15 13:55 265
f8deb5b9 Poul Sander 2022-01-15 13:55 266
#  ifdef __cpp_lib_ranges
f8deb5b9 Poul Sander 2022-01-15 13:55 267
struct cpp20_only_range {
f8deb5b9 Poul Sander 2022-01-15 13:55 268
  struct iterator {
f8deb5b9 Poul Sander 2022-01-15 13:55 269
    int val = 0;
f8deb5b9 Poul Sander 2022-01-15 13:55 270
f8deb5b9 Poul Sander 2022-01-15 13:55 271
    using value_type = int;
f8deb5b9 Poul Sander 2022-01-15 13:55 272
    using difference_type = std::ptrdiff_t;
f8deb5b9 Poul Sander 2022-01-15 13:55 273
    using iterator_concept = std::input_iterator_tag;
f8deb5b9 Poul Sander 2022-01-15 13:55 274
f8deb5b9 Poul Sander 2022-01-15 13:55 275
    iterator() = default;
f8deb5b9 Poul Sander 2022-01-15 13:55 276
    iterator(int i) : val(i) {}
f8deb5b9 Poul Sander 2022-01-15 13:55 277
    int operator*() const { return val; }
f8deb5b9 Poul Sander 2022-01-15 13:55 278
    iterator& operator++() {
f8deb5b9 Poul Sander 2022-01-15 13:55 279
      ++val;
f8deb5b9 Poul Sander 2022-01-15 13:55 280
      return *this;
f8deb5b9 Poul Sander 2022-01-15 13:55 281
    }
f8deb5b9 Poul Sander 2022-01-15 13:55 282
    void operator++(int) { ++*this; }
f8deb5b9 Poul Sander 2022-01-15 13:55 283
    bool operator==(const iterator& rhs) const { return val == rhs.val; }
f8deb5b9 Poul Sander 2022-01-15 13:55 284
  };
f8deb5b9 Poul Sander 2022-01-15 13:55 285
f8deb5b9 Poul Sander 2022-01-15 13:55 286
  int lo;
f8deb5b9 Poul Sander 2022-01-15 13:55 287
  int hi;
f8deb5b9 Poul Sander 2022-01-15 13:55 288
f8deb5b9 Poul Sander 2022-01-15 13:55 289
  iterator begin() const { return iterator(lo); }
f8deb5b9 Poul Sander 2022-01-15 13:55 290
  iterator end() const { return iterator(hi); }
f8deb5b9 Poul Sander 2022-01-15 13:55 291
};
f8deb5b9 Poul Sander 2022-01-15 13:55 292
f8deb5b9 Poul Sander 2022-01-15 13:55 293
static_assert(std::input_iterator<cpp20_only_range::iterator>);
f8deb5b9 Poul Sander 2022-01-15 13:55 294
#  endif
f8deb5b9 Poul Sander 2022-01-15 13:55 295
f8deb5b9 Poul Sander 2022-01-15 13:55 296
TEST(ranges_test, join_sentinel) {
f8deb5b9 Poul Sander 2022-01-15 13:55 297
  auto hello = zstring{"hello"};
f8deb5b9 Poul Sander 2022-01-15 13:55 298
  EXPECT_EQ(fmt::format("{}", hello), "['h', 'e', 'l', 'l', 'o']");
f8deb5b9 Poul Sander 2022-01-15 13:55 299
  EXPECT_EQ(fmt::format("{}", fmt::join(hello, "_")), "h_e_l_l_o");
f8deb5b9 Poul Sander 2022-01-15 13:55 300
}
f8deb5b9 Poul Sander 2022-01-15 13:55 301
f8deb5b9 Poul Sander 2022-01-15 13:55 302
TEST(ranges_test, join_range) {
f8deb5b9 Poul Sander 2022-01-15 13:55 303
  noncopyable_range<int> w(3u, 0);
f8deb5b9 Poul Sander 2022-01-15 13:55 304
  EXPECT_EQ(fmt::format("{}", fmt::join(w, ",")), "0,0,0");
f8deb5b9 Poul Sander 2022-01-15 13:55 305
  EXPECT_EQ(fmt::format("{}", fmt::join(noncopyable_range<int>(3u, 0), ",")),
f8deb5b9 Poul Sander 2022-01-15 13:55 306
            "0,0,0");
f8deb5b9 Poul Sander 2022-01-15 13:55 307
f8deb5b9 Poul Sander 2022-01-15 13:55 308
  non_const_only_range<int> x(3u, 0);
f8deb5b9 Poul Sander 2022-01-15 13:55 309
  EXPECT_EQ(fmt::format("{}", fmt::join(x, ",")), "0,0,0");
f8deb5b9 Poul Sander 2022-01-15 13:55 310
  EXPECT_EQ(fmt::format("{}", fmt::join(non_const_only_range<int>(3u, 0), ",")),
f8deb5b9 Poul Sander 2022-01-15 13:55 311
            "0,0,0");
f8deb5b9 Poul Sander 2022-01-15 13:55 312
f8deb5b9 Poul Sander 2022-01-15 13:55 313
  auto y = std::vector<int>(3u, 0);
f8deb5b9 Poul Sander 2022-01-15 13:55 314
  EXPECT_EQ(fmt::format("{}", fmt::join(y, ",")), "0,0,0");
f8deb5b9 Poul Sander 2022-01-15 13:55 315
  EXPECT_EQ(fmt::format("{}", fmt::join(std::vector<int>(3u, 0), ",")),
f8deb5b9 Poul Sander 2022-01-15 13:55 316
            "0,0,0");
f8deb5b9 Poul Sander 2022-01-15 13:55 317
f8deb5b9 Poul Sander 2022-01-15 13:55 318
  const auto z = std::vector<int>(3u, 0);
f8deb5b9 Poul Sander 2022-01-15 13:55 319
  EXPECT_EQ(fmt::format("{}", fmt::join(z, ",")), "0,0,0");
f8deb5b9 Poul Sander 2022-01-15 13:55 320
f8deb5b9 Poul Sander 2022-01-15 13:55 321
#  ifdef __cpp_lib_ranges
f8deb5b9 Poul Sander 2022-01-15 13:55 322
  EXPECT_EQ(fmt::format("{}", cpp20_only_range{.lo = 0, .hi = 5}),
f8deb5b9 Poul Sander 2022-01-15 13:55 323
            "[0, 1, 2, 3, 4]");
f8deb5b9 Poul Sander 2022-01-15 13:55 324
  EXPECT_EQ(
f8deb5b9 Poul Sander 2022-01-15 13:55 325
      fmt::format("{}", fmt::join(cpp20_only_range{.lo = 0, .hi = 5}, ",")),
f8deb5b9 Poul Sander 2022-01-15 13:55 326
      "0,1,2,3,4");
f8deb5b9 Poul Sander 2022-01-15 13:55 327
#  endif
f8deb5b9 Poul Sander 2022-01-15 13:55 328
}
f8deb5b9 Poul Sander 2022-01-15 13:55 329
#endif  // FMT_RANGES_TEST_ENABLE_JOIN
f8deb5b9 Poul Sander 2022-01-15 13:55 330
f8deb5b9 Poul Sander 2022-01-15 13:55 331
TEST(ranges_test, is_printable) {
f8deb5b9 Poul Sander 2022-01-15 13:55 332
  using fmt::detail::is_printable;
f8deb5b9 Poul Sander 2022-01-15 13:55 333
  EXPECT_TRUE(is_printable(0x0323));
f8deb5b9 Poul Sander 2022-01-15 13:55 334
  EXPECT_FALSE(is_printable(0x0378));
f8deb5b9 Poul Sander 2022-01-15 13:55 335
  EXPECT_FALSE(is_printable(0x110000));
f8deb5b9 Poul Sander 2022-01-15 13:55 336
}
f8deb5b9 Poul Sander 2022-01-15 13:55 337
f8deb5b9 Poul Sander 2022-01-15 13:55 338
TEST(ranges_test, escape_string) {
f8deb5b9 Poul Sander 2022-01-15 13:55 339
  using vec = std::vector<std::string>;
f8deb5b9 Poul Sander 2022-01-15 13:55 340
  EXPECT_EQ(fmt::format("{}", vec{"\n\r\t\"\\"}), "[\"\\n\\r\\t\\\"\\\\\"]");
f8deb5b9 Poul Sander 2022-01-15 13:55 341
  EXPECT_EQ(fmt::format("{}", vec{"\x07"}), "[\"\\x07\"]");
f8deb5b9 Poul Sander 2022-01-15 13:55 342
  EXPECT_EQ(fmt::format("{}", vec{"\x7f"}), "[\"\\x7f\"]");
f8deb5b9 Poul Sander 2022-01-15 13:55 343
  EXPECT_EQ(fmt::format("{}", vec{"n\xcc\x83"}), "[\"n\xcc\x83\"]");
f8deb5b9 Poul Sander 2022-01-15 13:55 344
f8deb5b9 Poul Sander 2022-01-15 13:55 345
  if (fmt::detail::is_utf8()) {
f8deb5b9 Poul Sander 2022-01-15 13:55 346
    EXPECT_EQ(fmt::format("{}", vec{"\xcd\xb8"}), "[\"\\u0378\"]");
f8deb5b9 Poul Sander 2022-01-15 13:55 347
    // Unassigned Unicode code points.
f8deb5b9 Poul Sander 2022-01-15 13:55 348
    EXPECT_EQ(fmt::format("{}", vec{"\xf0\xaa\x9b\x9e"}), "[\"\\U0002a6de\"]");
f8deb5b9 Poul Sander 2022-01-15 13:55 349
    EXPECT_EQ(fmt::format("{}", vec{"\xf4\x8f\xbf\xc0"}),
f8deb5b9 Poul Sander 2022-01-15 13:55 350
              "[\"\\xf4\\x8f\\xbf\\xc0\"]");
f8deb5b9 Poul Sander 2022-01-15 13:55 351
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 352
}
f8deb5b9 Poul Sander 2022-01-15 13:55 353
f8deb5b9 Poul Sander 2022-01-15 13:55 354
#ifdef FMT_USE_STRING_VIEW
f8deb5b9 Poul Sander 2022-01-15 13:55 355
struct convertible_to_string_view {
f8deb5b9 Poul Sander 2022-01-15 13:55 356
  operator std::string_view() const { return "foo"; }
f8deb5b9 Poul Sander 2022-01-15 13:55 357
};
f8deb5b9 Poul Sander 2022-01-15 13:55 358
f8deb5b9 Poul Sander 2022-01-15 13:55 359
TEST(ranges_test, escape_convertible_to_string_view) {
f8deb5b9 Poul Sander 2022-01-15 13:55 360
  EXPECT_EQ(fmt::format("{}", std::vector<convertible_to_string_view>(1)),
f8deb5b9 Poul Sander 2022-01-15 13:55 361
            "[\"foo\"]");
f8deb5b9 Poul Sander 2022-01-15 13:55 362
}
f8deb5b9 Poul Sander 2022-01-15 13:55 363
#endif  // FMT_USE_STRING_VIEW
1970-01-01 00:00 364