StdHelpers.hpp
Go to the documentation of this file.
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 /// \file
5 /// Defines helper functions for the standard library.
6 
7 #pragma once
8 
9 #include <array>
10 #include <chrono>
11 #include <cstdio>
12 #include <ctime>
13 #include <deque>
14 #include <list>
15 #include <map>
16 #include <memory>
17 #include <set>
18 #include <sstream>
19 #include <string>
20 #include <tuple>
21 #include <unordered_map>
22 #include <unordered_set>
23 #include <utility>
24 #include <vector>
25 
26 #include "Utilities/PrintHelpers.hpp"
27 #include "Utilities/Requires.hpp"
29 #include "Utilities/TypeTraits.hpp"
30 
31 namespace StdHelpers_detail {
32 // Helper classes for operator<< for tuples
33 template <size_t N>
34 struct TuplePrinter {
35  template <typename... Args>
36  static std::ostream& print(std::ostream& os, const std::tuple<Args...>& t) {
37  TuplePrinter<N - 1>::print(os, t);
38  os << "," << std::get<N - 1>(t);
39  return os;
40  }
41 };
42 
43 template <>
44 struct TuplePrinter<1> {
45  template <typename... Args>
46  static std::ostream& print(std::ostream& os, const std::tuple<Args...>& t) {
47  os << std::get<0>(t);
48  return os;
49  }
50 };
51 
52 template <>
53 struct TuplePrinter<0> {
54  template <typename... Args>
55  static std::ostream& print(std::ostream& os,
56  const std::tuple<Args...>& /*t*/) {
57  return os;
58  }
59 };
60 } // namespace StdHelpers_detail
61 
62 /*!
63  * \ingroup UtilitiesGroup
64  * \brief Output the items of a std::list
65  */
66 template <typename T>
67 inline std::ostream& operator<<(std::ostream& os, const std::list<T>& v) {
68  sequence_print_helper(os, std::begin(v), std::end(v));
69  return os;
70 }
71 
72 /*!
73  * \ingroup UtilitiesGroup
74  * \brief Output the items of a std::vector
75  */
76 template <typename T>
77 inline std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
78  sequence_print_helper(os, std::begin(v), std::end(v));
79  return os;
80 }
81 
82 /*!
83  * \ingroup UtilitiesGroup
84  * \brief Output the items of a std::deque
85  */
86 template <typename T>
87 inline std::ostream& operator<<(std::ostream& os, const std::deque<T>& v) {
88  sequence_print_helper(os, std::begin(v), std::end(v));
89  return os;
90 }
91 
92 /*!
93  * \ingroup UtilitiesGroup
94  * \brief Output the items of a std::array
95  */
96 template <typename T, size_t N>
97 inline std::ostream& operator<<(std::ostream& os, const std::array<T, N>& a) {
98  sequence_print_helper(os, begin(a), end(a));
99  return os;
100 }
101 
102 /*!
103  * \ingroup UtilitiesGroup
104  * \brief Stream operator for tuples
105  */
106 template <typename... Args>
108  const std::tuple<Args...>& t) {
109  os << "(";
110  StdHelpers_detail::TuplePrinter<sizeof...(Args)>::print(os, t);
111  os << ")";
112  return os;
113 }
114 
115 /*!
116  * \ingroup UtilitiesGroup
117  * \brief Output all the key, value pairs of a std::unordered_map
118  */
119 template <typename K, typename V, typename H>
121  const std::unordered_map<K, V, H>& m) {
123  os, begin(m), end(m),
124  [](std::ostream& out,
126  out << "[" << it->first << "," << it->second << "]";
127  });
128  return os;
129 }
130 
131 /*!
132  * \ingroup UtilitiesGroup
133  * \brief Output all the key, value pairs of a std::map
134  */
135 template <typename K, typename V, typename C>
136 inline std::ostream& operator<<(std::ostream& os, const std::map<K, V, C>& m) {
138  os, begin(m), end(m),
139  [](std::ostream& out, typename std::map<K, V, C>::const_iterator it) {
140  out << "[" << it->first << "," << it->second << "]";
141  });
142  return os;
143 }
144 
145 /*!
146  * \ingroup UtilitiesGroup
147  * \brief Output the items of a std::unordered_set
148  */
149 template <typename T>
151  const std::unordered_set<T>& v) {
152  unordered_print_helper(os, std::begin(v), std::end(v));
153  return os;
154 }
155 
156 /*!
157  * \ingroup UtilitiesGroup
158  * \brief Output the items of a std::set
159  */
160 template <typename T, typename C>
161 inline std::ostream& operator<<(std::ostream& os, const std::set<T, C>& v) {
162  sequence_print_helper(os, std::begin(v), std::end(v));
163  return os;
164 }
165 
166 /*!
167  * \ingroup UtilitiesGroup
168  * \brief Stream operator for std::unique_ptr
169  */
170 template <typename T, Requires<tt::is_streamable<std::ostream, T>::value>>
171 inline std::ostream& operator<<(std::ostream& os, const std::unique_ptr<T>& t) {
172  return os << *t;
173 }
174 
175 /*!
176  * \ingroup UtilitiesGroup
177  * \brief Stream operator for std::shared_ptr
178  */
179 template <typename T, Requires<tt::is_streamable<std::ostream, T>::value>>
180 inline std::ostream& operator<<(std::ostream& os, const std::shared_ptr<T>& t) {
181  return os << *t;
182 }
183 
184 /*!
185  * \ingroup UtilitiesGroup
186  * \brief Stream operator for std::pair
187  */
188 template <typename T, typename U>
189 inline std::ostream& operator<<(std::ostream& os, const std::pair<T, U>& t) {
190  return os << "(" << t.first << ", " << t.second << ")";
191 }
192 
193 /*!
194  * \ingroup UtilitiesGroup
195  * \brief Construct a string containing the keys of a std::unordered_map
196  */
197 template <typename K, typename V, typename H>
201  os, begin(m), end(m),
202  [](std::ostream& out,
204  out << it->first;
205  });
206  return os.str();
207 }
208 
209 /*!
210  * \ingroup UtilitiesGroup
211  * \brief Construct a string containing the keys of a std::map
212  */
213 template <typename K, typename V, typename C>
217  os, begin(m), end(m),
218  [](std::ostream& out, typename std::map<K, V, C>::const_iterator it) {
219  out << it->first;
220  });
221  return os.str();
222 }
223 
224 /*!
225  * \ingroup UtilitiesGroup
226  * \brief Format a string like printf
227  *
228  * Given a formatting string and arguments this returns the corresponding
229  * string. Similar to printf but using std::strings.
230  */
231 template <typename... Args>
232 std::string formatted_string(const std::string& fmt, Args... args) {
233 #pragma GCC diagnostic push
234 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
235  // clang-tidy: do not use snprintf
236  auto requiredBytes = static_cast<size_t>(std::snprintf( // NOLINT
237  nullptr, 0, fmt.c_str(), args...)) +
238  1;
239  std::string rtn;
240  rtn.resize(requiredBytes);
241  // clang-tidy: do not use snprintf
242  std::snprintf(&rtn[0], requiredBytes, fmt.c_str(), args...); // NOLINT
243 #pragma GCC diagnostic pop
244  if (rtn[rtn.size() - 1] == '\0') {
245  rtn.resize(rtn.size() - 1);
246  }
247  return rtn;
248 }
249 
250 /*!
251  * \ingroup UtilitiesGroup
252  * \brief Get the current date and time
253  */
255  const auto now =
257  return std::ctime(&now);
258 }
void unordered_print_helper(std::ostream &out, ForwardIt &&begin, ForwardIt &&end, Func f) noexcept
Definition: PrintHelpers.hpp:51
Definition: StdHelpers.hpp:31
constexpr Tag::type & get(Variables< TagList > &v) noexcept
Return Tag::type pointing into the contiguous array.
Definition: Variables.hpp:649
std::string formatted_string(const std::string &fmt, Args... args)
Format a string like printf.
Definition: StdHelpers.hpp:232
Declares stream operators for STL containers.
Defines the type alias Requires.
std::string current_date_and_time()
Get the current date and time.
Definition: StdHelpers.hpp:254
std::string keys_of(const std::unordered_map< K, V, H > &m)
Construct a string containing the keys of a std::unordered_map.
Definition: StdHelpers.hpp:198
void sequence_print_helper(std::ostream &out, ForwardIt &&begin, ForwardIt &&end, Func f) noexcept
Applies the function f(out, it) to each item from begin to end, separated by commas and surrounded by...
Definition: PrintHelpers.hpp:18
std::ostream & operator<<(std::ostream &os, const std::list< T > &v)
Output the items of a std::list.
Definition: StdHelpers.hpp:67
Defines type traits, some of which are future STL type_traits header.