TRIQS/nda 2.0.0
Multi-dimensional array library for C++
Loading...
Searching...
No Matches
concepts.hpp
Go to the documentation of this file.
1// Copyright (c) 2020--present, The Simons Foundation
2// This file is part of TRIQS/nda and is licensed under the Apache License, Version 2.0.
3// SPDX-License-Identifier: Apache-2.0
4// See LICENSE in the root of this distribution for details.
5
10
11#pragma once
12
14#include "./traits.hpp"
15
16#include <array>
17#include <concepts>
18#include <type_traits>
19#include <utility>
20
21namespace nda {
22
27
28 namespace detail {
29
30 // Helper function declaration to check if A can be called with R long arguments.
31 template <auto... Is, typename A>
32 auto call_on_R_longs(std::index_sequence<Is...>, A const &a) -> decltype(a((long{Is})...)); // no impl needed
33
34 } // namespace detail
35
45 template <typename A, int R>
46 concept CallableWithLongs = requires(A const &a) {
47 { detail::call_on_R_longs(std::make_index_sequence<R>{}, a) };
48 };
49
50 namespace detail {
51
52 // Check if T is of type std::array<long, R> for arbitrary array sizes R.
53 template <typename T>
54 constexpr bool is_std_array_of_long_v = false;
55
56 // Specialization of nda::detail::is_std_array_of_long_v for cvref types.
57 template <typename T>
58 requires(!std::is_same_v<T, std::remove_cvref_t<T>>)
59 constexpr bool is_std_array_of_long_v<T> = is_std_array_of_long_v<std::remove_cvref_t<T>>;
60
61 // Specialization of nda::detail::is_std_array_of_long_v for std::array<long, R>.
62 template <auto R>
63 constexpr bool is_std_array_of_long_v<std::array<long, R>> = true;
64
65 } // namespace detail
66
75 template <class T>
76 concept StdArrayOfLong = detail::is_std_array_of_long_v<T>;
77
82 template <typename S>
84
89 template <typename S>
91
96 template <typename S>
97 concept FloatOrDouble = std::same_as<float, std::remove_cvref_t<S>> or std::same_as<double, std::remove_cvref_t<S>>;
98
107 template <typename T, template <typename...> class TMPLT>
109
118 template <typename T, typename... Us>
119 concept AnyOf = is_any_of<T, Us...>;
120
122
123 namespace mem {
124
129
131 // Forward declarations.
132 struct blk_t;
133 enum class AddressSpace;
135
147 template <typename A>
148 concept Allocator = requires(A &a) {
149 { a.allocate(size_t{}) } noexcept -> std::same_as<blk_t>;
150 { a.allocate_zero(size_t{}) } noexcept -> std::same_as<blk_t>;
151 { a.deallocate(std::declval<blk_t>()) } noexcept;
152 { A::address_space } -> std::same_as<AddressSpace const &>;
153 };
154
165 template <typename H, typename T = typename std::remove_cvref_t<H>::value_type>
166 concept Handle = requires(H const &h) {
167 requires std::is_same_v<typename std::remove_cvref_t<H>::value_type, T>;
168 { h.is_null() } noexcept -> std::same_as<bool>;
169 { h.data() } noexcept -> std::same_as<T *>;
170 { H::address_space } -> std::same_as<AddressSpace const &>;
171 };
172
182 template <typename H, typename T = typename std::remove_cvref_t<H>::value_type>
183 concept OwningHandle = Handle<H, T> and requires(H const &h) {
184 requires not std::is_const_v<typename std::remove_cvref_t<H>::value_type>;
185 { h.size() } noexcept -> std::same_as<long>;
186 };
187
189
190 } // namespace mem
191
196
211 template <typename A>
212 concept Array = requires(A const &a) {
213 { a.shape() } -> StdArrayOfLong;
214 { a.size() } -> std::same_as<long>;
216 };
217
229 template <typename A, typename A_t = std::remove_cvref_t<A>>
230 concept MemoryArray = Array<A> && requires(A &a) {
231 typename A_t::storage_t;
233 typename A_t::value_type;
234 {
235 a.data()
236 } -> std::same_as<std::conditional_t<std::is_const_v<std::remove_reference_t<A>> || std::is_const_v<typename A_t::value_type>,
238 { a.indexmap().strides() } -> StdArrayOfLong;
239 };
240
247 template <typename A, int R>
248 concept ArrayOfRank = Array<A> and (get_rank<A> == R);
249
256 template <typename A, int R>
258
263 template <typename AS>
265
271 template <typename M>
273
279 template <typename V>
281
287 template <typename M>
289
295 template <typename V>
297
306 template <typename A, typename B>
307 concept ArrayInitializer = requires(A const &a) {
308 { a.shape() } -> StdArrayOfLong;
309 typename std::remove_cvref_t<A>::value_type;
310 requires MemoryArray<B> && requires(B &b) { a.invoke(b); }; // FIXME not perfect: it should accept any layout ??
311 };
312
313 // FIXME : We should not need this ... Only used once...
320 template <typename A, typename U>
321 concept HasValueTypeConstructibleFrom = Array<A> and (std::is_constructible_v<U, get_value_t<A>>);
322
324
325} // namespace nda
Check if T is the same as any of the types in Us.
Definition concepts.hpp:119
Check if a given type satisfies the array concept.
Definition concepts.hpp:212
Check if a given type satisfies the array initializer concept for a given nda::MemoryArray type.
Definition concepts.hpp:307
Check if a given type is an nda::Array of a certain rank.
Definition concepts.hpp:248
Check if if a given type is either an nda::Array or an nda::Scalar.
Definition concepts.hpp:264
Check if a given type can be called with a certain number of long arguments.
Definition concepts.hpp:46
Check if a given type is either a double or std::complex type.
Definition concepts.hpp:90
Check if a given type is either a float or double type.
Definition concepts.hpp:97
Check if a given type is constructible from the value type of a given nda::Array type.
Definition concepts.hpp:321
Check if a given type is an instantiation of some other template type.
Definition concepts.hpp:108
Check if a given type is a matrix, i.e. an nda::ArrayOfRank<2>.
Definition concepts.hpp:272
Check if a given type satisfies the memory array concept.
Definition concepts.hpp:230
Check if a given type is an nda::MemoryArray of a certain rank.
Definition concepts.hpp:257
Check if a given type is a memory matrix, i.e. an nda::MemoryArrayOfRank<2>.
Definition concepts.hpp:288
Check if a given type is a memory vector, i.e. an nda::MemoryArrayOfRank<1>.
Definition concepts.hpp:296
Check if a given type is either an arithmetic or complex type.
Definition concepts.hpp:83
Check if a given type is of type std::array<long, R> for some arbitrary R.
Definition concepts.hpp:76
Check if a given type is a vector, i.e. an nda::ArrayOfRank<1>.
Definition concepts.hpp:280
Check if a given type satisfies the allocator concept.
Definition concepts.hpp:148
Check if a given type satisfies the memory handle concept.
Definition concepts.hpp:166
Check if a given type satisfies the owning memory handle concept.
Definition concepts.hpp:183
constexpr int get_rank
Constexpr variable that specifies the rank of an nda::Array or of a contiguous 1-dimensional range.
Definition traits.hpp:147
std::decay_t< decltype(get_first_element(std::declval< A const >()))> get_value_t
Get the value type of an array/view or a scalar type.
Definition traits.hpp:212
AddressSpace
Enum providing identifiers for the different memory address spaces.
constexpr bool is_instantiation_of_v
Constexpr variable that is true if type T is an instantiation of TMPLT (see nda::is_instantiation_of)...
Definition traits.hpp:49
static constexpr bool is_any_of
Constexpr variable that is true if type T is contained in the parameter pack Ts.
Definition traits.hpp:53
constexpr bool is_double_or_complex_v
Constexpr variable that is true if type T is a std::complex type or a double type.
Definition traits.hpp:88
constexpr bool is_scalar_v
Constexpr variable that is true if type S is a scalar type, i.e. arithmetic or complex.
Definition traits.hpp:69
Provides missing concepts for older compiler versions.
Provides type traits for the nda library.