Page MenuHomec4science

operations.hh
No OneTemporary

File Metadata

Created
Fri, May 31, 13:00

operations.hh

/**
* @file
*
* @author Lucas Frérot <lucas.frerot@epfl.ch>
*
* @section LICENSE
*
* Copyright (©) 2018 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Expolit is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Tamaas is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Tamaas. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef OPERATIONS_HH
#define OPERATIONS_HH
#include "types.hh"
#include <functional>
#include <ostream>
#include <utility>
namespace expolit {
template <typename T, typename U, typename Op>
struct BinaryOperation : public Expression<BinaryOperation<T, U, Op>> {
/// Construct from two expressions
BinaryOperation(const Expression<T>& t, const Expression<U>& u)
: operands(static_cast<const T&>(t), static_cast<const U&>(u)) {}
/// Evaluate operation
template <typename Val>
auto operator()(Val&& v) const {
return op(operands.first, operands.second);
}
auto commute() const {
return BinaryOperation<U, T, Op>(operands.second, operands.first);
}
/// Product operarands
const std::pair<T, U> operands;
const Op op = Op();
};
template <typename T, typename U, typename Op>
using SBinaryOperation = BinaryOperation<U, T, Op>;
template <typename T, typename U>
using Product = BinaryOperation<T, U, std::multiplies<>>;
template <typename T, typename U>
using Sum = BinaryOperation<T, U, std::plus<>>;
template <typename T, typename U>
using Difference = BinaryOperation<T, U, std::minus<>>;
template <typename Der1, typename Der2>
auto operator*(const Expression<Der1>& e1, const Expression<Der2>& e2) {
return Product<Der1, Der2>(e1, e2);
}
template <typename Der1, typename Der2>
auto operator+(const Expression<Der1>& e1, const Expression<Der2>& e2) {
return Sum<Der1, Der2>(e1, e2);
}
template <typename Der1, typename Der2>
auto operator-(const Expression<Der1>& e1, const Expression<Der2>& e2) {
return Difference<Der1, Der2>(e1, e2);
}
template <typename T, typename U>
std::ostream& operator<<(std::ostream& os, const Product<T, U>& p) {
os << "(" << p.operands.first << ")"
<< " * "
<< "(" << p.operands.second << ")";
return os;
}
template <typename T, typename U>
std::ostream& operator<<(std::ostream& os, const Difference<T, U>& p) {
os << p.operands.first << " - " << p.operands.second;
return os;
}
template <typename T, typename U>
std::ostream& operator<<(std::ostream& os, const Sum<T, U>& p) {
os << p.operands.first << " + " << p.operands.second;
return os;
}
} // namespace expolit
#endif

Event Timeline