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--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
13#include <functional>
14#include <type_traits>
15
16namespace nda::clef {
17
22
23 namespace detail {
24
25 // Helper variable to determine if an objects of type `T` should be forced to be copied into an expression tree.
26 template <typename T>
27 constexpr bool force_copy_in_expr_impl = false;
28
29 // Helper struct to determine how a type should be stored in an expression tree.
30 template <class T>
31 struct expr_storage_impl {
32 using type = T;
33 };
34
35 // Specialization of expr_storage_impl for lvalue references.
36 template <class T>
37 struct expr_storage_impl<T &>
38 : std::conditional<force_copy_in_expr_impl<std::remove_const_t<T>>, std::remove_const_t<T>, std::reference_wrapper<T>> {};
39
40 // Specialization of expr_storage_impl for rvalue references.
41 template <class T>
42 struct expr_storage_impl<T &&> {
43 using type = T;
44 };
45
46 // Specialization of expr_storage_impl for const rvalue references.
47 template <class T>
48 struct expr_storage_impl<const T &&> {
49 using type = T;
50 };
51
52 // Specialization of expr_storage_impl for const types.
53 template <class T>
54 struct expr_storage_impl<const T> {
55 using type = T;
56 };
57
58 // Type used to encode which placeholder indices are used in an expression.
59 using ull_t = unsigned long long;
60
61 // Type trait that determines the set of placeholders in a parameter pack.
62 template <typename... Ts>
63 struct ph_set;
64
65 // Specialization of ph_set for parameter packs containing at least one type.
66 template <typename T0, typename... Ts>
67 struct ph_set<T0, Ts...> {
68 static constexpr ull_t value = ph_set<T0>::value | ph_set<Ts...>::value;
69 };
70
71 // Specialization of ph_set for a single non-lazy type.
72 template <typename T>
73 struct ph_set<T> {
74 static constexpr ull_t value = 0;
75 };
76
77 // Filter out certain placeholders given an integer value encoded by ph_set.
78 template <ull_t N, int... Is>
79 struct ph_filter;
80
81 // Specialization of ph_filter for at least one placeholder to filter out.
82 template <ull_t N, int I0, int... Is>
83 struct ph_filter<N, I0, Is...> {
84 static constexpr ull_t value = ph_filter<N, Is...>::value & (~(1ull << I0));
85 };
86
87 // Specialization of ph_filter for no placeholders to filter out.
88 template <ull_t N>
89 struct ph_filter<N> {
90 static constexpr ull_t value = N;
91 };
92
93 // Helper variable to determine if a type `T` is lazy.
94 template <typename T>
95 constexpr bool is_lazy_impl = false;
96
97 // Specialization of is_lazy_impl for cvref types.
98 template <typename T>
99 requires(!std::is_same_v<T, std::remove_cvref_t<T>>)
100 constexpr bool is_lazy_impl<T> = is_lazy_impl<std::remove_cvref_t<T>>;
101
102 // Helper variable to determine if a type `T` is an make_fun_impl type.
103 template <typename T>
104 inline constexpr bool is_function_impl = false;
105
106 // An erroneous diagnostics in gcc: i0 is indeed used. We silence it.
107#if defined(__GNUC__) and not defined(__clang__)
108#pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
109#endif
110
111 // Check if all given integers are different.
112 template <typename... Is>
113 constexpr bool all_different(int i0, Is... is) {
114 return (((is - i0) * ... * 1) != 0);
115 }
116
117#if defined(__GNUC__) and not defined(__clang__)
118#pragma GCC diagnostic pop
119#endif
120
121 } // namespace detail
122
124 template <typename T>
125 constexpr bool force_copy_in_expr = detail::force_copy_in_expr_impl<T>;
126
136 template <class T>
137 using expr_storage_t = typename detail::expr_storage_impl<T>::type;
138
140 template <typename T>
141 constexpr bool is_lazy = detail::is_lazy_impl<T>;
142
144 template <typename... Ts>
145 constexpr bool is_any_lazy = (is_lazy<Ts> or ...);
146
148 template <typename... Ts>
149 constexpr bool is_clef_expression = is_any_lazy<Ts...>;
150
152 template <typename T>
153 inline constexpr bool is_function = detail::is_function_impl<T>;
154
156
157} // namespace nda::clef
constexpr bool is_clef_expression
Alias template for nda::clef::is_any_lazy.
Definition utils.hpp:149
constexpr bool is_lazy
Constexpr variable that is true if the type T is a lazy type.
Definition utils.hpp:141
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:137
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:125
constexpr bool is_function
Constexpr variable that is true if the type T is an nda::clef::make_fun_impl type.
Definition utils.hpp:153
constexpr bool is_any_lazy
Constexpr variable that is true if any of the given types is lazy.
Definition utils.hpp:145