// 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 #define ROCPROFILER_IMPORT_TEMPLATE2(template_name) #define ROCPROFILER_IMPORT_TEMPLATE1(template_name) // Import a 2-type-argument operator template into boost (if necessary) and // provide a specialization of 'is_chained_base<>' for it. #define ROCPROFILER_OPERATOR_TEMPLATE2(template_name2) \ ROCPROFILER_IMPORT_TEMPLATE2(template_name2) \ template \ struct is_chained_base<::rocprofiler::common::container::template_name2> \ { \ using value = ::rocprofiler::common::container::true_t; \ }; // Import a 1-type-argument operator template into boost (if necessary) and // provide a specialization of 'is_chained_base<>' for it. #define ROCPROFILER_OPERATOR_TEMPLATE1(template_name1) \ ROCPROFILER_IMPORT_TEMPLATE1(template_name1) \ template \ struct is_chained_base<::rocprofiler::common::container::template_name1> \ { \ using value = ::rocprofiler::common::container::true_t; \ }; #define ROCPROFILER_OPERATOR_TEMPLATE(template_name) \ template , \ typename O = typename is_chained_base::value> \ struct template_name; \ \ template \ struct template_name : template_name##2 < T \ , U \ , B > \ {}; \ \ template \ struct template_name, true_t> : template_name##1 < T \ , U > \ {}; \ \ template \ struct template_name : template_name##1 < T \ , B > \ {}; \ \ template \ struct is_chained_base> \ { \ using value = ::rocprofiler::common::container::true_t; \ }; \ \ ROCPROFILER_OPERATOR_TEMPLATE2(template_name##2) \ ROCPROFILER_OPERATOR_TEMPLATE1(template_name##1) #define ROCPROFILER_BINARY_OPERATOR_COMMUTATIVE(NAME, OP) \ template > \ struct NAME##2 : B{friend T operator OP(T lhs, const U& rhs){return lhs OP## = rhs; \ } \ friend T operator OP(const U& lhs, T rhs) { return rhs OP## = lhs; } \ } \ ; \ \ template > \ struct NAME##1 : B{friend T operator OP(T lhs, const T& rhs){return lhs OP## = rhs; \ } \ } \ ; #define ROCPROFILER_BINARY_OPERATOR_NON_COMMUTATIVE(NAME, OP) \ template > \ struct NAME##2 : B{friend T operator OP(T lhs, const U& rhs){return lhs OP## = rhs; \ } \ } \ ; namespace rocprofiler { namespace common { namespace container { struct true_t {}; struct false_t {}; template class empty_base {}; template struct is_chained_base { using value = true_t; }; ROCPROFILER_BINARY_OPERATOR_COMMUTATIVE(addable, +) ROCPROFILER_BINARY_OPERATOR_NON_COMMUTATIVE(subtractable, -) ROCPROFILER_OPERATOR_TEMPLATE(addable) template > struct incrementable : B { friend T operator++(T& x, int) { incrementable_type nrv(x); ++x; return nrv; } private: // The use of this typedef works around a Borland bug typedef T incrementable_type; }; template > struct decrementable : B { friend T operator--(T& x, int) { decrementable_type nrv(x); --x; return nrv; } private: // The use of this typedef works around a Borland bug typedef T decrementable_type; }; template > struct dereferenceable : B { P operator->() const { return ::std::addressof(*static_cast(*this)); } }; template > struct indexable : B { R operator[](N n) const { return *(static_cast(*this) + n); } }; template > struct equality_comparable1 : B { friend bool operator!=(const T& x, const T& y) { return !static_cast(x == y); } }; template > struct input_iteratable : equality_comparable1>> {}; template > struct output_iteratable : incrementable {}; template > struct forward_iteratable : input_iteratable {}; template > struct bidirectional_iteratable : forward_iteratable> {}; // template > // struct subtractable2; template > struct additive2 : addable2> {}; template > struct less_than_comparable1 : B { friend bool operator>(const T& x, const T& y) { return y < x; } friend bool operator<=(const T& x, const T& y) { return !static_cast(y < x); } friend bool operator>=(const T& x, const T& y) { return !static_cast(x < y); } }; // To avoid repeated derivation from equality_comparable, // which is an indirect base typename of bidirectional_iterable, // random_access_iteratable must not be derived from totally_ordered1 // but from less_than_comparable1 only. (Helmut Zeisel, 02-Dec-2001) template > struct random_access_iteratable : bidirectional_iteratable>>> {}; template struct iterator_helper { using iterator_category = CategoryT; using value_type = Tp; using difference_type = DistanceT; using pointer = PointerT; using reference = ReferenceT; }; template struct random_access_iterator_helper : random_access_iteratable> { friend D requires_difference_operator(const T& x, const T& y) { return x - y; } }; // random_access_iterator_helper } // namespace container } // namespace common } // namespace rocprofiler