• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Formatting library for C++ - the core API
2 //
3 // Copyright (c) 2012 - present, Victor Zverovich
4 // All rights reserved.
5 //
6 // For the license information refer to format.h.
7 //
8 // Copyright (c) 2018 - present, Remotion (Igor Schulz)
9 // All Rights Reserved
10 // {fmt} support for ranges, containers and types tuple interface.
11 
12 #include "fmt/ranges.h"
13 #include "gtest.h"
14 
15 // Check if  'if constexpr' is supported.
16 #if (__cplusplus > 201402L) || \
17     (defined(_MSVC_LANG) && _MSVC_LANG > 201402L && _MSC_VER >= 1910)
18 
19 #  include <array>
20 #  include <map>
21 #  include <string>
22 #  include <vector>
23 
TEST(RangesTest,FormatVector)24 TEST(RangesTest, FormatVector) {
25   std::vector<int32_t> iv{1, 2, 3, 5, 7, 11};
26   auto ivf = fmt::format("{}", iv);
27   EXPECT_EQ("{1, 2, 3, 5, 7, 11}", ivf);
28 }
29 
TEST(RangesTest,FormatVector2)30 TEST(RangesTest, FormatVector2) {
31   std::vector<std::vector<int32_t>> ivv{{1, 2}, {3, 5}, {7, 11}};
32   auto ivf = fmt::format("{}", ivv);
33   EXPECT_EQ("{{1, 2}, {3, 5}, {7, 11}}", ivf);
34 }
35 
TEST(RangesTest,FormatMap)36 TEST(RangesTest, FormatMap) {
37   std::map<std::string, int32_t> simap{{"one", 1}, {"two", 2}};
38   EXPECT_EQ("{(\"one\", 1), (\"two\", 2)}", fmt::format("{}", simap));
39 }
40 
TEST(RangesTest,FormatPair)41 TEST(RangesTest, FormatPair) {
42   std::pair<int64_t, float> pa1{42, 1.5f};
43   EXPECT_EQ("(42, 1.5)", fmt::format("{}", pa1));
44 }
45 
TEST(RangesTest,FormatTuple)46 TEST(RangesTest, FormatTuple) {
47   std::tuple<int64_t, float, std::string, char> tu1{42, 1.5f, "this is tuple",
48                                                     'i'};
49   EXPECT_EQ("(42, 1.5, \"this is tuple\", 'i')", fmt::format("{}", tu1));
50 }
51 
TEST(RangesTest,JoinTuple)52 TEST(RangesTest, JoinTuple) {
53   // Value tuple args
54   std::tuple<char, int, float> t1 = std::make_tuple('a', 1, 2.0f);
55   EXPECT_EQ("(a, 1, 2.0)", fmt::format("({})", fmt::join(t1, ", ")));
56 
57   // Testing lvalue tuple args
58   int x = 4;
59   std::tuple<char, int&> t2{'b', x};
60   EXPECT_EQ("b + 4", fmt::format("{}", fmt::join(t2, " + ")));
61 
62   // Empty tuple
63   std::tuple<> t3;
64   EXPECT_EQ("", fmt::format("{}", fmt::join(t3, "|")));
65 
66   // Single element tuple
67   std::tuple<float> t4{4.0f};
68   EXPECT_EQ("4.0", fmt::format("{}", fmt::join(t4, "/")));
69 }
70 
71 struct my_struct {
72   int32_t i;
73   std::string str;  // can throw
getmy_struct74   template <std::size_t N> decltype(auto) get() const noexcept {
75     if constexpr (N == 0)
76       return i;
77     else if constexpr (N == 1)
78       return fmt::string_view{str};
79   }
80 };
81 
get(const my_struct & s)82 template <std::size_t N> decltype(auto) get(const my_struct& s) noexcept {
83   return s.get<N>();
84 }
85 
86 namespace std {
87 
88 template <>
89 struct tuple_size<my_struct> : std::integral_constant<std::size_t, 2> {};
90 
91 template <std::size_t N> struct tuple_element<N, my_struct> {
92   using type = decltype(std::declval<my_struct>().get<N>());
93 };
94 
95 }  // namespace std
96 
TEST(RangesTest,FormatStruct)97 TEST(RangesTest, FormatStruct) {
98   my_struct mst{13, "my struct"};
99   EXPECT_EQ("(13, \"my struct\")", fmt::format("{}", mst));
100 }
101 
TEST(RangesTest,FormatTo)102 TEST(RangesTest, FormatTo) {
103   char buf[10];
104   auto end = fmt::format_to(buf, "{}", std::vector{1, 2, 3});
105   *end = '\0';
106   EXPECT_STREQ(buf, "{1, 2, 3}");
107 }
108 
109 struct path_like {
110   const path_like* begin() const;
111   const path_like* end() const;
112 
113   operator std::string() const;
114 };
115 
TEST(RangesTest,PathLike)116 TEST(RangesTest, PathLike) {
117   EXPECT_FALSE((fmt::is_range<path_like, char>::value));
118 }
119 
120 #endif  // (__cplusplus > 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >
121         // 201402L && _MSC_VER >= 1910)
122 
123 #ifdef FMT_USE_STRING_VIEW
124 struct string_like {
125   const char* begin();
126   const char* end();
operator fmt::string_viewstring_like127   explicit operator fmt::string_view() const { return "foo"; }
operator std::string_viewstring_like128   explicit operator std::string_view() const { return "foo"; }
129 };
130 
TEST(RangesTest,FormatStringLike)131 TEST(RangesTest, FormatStringLike) {
132   EXPECT_EQ("foo", fmt::format("{}", string_like()));
133 }
134 #endif  // FMT_USE_STRING_VIEW
135