1 #pragma once 2 3 #ifdef PAJLADA_BOOST_ANY_SUPPORT 4 #include <boost/any.hpp> 5 #endif 6 7 #include <map> 8 #include <vector> 9 10 namespace pajlada { 11 12 template <typename Type> 13 struct IsEqual { 14 static bool getpajlada::IsEqual15 get(const Type &lhs, const Type &rhs) 16 { 17 return lhs == rhs; 18 } 19 }; 20 21 template <typename Type1, typename Type2> 22 struct IsEqual<std::pair<Type1, Type2>> { 23 static bool getpajlada::IsEqual24 get(const std::pair<Type1, Type2> &lhs, const std::pair<Type1, Type2> &rhs) 25 { 26 return IsEqual<Type1>::get(lhs.first, rhs.first) && 27 IsEqual<Type2>::get(lhs.second, rhs.second); 28 } 29 }; 30 31 #ifdef PAJLADA_BOOST_ANY_SUPPORT 32 template <> 33 struct IsEqual<boost::any> { 34 static bool getpajlada::IsEqual35 get(const boost::any &lhs, const boost::any &rhs) 36 { 37 // two boost::any cannot be safely compared to each other, so we only consider them equal if both are empty 38 return (lhs.empty() && rhs.empty()); 39 } 40 }; 41 #endif 42 43 template <typename KeyType, typename ValueType> 44 struct IsEqual<std::map<KeyType, ValueType>> { 45 static bool getpajlada::IsEqual46 get(const std::map<KeyType, ValueType> &lhs, 47 const std::map<KeyType, ValueType> &rhs) 48 { 49 if (lhs.size() != rhs.size()) { 50 return false; 51 } 52 53 return std::equal(lhs.begin(), lhs.end(), rhs.begin()); 54 } 55 }; 56 57 #ifdef PAJLADA_BOOST_ANY_SUPPORT 58 template <typename KeyType> 59 struct IsEqual<std::map<KeyType, boost::any>> { 60 static bool getpajlada::IsEqual61 get(const std::map<KeyType, boost::any> &lhs, 62 const std::map<KeyType, boost::any> &rhs) 63 { 64 if (lhs.size() != rhs.size()) { 65 return false; 66 } 67 68 for (const auto &p : lhs) { 69 auto rit = rhs.find(p.first); 70 71 if (rit == rhs.end()) { 72 return false; 73 } 74 75 if (!IsEqual<boost::any>::get(p.second, rit->second)) { 76 return false; 77 } 78 } 79 80 return true; 81 } 82 }; 83 #endif 84 85 template <typename ValueType> 86 struct IsEqual<std::vector<ValueType>> { 87 static bool getpajlada::IsEqual88 get(const std::vector<ValueType> &lhs, const std::vector<ValueType> &rhs) 89 { 90 if (lhs.size() != rhs.size()) { 91 return false; 92 } 93 94 return std::equal(lhs.begin(), lhs.end(), rhs.begin()); 95 } 96 }; 97 98 #ifdef PAJLADA_BOOST_ANY_SUPPORT 99 template <> 100 struct IsEqual<std::vector<boost::any>> { 101 static bool getpajlada::IsEqual102 get(const std::vector<boost::any> &lhs, const std::vector<boost::any> &rhs) 103 { 104 if (lhs.size() != rhs.size()) { 105 return false; 106 } 107 108 auto lit = lhs.begin(); 109 auto rit = rhs.begin(); 110 111 for (; lit != lhs.begin(); ++lit, ++rit) { 112 if (rit == rhs.end()) { 113 return false; 114 } 115 116 if (!IsEqual<boost::any>::get(*lit, *rit)) { 117 return false; 118 } 119 } 120 121 return true; 122 } 123 }; 124 #endif 125 126 } // namespace pajlada 127