Files
rocm-systems/source/lib/common/container/operators.hpp
T
Benjamin Welton 75264b5587 Clang-tidy performance error fixes (#411)
Fixes perf errors + ambiguity issues raised by clang-tidy
2024-01-26 10:19:18 -08:00

240 строки
11 KiB
C++

// MIT License
//
// Copyright (c) 2022 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 <iterator>
#include <type_traits>
#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 <typename T, typename U, typename B> \
struct is_chained_base<::rocprofiler::common::container::template_name2<T, U, B>> \
{ \
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 <typename T, typename B> \
struct is_chained_base<::rocprofiler::common::container::template_name1<T, B>> \
{ \
using value = ::rocprofiler::common::container::true_t; \
};
#define ROCPROFILER_OPERATOR_TEMPLATE(template_name) \
template <typename T, \
typename U = T, \
typename B = empty_base<T>, \
typename O = typename is_chained_base<U>::value> \
struct template_name; \
\
template <typename T, typename U, typename B> \
struct template_name<T, U, B, false_t> : template_name##2 < T \
, U \
, B > \
{}; \
\
template <typename T, typename U> \
struct template_name<T, U, empty_base<T>, true_t> : template_name##1 < T \
, U > \
{}; \
\
template <typename T, typename B> \
struct template_name<T, T, B, false_t> : template_name##1 < T \
, B > \
{}; \
\
template <typename T, typename U, typename B, typename O> \
struct is_chained_base<template_name<T, U, B, O>> \
{ \
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 <typename T, typename U, typename B = empty_base<T>> \
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 <typename T, typename B = empty_base<T>> \
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 <typename T, typename U, typename B = empty_base<T>> \
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 <typename T>
class empty_base
{};
template <typename T>
struct is_chained_base
{
using value = true_t;
};
ROCPROFILER_BINARY_OPERATOR_COMMUTATIVE(addable, +)
ROCPROFILER_BINARY_OPERATOR_NON_COMMUTATIVE(subtractable, -)
ROCPROFILER_OPERATOR_TEMPLATE(addable)
template <typename T, typename B = empty_base<T>>
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 <typename T, typename B = empty_base<T>>
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 <typename T, typename P, typename B = empty_base<T>>
struct dereferenceable : B
{
P operator->() const { return ::std::addressof(*static_cast<const T&>(*this)); }
};
template <typename T, typename N, typename R, typename B = empty_base<T>>
struct indexable : B
{
R operator[](N n) const { return *(static_cast<const T&>(*this) + n); }
};
template <typename T, typename B = empty_base<T>>
struct equality_comparable1 : B
{
friend bool operator!=(const T& x, const T& y) { return !static_cast<bool>(x == y); }
};
template <typename T, typename P, typename B = empty_base<T>>
struct input_iteratable : equality_comparable1<T, incrementable<T, dereferenceable<T, P, B>>>
{};
template <typename T, typename B = empty_base<T>>
struct output_iteratable : incrementable<T, B>
{};
template <typename T, typename P, typename B = empty_base<T>>
struct forward_iteratable : input_iteratable<T, P, B>
{};
template <typename T, typename P, typename B = empty_base<T>>
struct bidirectional_iteratable : forward_iteratable<T, P, decrementable<T, B>>
{};
// template <typename T, typename U, typename B = empty_base<T>>
// struct subtractable2;
template <typename T, typename U, typename B = empty_base<T>>
struct additive2 : addable2<T, U, subtractable2<T, U, B>>
{};
template <typename T, typename B = empty_base<T>>
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<bool>(y < x); }
friend bool operator>=(const T& x, const T& y) { return !static_cast<bool>(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 <typename T, typename P, typename D, typename R, typename B = empty_base<T>>
struct random_access_iteratable
: bidirectional_iteratable<T, P, less_than_comparable1<T, additive2<T, D, indexable<T, D, R, B>>>>
{};
template <typename CategoryT,
typename Tp,
typename DistanceT = std::ptrdiff_t,
typename PointerT = Tp*,
typename ReferenceT = Tp&>
struct iterator_helper
{
using iterator_category = CategoryT;
using value_type = Tp;
using difference_type = DistanceT;
using pointer = PointerT;
using reference = ReferenceT;
};
template <typename T, typename V, typename D = std::ptrdiff_t, typename P = V*, typename R = V&>
struct random_access_iterator_helper
: random_access_iteratable<T, P, D, R, iterator_helper<std::random_access_iterator_tag, V, D, P, R>>
{
friend D requires_difference_operator(const T& x, const T& y) { return x - y; }
}; // random_access_iterator_helper
} // namespace container
} // namespace common
} // namespace rocprofiler