TRIQS/nda 1.3.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
100 template <typename T, template <typename...> class TMPLT>
102
111 template <typename T, typename... Us>
112 concept AnyOf = is_any_of<T, Us...>;
113
115
116 namespace mem {
117
122
124 // Forward declarations.
125 struct blk_t;
126 enum class AddressSpace;
128
140 template <typename A>
141 concept Allocator = requires(A &a) {
142 { a.allocate(size_t{}) } noexcept -> std::same_as<blk_t>;
143 { a.allocate_zero(size_t{}) } noexcept -> std::same_as<blk_t>;
144 { a.deallocate(std::declval<blk_t>()) } noexcept;
145 { A::address_space } -> std::same_as<AddressSpace const &>;
146 };
147
158 template <typename H, typename T = typename std::remove_cvref_t<H>::value_type>
159 concept Handle = requires(H const &h) {
160 requires std::is_same_v<typename std::remove_cvref_t<H>::value_type, T>;
161 { h.is_null() } noexcept -> std::same_as<bool>;
162 { h.data() } noexcept -> std::same_as<T *>;
163 { H::address_space } -> std::same_as<AddressSpace const &>;
164 };
165
175 template <typename H, typename T = typename std::remove_cvref_t<H>::value_type>
176 concept OwningHandle = Handle<H, T> and requires(H const &h) {
177 requires not std::is_const_v<typename std::remove_cvref_t<H>::value_type>;
178 { h.size() } noexcept -> std::same_as<long>;
179 };
180
182
183 } // namespace mem
184
189
204 template <typename A>
205 concept Array = requires(A const &a) {
206 { a.shape() } -> StdArrayOfLong;
207 { a.size() } -> std::same_as<long>;
209 };
210
222 template <typename A, typename A_t = std::remove_cvref_t<A>>
223 concept MemoryArray = Array<A> && requires(A &a) {
224 typename A_t::storage_t;
226 typename A_t::value_type;
227 {
228 a.data()
229 } -> std::same_as<std::conditional_t<std::is_const_v<std::remove_reference_t<A>> || std::is_const_v<typename A_t::value_type>,
231 { a.indexmap().strides() } -> StdArrayOfLong;
232 };
233
240 template <typename A, int R>
241 concept ArrayOfRank = Array<A> and (get_rank<A> == R);
242
249 template <typename A, int R>
251
256 template <typename AS>
258
264 template <typename M>
266
272 template <typename V>
274
280 template <typename M>
282
288 template <typename V>
290
299 template <typename A, typename B>
300 concept ArrayInitializer = requires(A const &a) {
301 { a.shape() } -> StdArrayOfLong;
302 typename std::remove_cvref_t<A>::value_type;
303 requires MemoryArray<B> && requires(B &b) { a.invoke(b); }; // FIXME not perfect: it should accept any layout ??
304 };
305
306 // FIXME : We should not need this ... Only used once...
313 template <typename A, typename U>
314 concept HasValueTypeConstructibleFrom = Array<A> and (std::is_constructible_v<U, get_value_t<A>>);
315
317
318} // namespace nda
True iif T is same_as any of the Us.
Definition concepts.hpp:112
Check if a given type satisfies the array concept.
Definition concepts.hpp:205
Check if a given type satisfies the array initializer concept for a given nda::MemoryArray type.
Definition concepts.hpp:300
Check if a given type is an nda::Array of a certain rank.
Definition concepts.hpp:241
Check if if a given type is either an nda::Array or an nda::Scalar.
Definition concepts.hpp:257
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 complex type.
Definition concepts.hpp:90
Check if a given type is constructible from the value type of a given nda::Array type.
Definition concepts.hpp:314
Check if a given type is an instantiation of some other template type.
Definition concepts.hpp:101
Check if a given type is a matrix, i.e. an nda::ArrayOfRank<2>.
Definition concepts.hpp:265
Check if a given type satisfies the memory array concept.
Definition concepts.hpp:223
Check if a given type is an nda::MemoryArray of a certain rank.
Definition concepts.hpp:250
Check if a given type is a memory matrix, i.e. an nda::MemoryArrayOfRank<2>.
Definition concepts.hpp:281
Check if a given type is a memory vector, i.e. an nda::MemoryArrayOfRank<1>.
Definition concepts.hpp:289
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:273
Check if a given type satisfies the allocator concept.
Definition concepts.hpp:141
Check if a given type satisfies the memory handle concept.
Definition concepts.hpp:159
Check if a given type satisfies the owning memory handle concept.
Definition concepts.hpp:176
constexpr int get_rank
Constexpr variable that specifies the rank of an nda::Array or of a contiguous 1-dimensional range.
Definition traits.hpp:126
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:182
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.