TRIQS/nda 1.3.0
Multi-dimensional array library for C++
Loading...
Searching...
No Matches
utils.hpp
Go to the documentation of this file.
1// Copyright (c) 2024 Simons Foundation
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0.txt
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15// Authors: Thomas Hahn
16
22#pragma once
23
24#include <functional>
25#include <type_traits>
26
27namespace nda::clef {
28
34 namespace detail {
35
36 // Helper variable to determine if an objects of type `T` should be forced to be copied into an expression tree.
37 template <typename T>
38 constexpr bool force_copy_in_expr_impl = false;
39
40 // Helper struct to determine how a type should be stored in an expression tree.
41 template <class T>
42 struct expr_storage_impl {
43 using type = T;
44 };
45
46 // Specialization of expr_storage_impl for lvalue references.
47 template <class T>
48 struct expr_storage_impl<T &>
49 : std::conditional<force_copy_in_expr_impl<std::remove_const_t<T>>, std::remove_const_t<T>, std::reference_wrapper<T>> {};
50
51 // Specialization of expr_storage_impl for rvalue references.
52 template <class T>
53 struct expr_storage_impl<T &&> {
54 using type = T;
55 };
56
57 // Specialization of expr_storage_impl for const rvalue references.
58 template <class T>
59 struct expr_storage_impl<const T &&> {
60 using type = T;
61 };
62
63 // Specialization of expr_storage_impl for const types.
64 template <class T>
65 struct expr_storage_impl<const T> {
66 using type = T;
67 };
68
69 // Type used to encode which placeholder indices are used in an expression.
70 using ull_t = unsigned long long;
71
72 // Type trait that determines the set of placeholders in a parameter pack.
73 template <typename... Ts>
74 struct ph_set;
75
76 // Specialization of ph_set for parameter packs containing at least one type.
77 template <typename T0, typename... Ts>
78 struct ph_set<T0, Ts...> {
79 static constexpr ull_t value = ph_set<T0>::value | ph_set<Ts...>::value;
80 };
81
82 // Specialization of ph_set for a single non-lazy type.
83 template <typename T>
84 struct ph_set<T> {
85 static constexpr ull_t value = 0;
86 };
87
88 // Filter out certain placeholders given an integer value encoded by ph_set.
89 template <ull_t N, int... Is>
90 struct ph_filter;
91
92 // Specialization of ph_filter for at least one placeholder to filter out.
93 template <ull_t N, int I0, int... Is>
94 struct ph_filter<N, I0, Is...> {
95 static constexpr ull_t value = ph_filter<N, Is...>::value & (~(1ull << I0));
96 };
97
98 // Specialization of ph_filter for no placeholders to filter out.
99 template <ull_t N>
100 struct ph_filter<N> {
101 static constexpr ull_t value = N;
102 };
103
104 // Helper variable to determine if a type `T` is lazy.
105 template <typename T>
106 constexpr bool is_lazy_impl = false;
107
108 // Specialization of is_lazy_impl for cvref types.
109 template <typename T>
110 requires(!std::is_same_v<T, std::remove_cvref_t<T>>)
111 constexpr bool is_lazy_impl<T> = is_lazy_impl<std::remove_cvref_t<T>>;
112
113 // Helper variable to determine if a type `T` is an make_fun_impl type.
114 template <typename T>
115 inline constexpr bool is_function_impl = false;
116
117 // An erroneous diagnostics in gcc: i0 is indeed used. We silence it.
118#if defined(__GNUC__) and not defined(__clang__)
119#pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
120#endif
121
122 // Check if all given integers are different.
123 template <typename... Is>
124 constexpr bool all_different(int i0, Is... is) {
125 return (((is - i0) * ... * 1) != 0);
126 }
127
128#if defined(__GNUC__) and not defined(__clang__)
129#pragma GCC diagnostic pop
130#endif
131
132 } // namespace detail
133
135 template <typename T>
136 constexpr bool force_copy_in_expr = detail::force_copy_in_expr_impl<T>;
137
147 template <class T>
148 using expr_storage_t = typename detail::expr_storage_impl<T>::type;
149
151 template <typename T>
152 constexpr bool is_lazy = detail::is_lazy_impl<T>;
153
155 template <typename... Ts>
156 constexpr bool is_any_lazy = (is_lazy<Ts> or ...);
157
159 template <typename... Ts>
160 constexpr bool is_clef_expression = is_any_lazy<Ts...>;
161
163 template <typename T>
164 inline constexpr bool is_function = detail::is_function_impl<T>;
165
168} // namespace nda::clef
constexpr bool is_clef_expression
Alias template for nda::clef::is_any_lazy.
Definition utils.hpp:160
constexpr bool is_lazy
Constexpr variable that is true if the type T is a lazy type.
Definition utils.hpp:152
typename detail::expr_storage_impl< T >::type expr_storage_t
Type trait to determine how a type should be stored in an expression tree, i.e. either by reference o...
Definition utils.hpp:148
constexpr bool force_copy_in_expr
Constexpr variable that is true if objects of type T should be forced to be copied into an expression...
Definition utils.hpp:136
constexpr bool is_function
Constexpr variable that is true if the type T is an nda::clef::make_fun_impl type.
Definition utils.hpp:164
constexpr bool is_any_lazy
Constexpr variable that is true if any of the given types is lazy.
Definition utils.hpp:156