TRIQS/nda 1.3.0
Multi-dimensional array library for C++
Loading...
Searching...
No Matches
eval.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 "./expression.hpp"
14#include "./operation.hpp"
15#include "./placeholder.hpp"
16#include "./utils.hpp"
17#include "../macros.hpp"
18
19#include <functional>
20#include <tuple>
21#include <type_traits>
22#include <utility>
23
24namespace nda::clef {
25
30
32 // Forward declarations.
33 template <typename T, typename... Pairs>
34 decltype(auto) eval(T const &obj, Pairs &&...pairs);
36
43 template <typename T, typename... Pairs>
44 struct evaluator {
46 static constexpr bool is_lazy = is_any_lazy<T>;
47
54 FORCEINLINE T const &operator()(T const &t, Pairs &...) const { return t; }
55 };
56
64 template <int N, int... Is, typename... Ts>
65 struct evaluator<placeholder<N>, pair<Is, Ts>...> {
66 private:
67 // Helper function to determine the position of the nda::clef::pair that has the nda::clef::placeholder<N>.
68 template <size_t... Ps>
69 static constexpr int get_position_of_N(std::index_sequence<Ps...>) {
70 return ((Is == N ? int(Ps) + 1 : 0) + ...) - 1;
71 }
72
73 // The position of the nda::clef::pair that has the nda::clef::placeholder<N> (-1 if no such pair was given).
74 static constexpr int N_position = get_position_of_N(std::make_index_sequence<sizeof...(Is)>{});
75
76 public:
81 static constexpr bool is_lazy = (N_position == -1);
82
90 FORCEINLINE decltype(auto) operator()(placeholder<N>, pair<Is, Ts> &...pairs) const {
91 if constexpr (not is_lazy) { // N is one of the Is
92 auto &pair_N = std::get<N_position>(std::tie(pairs...));
93 // the pair is a temporary constructed for the time of the eval call
94 // if it holds a reference, we return it, else we move the rhs object out of the pair
95 if constexpr (std::is_lvalue_reference_v<decltype(pair_N.rhs)>) {
96 return pair_N.rhs;
97 } else {
98 return std::move(pair_N.rhs);
99 }
100 } else { // N is not one of the Is
101 return placeholder<N>{};
102 }
103 }
104 };
105
112 template <typename T, typename... Pairs>
113 struct evaluator<std::reference_wrapper<T>, Pairs...> {
115 static constexpr bool is_lazy = false;
116
124 FORCEINLINE decltype(auto) operator()(std::reference_wrapper<T> const &wrapper, Pairs const &...pairs) const {
125 return eval(wrapper.get(), pairs...);
126 }
127 };
128
136 template <typename Tag, typename... Childs, typename... Pairs>
137 struct evaluator<expr<Tag, Childs...>, Pairs...> {
139 static constexpr bool is_lazy = (evaluator<Childs, Pairs...>::is_lazy or ...);
140
141 private:
142 // Helper function to evaluate the given expression.
143 template <size_t... Is>
144 [[nodiscard]] FORCEINLINE decltype(auto) eval_impl(std::index_sequence<Is...>, expr<Tag, Childs...> const &ex, Pairs &...pairs) const {
145 return op_dispatch<Tag>(std::integral_constant<bool, is_lazy>{}, eval(std::get<Is>(ex.childs), pairs...)...);
146 }
147
148 public:
159 [[nodiscard]] FORCEINLINE decltype(auto) operator()(expr<Tag, Childs...> const &ex, Pairs &...pairs) const {
160 return eval_impl(std::make_index_sequence<sizeof...(Childs)>(), ex, pairs...);
161 }
162 };
163
185 template <typename T, typename... Pairs>
186 FORCEINLINE decltype(auto) eval(T const &obj, Pairs &&...pairs) { // NOLINT (we don't want to forward here)
187 return evaluator<T, std::remove_reference_t<Pairs>...>()(obj, pairs...);
188 }
189
191
192} // namespace nda::clef
Provides some utility functions and type traits for the CLEF library.
Provides a basic lazy expression type for the clef library.
__inline__ decltype(auto) eval(T const &obj, Pairs &&...pairs)
Generic function to evaluate expressions and other types.
Definition eval.hpp:186
__inline__ auto op_dispatch(std::true_type, Args &&...args)
Dispatch operations containing at least one lazy operand.
constexpr bool is_any_lazy
Constexpr variable that is true if any of the given types is lazy.
Definition utils.hpp:145
Macros used in the nda library.
Provides operations for the clef library.
Provides placeholders for the clef library.
static constexpr bool is_lazy
Constexpr variable that is true if any of the evaluators of the child nodes is lazy.
Definition eval.hpp:139
static constexpr bool is_lazy
Constexpr variable that is true if the there is no nda::clef::pair containing an nda::clef::placehold...
Definition eval.hpp:81
static constexpr bool is_lazy
Constexpr variable that is always false.
Definition eval.hpp:115
Generic evaluator for types which do not have a specialized evaluator.
Definition eval.hpp:44
__inline__ T const & operator()(T const &t, Pairs &...) const
Evaluate the object and ignore all given nda::clef::pair objects.
Definition eval.hpp:54
static constexpr bool is_lazy
Definition eval.hpp:46
Single node of the expression tree.
childs_t childs
Child nodes of the current expression node.
A pair consisting of a placeholder and its assigned value.
A placeholder is an empty struct, labelled by an int.