SpECTRE Documentation Coverage Report
Current view: top level - Utilities - StdHelpers.hpp Hit Total Coverage
Commit: 9ddc33268b29014a4956c8f0c24ca90b397463e1 Lines: 20 20 100.0 %
Date: 2024-04-26 20:00:04
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 1.14