rivet is hosted by Hepforge, IPPP Durham
RivetSTL.hh
Go to the documentation of this file.
00001 #ifndef RIVET_RivetSTL_HH
00002 #define RIVET_RivetSTL_HH
00003 
00004 #include <string>
00005 #include <vector>
00006 #include <set>
00007 #include <list>
00008 #include <map>
00009 #include <utility>
00010 #include <algorithm>
00011 #include <type_traits>
00012 #include <stdexcept>
00013 #include <cassert>
00014 #include <memory>
00015 #include <typeinfo>
00016 #include <sstream>
00017 #include <fstream>
00018 #include <iostream>
00019 #include <iomanip>
00020 #include <cmath>
00021 #include <limits>
00022 
00023 
00024 #ifndef foreach
00025 /// @decl A foreach macro for backward compatibility with BOOST_FOREACH
00026 #define foreach(value, container) for (value : container)
00027 #endif
00028 
00029 
00030 namespace Rivet {
00031 
00032 
00033   /// We implicitly use STL entities in the Rivet namespace
00034   using namespace std;
00035 
00036 
00037   /// @name Streaming containers as string reps
00038   /// @todo Make these named toStr rather than operator<<
00039   /// @todo Make these generic to any iterable
00040   //@{
00041 
00042   /// Convenient function for streaming out vectors of any streamable object.
00043   template<typename T>
00044   inline std::ostream& operator<<(std::ostream& os, const std::vector<T>& vec) {
00045     os << "[ ";
00046     for (size_t i=0; i<vec.size(); ++i) {
00047       os << vec[i] << " ";
00048     }
00049     os << "]";
00050     return os;
00051   }
00052 
00053   /// Convenient function for streaming out lists of any streamable object.
00054   template<typename T>
00055   inline std::ostream& operator<<(std::ostream& os, const std::list<T>& vec) {
00056     os << "[ ";
00057     for (size_t i=0; i<vec.size(); ++i) {
00058       os << vec[i] << " ";
00059     }
00060     os << "]";
00061     return os;
00062   }
00063 
00064   //@}
00065 
00066 
00067   /// @name Boolean-return container searching
00068   //@{
00069 
00070   /// @todo Use SFINAE, Boost.Range, or other template trickery for more generic container matching?
00071 
00072   /// Does @a s contain @a sub as a substring?
00073   inline bool contains(const std::string& s, const std::string& sub) {
00074     return s.find(sub) != string::npos;
00075   }
00076 
00077   /// Does the vector @a v contain @a x?
00078   template <typename T>
00079   inline bool contains(const std::vector<T>& v, const T& x) {
00080     return find(v.begin(), v.end(), x) != v.end();
00081   }
00082 
00083   /// Does the list @a l contain @a x?
00084   template <typename T>
00085   inline bool contains(const std::list<T>& l, const T& x) {
00086     return find(l.begin(), l.end(), x) != l.end();
00087   }
00088 
00089   /// Does the set @a s contain @a x?
00090   template <typename T>
00091   inline bool contains(const std::set<T>& s, const T& x) {
00092     return find(s.begin(), s.end(), x) != s.end();
00093   }
00094 
00095   /// Does the map @a m contain the key @a key?
00096   template <typename K, typename T>
00097   inline bool has_key(const std::map<K, T>& m, const K& key) {
00098     return m.find(key) != m.end();
00099   }
00100 
00101   /// Does the map @a m contain the value @a val?
00102   template <typename K, typename T>
00103   inline bool has_value(const std::map<K, T>& m, const T& val) {
00104     for (typename std::map<K,T>::const_iterator it = m.begin(); it != m.end(); ++it) {
00105       if (it->second == val) return true;
00106     }
00107     return false;
00108   }
00109 
00110   //@}
00111 
00112 
00113 }
00114 
00115 namespace std {
00116 
00117 
00118   /// @name Container filling and merging
00119   //@{
00120 
00121   /// Append a single item to vector @a v
00122   template <typename T>
00123   inline void operator+=(std::vector<T>& v, const T& x) { v.push_back(x); }
00124 
00125   /// Append all the items from vector @a v2 to vector @a v1
00126   template <typename T>
00127   inline void operator+=(std::vector<T>& v1, const std::vector<T>& v2) {
00128     for (const auto& x : v2) v1.push_back(x);
00129   }
00130 
00131   /// Create a new vector from the concatenated items in vectors @a v1 and @a v2
00132   template <typename T>
00133   inline std::vector<T> operator+(const std::vector<T>& v1, const std::vector<T>& v2) {
00134     std::vector<T> rtn(v1);
00135     rtn += v2;
00136     return rtn;
00137   }
00138 
00139 
00140   /// Merge the contents of set @a s2 into @a s1
00141   template <typename T>
00142   inline void operator+=(std::set<T>& s1, const std::set<T>& s2) {
00143     for (const auto& x : s2) s1.insert(x);
00144   }
00145 
00146   /// Merge the contents of sets @a s1 and @a s2
00147   template <typename T>
00148   inline std::set<T> operator+(const std::set<T>& s1, const std::set<T>& s2) {
00149     std::set<T> rtn(s1);
00150     rtn += s2;
00151     return rtn;
00152   }
00153 
00154   //@}
00155 
00156 
00157   /// @name Function helpers
00158   //@{
00159 
00160   /// Get a function pointer / hash integer from an std::function
00161   template<typename T, typename... U>
00162   inline size_t get_address(std::function<T(U...)> f) {
00163     typedef T(fnType)(U...);
00164     fnType ** fnPointer = f.template target<fnType*>();
00165     return (fnPointer != nullptr) ? reinterpret_cast<size_t>(*fnPointer) : 0;
00166   }
00167 
00168   //@}
00169 
00170 
00171 }
00172 
00173 #endif