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