/******************************************************************************* * * MIT License * * Copyright (C) 2022-2025 Advanced Micro Devices, Inc. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * *******************************************************************************/ #pragma once #include #include namespace TensileLite { /** * \ingroup Utilities * \defgroup Comparison Comparison */ /** * \addtogroup Comparison * @{ */ /** * Lexicographically compares two lists of values, one pair of values at a * time. * * \return -1: The first list is lesser. * 1: The second list is lesser. * 0: The lists are equal. */ inline int LexicographicCompare() { return 0; } template inline int LexicographicCompare(A const& lhs, A const& rhs) { if(lhs < rhs) return -1; if(lhs > rhs) return 1; return 0; } template > inline int LexicographicCompare(A const& lhs, A const& rhs, Args const&... rest) { if(lhs < rhs) return -1; if(lhs > rhs) return 1; return LexicographicCompare(rest...); } /** * @brief Traits class which enables comparison operators to be implemented * based on a `compare()` function. * * Specializations must implement a `compare(lhs, rhs)` function which returns: * - -1: lhs is lesser * - 0: values are equal * - 1: rhs is lesser */ template struct Comparison { enum { implemented = false }; }; template ::implemented>::type> inline bool operator==(T const& lhs, U const& rhs) { return Comparison::compare(lhs, rhs) == 0; } template ::implemented>::type> inline bool operator!=(T const& lhs, U const& rhs) { return Comparison::compare(lhs, rhs) != 0; } template ::implemented>::type> inline bool operator<(T const& lhs, U const& rhs) { return Comparison::compare(lhs, rhs) < 0; } template ::implemented>::type> inline bool operator<=(T const& lhs, U const& rhs) { return Comparison::compare(lhs, rhs) <= 0; } template ::implemented>::type> inline bool operator>(T const& lhs, U const& rhs) { return Comparison::compare(lhs, rhs) > 0; } template ::implemented>::type> inline bool operator>=(T const& lhs, U const& rhs) { return Comparison::compare(lhs, rhs) >= 0; } /** * Combines a number of already-hashed values. */ template inline size_t combine_hashes(size_t a, Ts... rest) { return combine_hashes(a, combine_hashes(rest...)); } template <> inline size_t combine_hashes(size_t a, size_t b) { return b ^ (a + 0x9b9773e99e3779b9 + (b << 6) + (b >> 2)); } template inline size_t hash_combine(T const& val) { return std::hash()(val); } template inline size_t hash_combine(T const& val, Ts const&... more) { size_t mine = std::hash()(val); size_t rest = hash_combine(more...); return combine_hashes(mine, rest); } template inline size_t hash_combine_iter(Iter begin, Iter end) { size_t rv = 0; while(begin != end) { rv = combine_hashes(hash_combine(*begin), rv); begin++; } return rv; } template struct tuple_hash { using MyTuple = std::tuple; using TypeN = typename std::tuple_element::type; static size_t apply(std::tuple const& tup) { size_t mine = std::hash()(std::get(tup)); size_t rest = tuple_hash::apply(tup); return combine_hashes(mine, rest); } }; template struct tuple_hash<0, Types...> { using MyTuple = std::tuple; using Type0 = typename std::tuple_element<0, MyTuple>::type; static size_t apply(std::tuple const& tup) { return std::hash()(std::get<0>(tup)); } }; template size_t hash_tuple(std::tuple const& tup) { return tuple_hash::apply(tup); } /** * @} */ } // namespace TensileLite namespace std { template struct hash> { inline size_t operator()(tuple const& tup) const { return TensileLite::hash_tuple(tup); } }; } // namespace std