Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-21 08:33:52

0001 #ifndef RIVET_RivetSTL_HH
0002 #define RIVET_RivetSTL_HH
0003 
0004 #include <string>
0005 #include <array>
0006 #include <vector>
0007 #include <list>
0008 #include <set>
0009 #include <map>
0010 #include <memory>
0011 #include <functional>
0012 #include <ostream>
0013 #include <fstream>
0014 #include <sstream>
0015 #include <cmath>
0016 #include <limits>
0017 #include <complex>
0018 #include <cstdint>
0019 #include <type_traits>
0020 
0021 namespace Rivet {
0022 
0023 
0024   /// We implicitly use STL entities in the Rivet namespace
0025   // using namespace std;
0026   using std::string;
0027   using std::to_string;
0028   using namespace std::string_literals;
0029 
0030   using std::ifstream;
0031   using std::ofstream;
0032 
0033   using std::array;
0034   using std::vector;
0035   using std::list;
0036   using std::set;
0037   using std::multiset;
0038   using std::map;
0039   using std::multimap;
0040   using std::pair;
0041   using std::make_pair;
0042 
0043   using std::unique_ptr;
0044   using std::shared_ptr;
0045   using std::make_shared;
0046   using std::make_unique;
0047   using std::dynamic_pointer_cast;
0048 
0049   using std::initializer_list;
0050 
0051   using std::function;
0052 
0053   using std::isnan;
0054 
0055   using std::complex;
0056 
0057   /// @name Streaming containers as string reps
0058   ///
0059   /// @todo Make these named toStr rather than operator<<
0060   /// @todo Make these generic to any iterable
0061   /// @{
0062 
0063   /// Convenient function for streaming out vectors of any streamable object.
0064   template<typename T>
0065   inline std::ostream& operator << (std::ostream& os, const std::vector<T>& vec) {
0066     os << "[ ";
0067     for (size_t i=0; i<vec.size(); ++i) {
0068       os << vec[i] << " ";
0069     }
0070     os << "]";
0071     return os;
0072   }
0073 
0074   /// Convenient function for streaming out lists of any streamable object.
0075   template<typename T>
0076   inline std::ostream& operator << (std::ostream& os, const std::list<T>& vec) {
0077     os << "[ ";
0078     for (size_t i=0; i<vec.size(); ++i) {
0079       os << vec[i] << " ";
0080     }
0081     os << "]";
0082     return os;
0083   }
0084 
0085   /// @}
0086 
0087   /// @name Convenience container typedefs
0088   /// @{
0089   typedef vector<std::string> strings;
0090   typedef vector<double> doubles;
0091   typedef vector<float> floats;
0092   typedef vector<int> ints;
0093   /// @}
0094 
0095 
0096   /// @name Conversions between containers
0097   /// @{
0098 
0099   /// Convert a container CONT to a vector of T via static casting
0100   template <typename T, typename CONT>
0101   inline vector<T> mkVecOf(const CONT& c) {
0102     vector<T> rtn; rtn.reserve(c.size());
0103     for (const typename CONT::value_type& x : c) {
0104       rtn.push_back(static_cast<T>(x)); //< check narrowing conversion?
0105     }
0106     return rtn;
0107   }
0108 
0109   // /// Convert an initializer list of X to a vector of T via static casting
0110   // template <typename T, typename X>
0111   // inline vector<T> mkVecOf(const std::initializer_list<X>& il) {
0112   //   return mkVecOf<T>(vector<X>(il));
0113   // }
0114 
0115 
0116   /// Convert a container CONT to a vector of T via static casting
0117   //
0118   template <typename T, typename CONT, typename FN = std::string(*)(typename std::remove_reference_t<CONT>::value_type),
0119             typename = std::enable_if_t<std::is_convertible_v<
0120                             T, std::decay_t<std::invoke_result_t<
0121                             FN, typename std::remove_reference_t<CONT>::value_type>> >> >
0122   vector<T> mkVecOf(CONT&& c, FN&& fn) {
0123     vector<T> rtn;
0124     rtn.reserve(std::distance(std::begin(c), std::end(c)));
0125     for (auto&& x : std::forward<CONT>(c)) {
0126       rtn.push_back(std::forward<FN>(fn)(std::forward<decltype(x)>(x))); //< check narrowing conversion?
0127     }
0128     return rtn;
0129   }
0130 
0131   // template <typename CONT, typename FN = std::string(*)(typename std::remove_reference_t<CONT>::value_type),
0132   //           typename T = std::decay_t<std::invoke_result_t<FN, typename std::remove_reference_t<CONT>::value_type> >        >
0133   // vector<T> mkVecOf(CONT&& c, FN&& fn) {
0134   //   vector<T> rtn;
0135   //   rtn.reserve(std::distance(std::begin(c), std::end(c)));
0136   //   for (auto&& x : std::forward<CONT>(c)) {
0137   //     rtn.push_back(std::forward<FN>(fn)(std::forward<decltype(x)>(x)));
0138   //   }
0139   //   return rtn;
0140   // }
0141 
0142 
0143   /// Convert a container to a vector of strings
0144   template <typename CONT>
0145   inline vector<std::string>
0146   mkStrings(const CONT& c) { return mkVecOf<string>(c, to_string); }
0147 
0148   /// Convert an initializer list to a vector of strings
0149   template <typename X>
0150   inline vector<std::string>
0151   mkStrings(const std::initializer_list<X>& il) { return mkVecOf<string>(il, to_string); }
0152 
0153 
0154   /// Convert a container to a vector of doubles
0155   template <typename CONT>
0156   //inline typename std::enable_if_t<std::is_floating_point_v<typename CONT::value_type>, vector<double> >
0157   inline vector<double>
0158   mkDoubles(const CONT& c) { return mkVecOf<double>(c); }
0159 
0160   /// Convert an initializer list to a vector of doubles
0161   template <typename X>
0162   //inline typename std::enable_if_t<std::is_floating_point_v<X>, vector<double> >
0163   inline vector<double>
0164   mkDoubles(const std::initializer_list<X>& il) { return mkVecOf<double>(il); }
0165 
0166 
0167   /// Convert a container to a vector of floats
0168   template <typename CONT>
0169   inline typename std::enable_if_t<std::is_floating_point_v<typename CONT::value_type>, vector<float> >
0170   // inline vector<float>
0171   mkFloats(const CONT& c) { return mkVecOf<float>(c); }
0172 
0173   /// Convert an initializer list to a vector of floats
0174   template <typename X>
0175   // inline typename std::enable_if_t<std::is_floating_point_v<X>, vector<float> >
0176   inline vector<float>
0177   mkFloats(const std::initializer_list<X>& il) { return mkVecOf<float>(il); }
0178 
0179 
0180   /// Convert a container to a vector of ints
0181   template <typename CONT>
0182   //inline typename std::enable_if_t<std::is_arithmetic_v<typename CONT::value_type>, vector<int> >
0183   inline vector<int>
0184   mkInts(const CONT& c) { return mkVecOf<int>(c); }
0185 
0186   /// Convert an initializer list to a vector of ints
0187   template <typename X>
0188   //inline typename std::enable_if_t<std::is_arithmetic_v<X>, vector<int> >
0189   inline vector<int>
0190   mkInts(const std::initializer_list<X>& il) { return mkVecOf<int>(il); }
0191 
0192   /// @}
0193 
0194   
0195   /// @name Boolean-return container searching
0196   /// @{
0197 
0198   /// @todo Use SFINAE, Boost.Range, or other template trickery for more generic container matching?
0199 
0200   /// Does @a s contain @a sub as a substring?
0201   inline bool contains(const std::string& s, const std::string& sub) {
0202     return s.find(sub) != string::npos;
0203   }
0204 
0205   /// Does the init list @a il contain @a x?
0206   template <typename T>
0207   inline bool contains(const std::initializer_list<T>& il, const T& x) {
0208     return find(begin(il), end(il), x) != end(il);
0209   }
0210 
0211   /// Does the vector @a v contain @a x?
0212   template <typename T>
0213   inline bool contains(const std::vector<T>& v, const T& x) {
0214     return find(begin(v), end(v), x) != end(v);
0215   }
0216 
0217   /// Does the list @a l contain @a x?
0218   template <typename T>
0219   inline bool contains(const std::list<T>& l, const T& x) {
0220     return find(begin(l), end(l), x) != end(l);
0221   }
0222 
0223   /// Does the set @a s contain @a x?
0224   template <typename T>
0225   inline bool contains(const std::set<T>& s, const T& x) {
0226     return find(begin(s), end(s), x) != end(s);
0227   }
0228 
0229   /// Does the map @a m contain the key @a key?
0230   template <typename K, typename T>
0231   inline bool has_key(const std::map<K, T>& m, const K& key) {
0232     return m.find(key) != end(m);
0233   }
0234 
0235   /// Does the map @a m contain the value @a val?
0236   template <typename K, typename T>
0237   inline bool has_value(const std::map<K, T>& m, const T& val) {
0238     for (typename std::map<K,T>::const_iterator it = begin(m); it != end(m); ++it) {
0239       if (it->second == val) return true;
0240     }
0241     return false;
0242   }
0243 
0244   /// Get the value in map @a m with key @a key, or fall back to @a fallback
0245   template <typename K, typename T>
0246   inline const T& retrieve(const std::map<K, T>& m, const K& key, const T& fallback) {
0247     return has_key(m, key) ? m[key] : fallback;
0248   }
0249 
0250   /// Get the value in map @a m with key @a key, or fall back to @a fallback (string-value specialisation)
0251   template <typename K>
0252   inline const std::string& retrieve(const std::map<K, std::string>& m, const K& key, const std::string& fallback) {
0253     return has_key(m, key) ? m.find(key)->second : fallback;
0254   }
0255 
0256   /// Get the value in map @a m with key @a key, or fall back to @a fallback (string-key specialisation)
0257   template <typename T>
0258   inline const T& retrieve(const std::map<std::string, T>& m, const std::string& key, const T& fallback) {
0259     return has_key(m, key) ? m.find(key)->second : fallback;
0260   }
0261 
0262   /// Get the value in map @a m with key @a key, or fall back to @a fallback (string-key+value specialisation)
0263   inline const std::string& retrieve(const std::map<std::string, std::string>& m, const std::string& key, const std::string& fallback) {
0264     return has_key(m, key) ? m.find(key)->second : fallback;
0265   }  
0266   
0267   /// @}
0268 
0269 
0270 }
0271 
0272 
0273 namespace std {
0274 
0275 
0276   /// @name Container filling and merging
0277   /// @{
0278 
0279   /// Append a single item to vector @a v
0280   template <typename T>
0281   inline void operator += (std::vector<T>& v, const T& x) { v.push_back(x); }
0282 
0283   /// Append all the items from vector @a v2 to vector @a v1
0284   template <typename T>
0285   inline void operator += (std::vector<T>& v1, const std::vector<T>& v2) {
0286     for (const auto& x : v2) v1.push_back(x);
0287   }
0288 
0289   /// Create a new vector from the concatenated items in vectors @a v1 and @a v2
0290   template <typename T>
0291   inline std::vector<T> operator + (const std::vector<T>& v1, const std::vector<T>& v2) {
0292     std::vector<T> rtn(v1);
0293     rtn += v2;
0294     return rtn;
0295   }
0296 
0297 
0298   /// Merge the contents of set @a s2 into @a s1
0299   template <typename T>
0300   inline void operator += (std::set<T>& s1, const std::set<T>& s2) {
0301     for (const auto& x : s2) s1.insert(x);
0302   }
0303 
0304   /// Merge the contents of sets @a s1 and @a s2
0305   template <typename T>
0306   inline std::set<T> operator + (const std::set<T>& s1, const std::set<T>& s2) {
0307     std::set<T> rtn(s1);
0308     rtn += s2;
0309     return rtn;
0310   }
0311 
0312   /// @}
0313 
0314 
0315   /// @name Function helpers
0316   /// @{
0317 
0318   /// Get a function pointer / hash integer from an std::function
0319   template<typename T, typename... U>
0320   inline uintptr_t get_address(std::function<T(U...)> f) {
0321     typedef T(fnType)(U...);
0322     fnType ** fnPointer = f.template target<fnType*>();
0323     return (fnPointer != nullptr) ? reinterpret_cast<uintptr_t>(*fnPointer) : 0;
0324   }
0325 
0326   /// @}
0327 
0328 
0329 }
0330 
0331 #endif