TRIQS/nda 1.3.0
Multi-dimensional array library for C++
Loading...
Searching...
No Matches
io.hpp
Go to the documentation of this file.
1// Copyright (c) 2019-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, Olivier Parcollet, Nils Wentzell
16
22#pragma once
23
24#include "./clef.hpp"
25
26#include <functional>
27#include <iostream>
28#include <tuple>
29#include <type_traits>
30#include <utility>
31
32namespace nda::clef {
33
46 template <int N>
47 std::ostream &operator<<(std::ostream &sout, placeholder<N>) {
48 return sout << "_" << N;
49 }
50
59 template <typename T>
60 std::ostream &operator<<(std::ostream &sout, std::reference_wrapper<T> const &wrapper) {
61 return sout << wrapper.get();
62 }
63
64 // Overload of nda::clef::variadic_print for the case of an empty list of arguments.
65 inline std::ostream &variadic_print(std::ostream &sout) { return sout; }
66
77 template <typename T0, typename... Ts>
78 std::ostream &variadic_print(std::ostream &sout, T0 &&t0, Ts &&...ts) {
79 sout << std::forward<T0>(t0) << (sizeof...(Ts) > 0 ? ", " : "");
80 variadic_print(sout, std::forward<Ts>(ts)...);
81 return sout;
82 }
83
84 namespace detail {
85
86 // Helper struct to print a std::tuple recursively to std::ostream.
87 template <int C, int N>
88 struct print_tuple_impl {
89 template <typename Tuple>
90 void operator()(std::ostream &sout, Tuple const &t) {
91 sout << std::get<C>(t) << (C != N - 1 ? ", " : "");
92 print_tuple_impl<C + 1, N>()(sout, t);
93 }
94 };
95
96 // Helper struct to print a std::tuple recursively to std::ostream (end of the recursion).
97 template <int N>
98 struct print_tuple_impl<N, N> {
99 template <typename Tuple>
100 void operator()(std::ostream &, Tuple const &) {}
101 };
102
103 } // namespace detail
104
113 template <typename Tuple>
114 std::ostream &print_tuple(std::ostream &sout, Tuple const &t) {
115 detail::print_tuple_impl<1, std::tuple_size_v<Tuple>>()(sout, t);
116 return sout;
117 }
118
128 template <typename Tag, typename L>
129 requires std::is_base_of_v<tags::unary_op, Tag>
130 std::ostream &operator<<(std::ostream &sout, expr<Tag, L> const &ex) {
131 return sout << "(" << Tag::name() << " " << std::get<0>(ex.childs) << ")";
132 }
133
144 template <typename Tag, typename L, typename R>
145 requires std::is_base_of_v<tags::binary_op, Tag>
146 std::ostream &operator<<(std::ostream &sout, expr<Tag, L, R> const &ex) {
147 return sout << "(" << std::get<0>(ex.childs) << " " << Tag::name() << " " << std::get<1>(ex.childs) << ")";
148 }
149
160 template <typename C, typename A, typename B>
161 std::ostream &operator<<(std::ostream &sout, expr<tags::if_else, C, A, B> const &ex) {
162 return sout << "(" << std::get<0>(ex.childs) << " ? " << std::get<1>(ex.childs) << " : " << std::get<2>(ex.childs) << ")";
163 }
164
173 template <typename... Ts>
174 std::ostream &operator<<(std::ostream &sout, expr<tags::function, Ts...> const &ex) {
175 sout << "lambda"
176 << "(";
177 print_tuple(sout, ex.childs);
178 return sout << ")";
179 }
180
189 template <typename... Ts>
190 std::ostream &operator<<(std::ostream &sout, expr<tags::subscript, Ts...> const &ex) {
191 sout << "lambda"
192 << "[";
193 print_tuple(sout, ex.childs);
194 return sout << "]";
195 }
196
205 template <typename T>
206 std::ostream &operator<<(std::ostream &sout, expr<tags::terminal, T> const &ex) {
207 return sout << std::get<0>(ex.childs);
208 }
209
218 template <typename T>
219 std::ostream &operator<<(std::ostream &sout, expr<tags::subscript, T> const &ex) {
220 return sout << std::get<0>(ex.childs) << "[" << std::get<1>(ex.childs) << "]";
221 }
222
231 template <typename T>
232 std::ostream &operator<<(std::ostream &sout, expr<tags::negate, T> const &ex) {
233 return sout << "-(" << std::get<0>(ex.childs) << ")";
234 }
235
245 template <typename Expr, int... Is>
246 std::ostream &operator<<(std::ostream &sout, make_fun_impl<Expr, Is...> const &f) {
247 sout << "lazy function : (";
248 variadic_print(sout, placeholder<Is>()...);
249 return sout << ") --> " << f.obj;
250 }
251
254} // namespace nda::clef
Includes all relevant headers for the core clef library.
__inline__ void operator<<(expr< tags::function, F, placeholder< Is >... > const &ex, RHS &&rhs)
Assign values to the underlying object of a lazy function call expression.
std::ostream & print_tuple(std::ostream &sout, Tuple const &t)
Print a std::tuple to std::ostream.
Definition io.hpp:114
Single node of the expression tree.
childs_t childs
Child nodes of the current expression node.
Helper struct to simplify calls to nda::clef::eval.
Definition function.hpp:52
T obj
Object to be evaluated.
Definition function.hpp:54
A placeholder is an empty struct, labelled by an int.