File indexing completed on 2024-04-06 12:03:54
0001 #ifndef DataFormats_Common_interface_StdArray_h
0002 #define DataFormats_Common_interface_StdArray_h
0003
0004 #include <array>
0005 #include <cstddef>
0006 #include <iostream>
0007 #include <iterator>
0008
0009 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
0010
0011 namespace edm {
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 namespace detail {
0025 template <typename T, std::size_t N>
0026 class StdArrayTrait {
0027 public:
0028 using array_type = T[N];
0029 };
0030
0031 template <typename T>
0032 class StdArrayTrait<T, 0> {
0033 public:
0034 struct array_type {};
0035 };
0036 }
0037
0038 template <typename T, std::size_t N>
0039 class StdArray {
0040 public:
0041
0042
0043 using value_type = T;
0044 using size_type = std::size_t;
0045 using difference_type = std::ptrdiff_t;
0046 using reference = value_type&;
0047 using const_reference = value_type const&;
0048 using pointer = value_type*;
0049 using const_pointer = const value_type*;
0050 using iterator = pointer;
0051 using const_iterator = const_pointer;
0052 using reverse_iterator = std::reverse_iterator<iterator>;
0053 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
0054
0055
0056
0057
0058 constexpr StdArray& operator=(std::array<T, N> const& init) {
0059 for (size_type i = 0; i < N; ++i) {
0060 data_[i] = init[i];
0061 }
0062 return *this;
0063 }
0064
0065
0066 constexpr StdArray& operator=(std::array<T, N>&& init) {
0067 for (size_type i = 0; i < N; ++i) {
0068 data_[i] = std::move(init[i]);
0069 }
0070 return *this;
0071 }
0072
0073
0074 constexpr operator std::array<T, N>() const {
0075 std::array<T, N> copy;
0076 for (size_type i = 0; i < N; ++i) {
0077 copy[i] = data_[i];
0078 }
0079 return copy;
0080 }
0081
0082
0083
0084
0085
0086 constexpr reference at(size_type pos) {
0087 if (pos >= N)
0088 abort();
0089 return data_[pos];
0090 }
0091 constexpr const_reference at(size_type pos) const {
0092 if (pos >= N)
0093 abort();
0094 return data_[pos];
0095 }
0096
0097
0098 constexpr reference operator[](size_type pos) { return data_[pos]; }
0099 constexpr const_reference operator[](size_type pos) const { return data_[pos]; }
0100
0101
0102
0103 constexpr reference front() {
0104 if constexpr (N == 0)
0105 abort();
0106 return data_[0];
0107 }
0108 constexpr const_reference front() const {
0109 if constexpr (N == 0)
0110 abort();
0111 return data_[0];
0112 }
0113
0114
0115
0116 constexpr reference back() {
0117 if constexpr (N == 0)
0118 abort();
0119 return data_[N - 1];
0120 }
0121 constexpr const_reference back() const {
0122 if constexpr (N == 0)
0123 abort();
0124 return data_[N - 1];
0125 }
0126
0127
0128
0129
0130 constexpr pointer data() noexcept {
0131 if constexpr (N != 0)
0132 return data_;
0133 else
0134 return nullptr;
0135 }
0136 constexpr const_pointer data() const noexcept {
0137 if constexpr (N != 0)
0138 return data_;
0139 else
0140 return nullptr;
0141 }
0142
0143
0144
0145
0146
0147 constexpr iterator begin() noexcept {
0148 if constexpr (N != 0)
0149 return data_;
0150 else
0151 return nullptr;
0152 }
0153 constexpr const_iterator begin() const noexcept {
0154 if constexpr (N != 0)
0155 return data_;
0156 else
0157 return nullptr;
0158 }
0159 constexpr const_iterator cbegin() const noexcept {
0160 if constexpr (N != 0)
0161 return data_;
0162 else
0163 return nullptr;
0164 }
0165
0166
0167
0168 constexpr iterator end() noexcept {
0169 if constexpr (N != 0)
0170 return data_ + N;
0171 else
0172 return nullptr;
0173 }
0174 constexpr const_iterator end() const noexcept {
0175 if constexpr (N != 0)
0176 return data_ + N;
0177 else
0178 return nullptr;
0179 }
0180 constexpr const_iterator cend() const noexcept {
0181 if constexpr (N != 0)
0182 return data_ + N;
0183 else
0184 return nullptr;
0185 }
0186
0187
0188
0189 constexpr reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
0190 constexpr const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); }
0191 constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); }
0192
0193
0194
0195 constexpr reverse_iterator rend() noexcept { return reverse_iterator(begin()); }
0196 constexpr const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); }
0197 constexpr const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); }
0198
0199
0200
0201
0202 constexpr bool empty() const noexcept { return N == 0; }
0203
0204
0205 constexpr size_type size() const noexcept { return N; }
0206
0207
0208 constexpr size_type max_size() const noexcept { return N; }
0209
0210
0211
0212
0213 constexpr void fill(const T& value) {
0214 for (size_type i = 0; i < N; ++i)
0215 data_[i] = N;
0216 }
0217
0218
0219 constexpr void swap(StdArray& other) noexcept(std::is_nothrow_swappable_v<T>) {
0220 if (&other == this)
0221 return;
0222 for (size_type i = 0; i < N; ++i)
0223 std::swap(data_[i], other[i]);
0224 }
0225
0226
0227
0228
0229 typename detail::StdArrayTrait<T, N>::array_type data_;
0230
0231
0232 CMS_CLASS_VERSION(3);
0233 };
0234
0235
0236 template <class T, class U, std::size_t N>
0237 constexpr bool operator==(StdArray<T, N> const& lhs, StdArray<U, N> const& rhs) {
0238 for (std::size_t i = 0; i < N; ++i) {
0239 if (lhs[i] != rhs[i])
0240 return false;
0241 }
0242 return true;
0243 }
0244
0245
0246 template <typename T, std::size_t N>
0247 std::ostream& operator<<(std::ostream& out, edm::StdArray<T, N> const& array) {
0248 out << "{";
0249 if constexpr (N > 0) {
0250 out << " " << array[0];
0251 }
0252 for (std::size_t i = 1; i < N; ++i)
0253 out << ", " << array[i];
0254 out << " }";
0255 return out;
0256 }
0257
0258 }
0259
0260 #endif