GQCP
Loading...
Searching...
No Matches
Function.hpp
Go to the documentation of this file.
1// This file is part of GQCG-GQCP.
2//
3// Copyright (C) 2017-2020 the GQCG developers
4//
5// GQCG-GQCP is free software: you can redistribute it and/or modify
6// it under the terms of the GNU Lesser General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// GQCG-GQCP is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU Lesser General Public License for more details.
14//
15// You should have received a copy of the GNU Lesser General Public License
16// along with GQCG-GQCP. If not, see <http://www.gnu.org/licenses/>.
17
18#pragma once
19
20
21#include "Utilities/aliases.hpp"
23
24#include <boost/format.hpp>
25
26
27namespace GQCP {
28
29
30/*
31 * MARK: Forward declarations
32 */
33template <typename OutputType, typename InputType>
34class Function;
35
36
37/*
38 * MARK: `FunctionProduct` implementation
39 */
40
47template <typename T1, typename T2 = T1>
49 public Function<product_t<typename T1::OutputType, typename T2::OutputType>, typename T1::InputType> {
50
51 static_assert(std::is_same<typename T1::InputType, typename T2::InputType>::value, "FunctionProduct: T1 and T2 should have the same InputType.");
52
53private:
54 // The left-hand side of the product.
55 T1 m_lhs;
56
57 // The right-hand side of the product.
58 T2 m_rhs;
59
60
61public:
62 // The combined output type of the `operator()`.
64
65 // The input type of the `operator()`.
66 using InputType = typename T1::InputType; // Due to the `static_assert`, this is equal to `T2::InputType`.
67
68
69public:
70 /*
71 * MARK: Constructors
72 */
73
78 FunctionProduct(const T1& lhs, const T2& rhs) :
79 m_lhs {lhs},
80 m_rhs {rhs} {}
81
82
86 FunctionProduct() = default;
87
88
94 FunctionProduct(const int zero) :
96
97 if (zero != 0) {
98 throw std::invalid_argument("FunctionProduct(const int): Can't convert a non-zero integer to a 'zero' instance.");
99 }
100 }
101
102
103 /*
104 * MARK: General information
105 */
106
110 std::string description() const {
111 return (boost::format("((%s) * (%s))") % this->m_lhs.description() % this->m_rhs.description()).str();
112 }
113
114
115 /*
116 * MARK: Access
117 */
118
122 const T1& lhs() const { return this->m_lhs; }
123
127 const T2& rhs() const { return this->m_rhs; }
128
136 OutputType operator()(const InputType& in) const override {
137 return this->m_lhs(in) * this->m_rhs(in);
138 }
139};
140
141
142/*
143 * MARK: `Function` implementation
144 */
145
152template <typename _OutputType, typename _InputType>
153class Function {
154public:
155 // The return type of the `operator()`.
156 using OutputType = _OutputType;
157
158 // The input type of the `operator()`.
159 using InputType = _InputType;
160
161
162public:
163 /*
164 * MARK: Destructor
165 */
166
170 virtual ~Function() = default;
171
172
173 /*
174 * MARK: `Function` behavior
175 */
176
184 virtual OutputType operator()(const InputType& in) const = 0;
185};
186
187
188/*
189 * MARK: Aliases related to `Function`.
190 */
191
195template <typename T>
197
198
207template <typename F1, typename F2, typename = IsFunction<F1>, typename = IsFunction<F2>>
208FunctionProduct<F1, F2> operator*(const F1& lhs, const F2& rhs) {
209
210 return FunctionProduct<F1, F2>(lhs, rhs);
211}
212
213
214} // namespace GQCP
Definition: Function.hpp:153
virtual ~Function()=default
_OutputType OutputType
Definition: Function.hpp:156
virtual OutputType operator()(const InputType &in) const =0
_InputType InputType
Definition: Function.hpp:159
Definition: Function.hpp:49
typename T1::InputType InputType
Definition: Function.hpp:66
const T2 & rhs() const
Definition: Function.hpp:127
FunctionProduct(const T1 &lhs, const T2 &rhs)
Definition: Function.hpp:78
FunctionProduct(const int zero)
Definition: Function.hpp:94
const T1 & lhs() const
Definition: Function.hpp:122
OutputType operator()(const InputType &in) const override
Definition: Function.hpp:136
product_t< typename T1::OutputType, typename T2::OutputType > OutputType
Definition: Function.hpp:63
std::string description() const
Definition: Function.hpp:110
Definition: BaseOneElectronIntegralBuffer.hpp:25
typename std::enable_if< B, T >::type enable_if_t
Definition: type_traits.hpp:37
decltype(std::declval< T >() *std::declval< U >()) product_t
Definition: aliases.hpp:35
enable_if_t< std::is_base_of< Function< typename T::OutputType, typename T::InputType >, T >::value > IsFunction
Definition: Function.hpp:196
FunctionProduct< F1, F2 > operator*(const F1 &lhs, const F2 &rhs)
Definition: Function.hpp:208