SpECTRE Documentation Coverage Report
Current view: top level - Utilities - StdHelpers.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 100.0 % 20 20
Test Date: 2026-10-22 17:29:42
Legend: Lines:     hit not hit

            Line data    Source code
       1            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 <optional>
      18              : #include <set>
      19              : #include <sstream>
      20              : #include <string>
      21              : #include <tuple>
      22              : #include <unordered_map>
      23              : #include <unordered_set>
      24              : #include <utility>
      25              : #include <vector>
      26              : 
      27              : #include "Utilities/PrintHelpers.hpp"
      28              : #include "Utilities/Requires.hpp"
      29              : #include "Utilities/StlStreamDeclarations.hpp"
      30              : #include "Utilities/TypeTraits/IsStreamable.hpp"
      31              : 
      32              : namespace StdHelpers_detail {
      33              : 
      34              : // Helper classes for operator<< for tuples
      35              : template <size_t N>
      36              : struct TuplePrinter {
      37              :   template <typename... Args>
      38              :   static std::ostream& print(std::ostream& os, const std::tuple<Args...>& t) {
      39              :     TuplePrinter<N - 1>::print(os, t);
      40              :     os << ",";
      41              :     print_value(os, std::get<N - 1>(t));
      42              :     return os;
      43              :   }
      44              : };
      45              : 
      46              : template <>
      47              : struct TuplePrinter<1> {
      48              :   template <typename... Args>
      49              :   static std::ostream& print(std::ostream& os, const std::tuple<Args...>& t) {
      50              :     print_value(os, std::get<0>(t));
      51              :     return os;
      52              :   }
      53              : };
      54              : 
      55              : template <>
      56              : struct TuplePrinter<0> {
      57              :   template <typename... Args>
      58              :   static std::ostream& print(std::ostream& os,
      59              :                              const std::tuple<Args...>& /*t*/) {
      60              :     return os;
      61              :   }
      62              : };
      63              : }  // namespace StdHelpers_detail
      64              : 
      65              : /*!
      66              :  * \ingroup UtilitiesGroup
      67              :  * \brief Output the items of a std::list
      68              :  */
      69              : template <typename T>
      70            1 : inline std::ostream& operator<<(std::ostream& os, const std::list<T>& v) {
      71              :   sequence_print_helper(os, std::begin(v), std::end(v));
      72              :   return os;
      73              : }
      74              : 
      75              : /*!
      76              :  * \ingroup UtilitiesGroup
      77              :  * \brief Output the items of a std::vector
      78              :  */
      79              : template <typename T>
      80            1 : inline std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
      81              :   sequence_print_helper(os, std::begin(v), std::end(v));
      82              :   return os;
      83              : }
      84              : 
      85              : /*!
      86              :  * \ingroup UtilitiesGroup
      87              :  * \brief Output the items of a std::deque
      88              :  */
      89              : template <typename T>
      90            1 : inline std::ostream& operator<<(std::ostream& os, const std::deque<T>& v) {
      91              :   sequence_print_helper(os, std::begin(v), std::end(v));
      92              :   return os;
      93              : }
      94              : 
      95              : /*!
      96              :  * \ingroup UtilitiesGroup
      97              :  * \brief Output the items of a std::array
      98              :  */
      99              : template <typename T, size_t N>
     100            1 : inline std::ostream& operator<<(std::ostream& os, const std::array<T, N>& a) {
     101              :   sequence_print_helper(os, begin(a), end(a));
     102              :   return os;
     103              : }
     104              : 
     105              : /*!
     106              :  * \ingroup UtilitiesGroup
     107              :  * \brief Stream operator for tuples
     108              :  */
     109              : template <typename... Args>
     110            1 : inline std::ostream& operator<<(std::ostream& os,
     111              :                                 const std::tuple<Args...>& t) {
     112              :   os << "(";
     113              :   StdHelpers_detail::TuplePrinter<sizeof...(Args)>::print(os, t);
     114              :   os << ")";
     115              :   return os;
     116              : }
     117              : 
     118              : /*!
     119              :  * \ingroup UtilitiesGroup
     120              :  * \brief Output all the key, value pairs of a std::unordered_map
     121              :  */
     122              : template <typename K, typename V, typename H>
     123            1 : inline std::ostream& operator<<(std::ostream& os,
     124              :                                 const std::unordered_map<K, V, H>& m) {
     125              :   unordered_print_helper(
     126              :       os, begin(m), end(m),
     127              :       [](std::ostream& out,
     128              :          const typename std::unordered_map<K, V, H>::value_type& value) {
     129              :         out << "[";
     130              :         print_value(out, value.first);
     131              :         out << ",";
     132              :         print_value(out, value.second);
     133              :         out << "]";
     134              :       });
     135              :   return os;
     136              : }
     137              : 
     138              : /*!
     139              :  * \ingroup UtilitiesGroup
     140              :  * \brief Output all the key, value pairs of a std::map
     141              :  */
     142              : template <typename K, typename V, typename C>
     143            1 : inline std::ostream& operator<<(std::ostream& os, const std::map<K, V, C>& m) {
     144              :   sequence_print_helper(
     145              :       os, begin(m), end(m),
     146              :       [](std::ostream& out,
     147              :          const typename std::map<K, V, C>::value_type& value) {
     148              :         out << "[";
     149              :         print_value(out, value.first);
     150              :         out << ",";
     151              :         print_value(out, value.second);
     152              :         out << "]";
     153              :       });
     154              :   return os;
     155              : }
     156              : 
     157              : /*!
     158              :  * \ingroup UtilitiesGroup
     159              :  * \brief Output the items of a std::unordered_set
     160              :  */
     161              : template <typename T, typename H>
     162            1 : inline std::ostream& operator<<(std::ostream& os,
     163              :                                 const std::unordered_set<T, H>& v) {
     164              :   unordered_print_helper(os, std::begin(v), std::end(v));
     165              :   return os;
     166              : }
     167              : 
     168              : /*!
     169              :  * \ingroup UtilitiesGroup
     170              :  * \brief Output the items of a std::unordered_multiset
     171              :  */
     172              : template <typename T, typename H>
     173            1 : inline std::ostream& operator<<(std::ostream& os,
     174              :                                 const std::unordered_multiset<T, H>& v) {
     175              :   unordered_print_helper(os, std::begin(v), std::end(v));
     176              :   return os;
     177              : }
     178              : 
     179              : /*!
     180              :  * \ingroup UtilitiesGroup
     181              :  * \brief Output the items of a std::set
     182              :  */
     183              : template <typename T, typename C>
     184            1 : inline std::ostream& operator<<(std::ostream& os, const std::set<T, C>& v) {
     185              :   sequence_print_helper(os, std::begin(v), std::end(v));
     186              :   return os;
     187              : }
     188              : 
     189              : /*!
     190              :  * \ingroup UtilitiesGroup
     191              :  * \brief Stream operator for std::unique_ptr
     192              :  */
     193              : template <typename T, Requires<tt::is_streamable<std::ostream, T>::value>>
     194            1 : inline std::ostream& operator<<(std::ostream& os, const std::unique_ptr<T>& t) {
     195              :   return os << *t;
     196              : }
     197              : 
     198              : /*!
     199              :  * \ingroup UtilitiesGroup
     200              :  * \brief Stream operator for std::shared_ptr
     201              :  */
     202              : template <typename T, Requires<tt::is_streamable<std::ostream, T>::value>>
     203            1 : inline std::ostream& operator<<(std::ostream& os, const std::shared_ptr<T>& t) {
     204              :   return os << *t;
     205              : }
     206              : 
     207              : /*!
     208              :  * \ingroup UtilitiesGroup
     209              :  * \brief Stream operator for std::pair
     210              :  */
     211              : template <typename T, typename U>
     212            1 : inline std::ostream& operator<<(std::ostream& os, const std::pair<T, U>& t) {
     213              :   os << "(";
     214              :   print_value(os, t.first);
     215              :   os << ", ";
     216              :   print_value(os, t.second);
     217              :   os << ")";
     218              :   return os;
     219              : }
     220              : 
     221              : /*!
     222              :  * \ingroup UtilitiesGroup
     223              :  * \brief Stream operator for std::optional
     224              :  */
     225              : template <typename T>
     226            1 : inline std::ostream& operator<<(std::ostream& os, const std::optional<T>& t) {
     227              :   // Match boost::optional behavior and print "--" when invalid
     228              :   if (t.has_value()) {
     229              :     print_value(os, t.value());
     230              :     return os;
     231              :   } else {
     232              :     return os << "--";
     233              :   }
     234              : }
     235              : 
     236              : /*!
     237              :  * \ingroup UtilitiesGroup
     238              :  * \brief Equivalent to `os << t`.
     239              :  *
     240              :  * For some reason this sometimes works when trying to stream directly
     241              :  * doesn't find our STL container stream operators.
     242              :  */
     243              : template <typename T>
     244            1 : void print_stl(std::ostream& os, const T& t) {
     245              :   using ::operator<<;
     246              :   os << t;
     247              : }
     248              : 
     249              : /*!
     250              :  * \ingroup UtilitiesGroup
     251              :  * \brief Construct a string containing the keys of a std::unordered_map
     252              :  */
     253              : template <typename K, typename V, typename H>
     254            1 : inline std::string keys_of(const std::unordered_map<K, V, H>& m) {
     255              :   std::ostringstream os;
     256              :   unordered_print_helper(
     257              :       os, begin(m), end(m),
     258              :       [](std::ostream& out,
     259              :          const typename std::unordered_map<K, V, H>::value_type& value) {
     260              :         print_value(out, value.first);
     261              :       });
     262              :   return os.str();
     263              : }
     264              : 
     265              : /*!
     266              :  * \ingroup UtilitiesGroup
     267              :  * \brief Construct a string containing the keys of a std::map
     268              :  */
     269              : template <typename K, typename V, typename C>
     270            1 : inline std::string keys_of(const std::map<K, V, C>& m) {
     271              :   std::ostringstream os;
     272              :   sequence_print_helper(
     273              :       os, begin(m), end(m),
     274              :       [](std::ostream& out,
     275              :          const typename std::map<K, V, C>::value_type& value) {
     276              :         print_value(out, value.first);
     277              :       });
     278              :   return os.str();
     279              : }
     280              : 
     281              : /*!
     282              :  * \ingroup UtilitiesGroup
     283              :  * \brief Format a string like printf
     284              :  *
     285              :  * Given a formatting string and arguments this returns the corresponding
     286              :  * string. Similar to printf but using std::strings.
     287              :  */
     288              : template <typename... Args>
     289            1 : std::string formatted_string(const std::string& fmt, Args... args) {
     290              : #pragma GCC diagnostic push
     291              : #pragma GCC diagnostic ignored "-Wformat-nonliteral"
     292              :   // clang-tidy: do not use snprintf
     293              :   auto requiredBytes = static_cast<size_t>(std::snprintf(  // NOLINT
     294              :                            nullptr, 0, fmt.c_str(), args...)) +
     295              :                        1;
     296              :   std::string rtn;
     297              :   rtn.resize(requiredBytes);
     298              :   // clang-tidy: do not use snprintf
     299              :   std::snprintf(&rtn[0], requiredBytes, fmt.c_str(), args...);  // NOLINT
     300              : #pragma GCC diagnostic pop
     301              :   if (rtn[rtn.size() - 1] == '\0') {
     302              :     rtn.resize(rtn.size() - 1);
     303              :   }
     304              :   return rtn;
     305              : }
     306              : 
     307              : /*!
     308              :  * \ingroup UtilitiesGroup
     309              :  * \brief Get the current date and time
     310              :  */
     311            1 : inline std::string current_date_and_time() {
     312              :   const auto now =
     313              :       std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
     314              :   return std::ctime(&now);
     315              : }
        

Generated by: LCOV version 2.0-1