#pragma once #include "Support/ADT.h" #include "Struct.h" namespace clice::refl { template struct Equal { constexpr static bool equal(const LHS& lhs, const RHS& rhs) { return lhs == rhs; } }; struct equal_t { template constexpr static bool operator() (const LHS& lhs, const RHS& rhs) { return Equal::equal(lhs, rhs); } }; constexpr inline equal_t equal; template struct Equal> { constexpr static bool equal(const std::vector& lhs, const std::vector& rhs) { if(lhs.size() != rhs.size()) { return false; } for(std::size_t i = 0; i < lhs.size(); ++i) { if(!refl::equal(lhs[i], rhs[i])) { return false; } } return true; } }; template requires (!requires(T lhs, T rhs) { { lhs == rhs } -> std::convertible_to; }) struct Equal { constexpr static bool equal(const T& lhs, const T& rhs) { return foreach(lhs, rhs, [](const auto& lhs, const auto& rhs) { return refl::equal(lhs, rhs); }); } }; template struct Less { constexpr static bool less(const LHS& lhs, const RHS& rhs) { return lhs < rhs; } }; struct less_t { template constexpr static bool operator() (const LHS& lhs, const RHS& rhs) { return Less::less(lhs, rhs); } }; constexpr inline less_t less; template struct Less> { constexpr static bool less(const std::vector& lhs, const std::vector& rhs) { if(lhs.size() != rhs.size()) { return lhs.size() < rhs.size(); } for(std::size_t i = 0; i < lhs.size(); ++i) { if(refl::less(lhs[i], rhs[i])) { return true; } } return false; } }; template requires (!requires(T lhs, T rhs) { { lhs < rhs } -> std::convertible_to; }) struct Less { constexpr static bool less(const T& lhs, const T& rhs) { bool result = false; foreach(lhs, rhs, [&](const auto& lhs, const auto& rhs) { /// return false to break the loop. if(refl::less(lhs, rhs)) { result = true; return false; } if(refl::less(rhs, lhs)) { result = false; return false; } /// continue the loop. return true; }); return result; } }; } // namespace clice::refl