Skip to content
Merged

Nary #146

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 53 additions & 60 deletions include/utilities/dsl/binary_op.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,27 @@
#pragma once
#include <tuple>
#include <type_traits>
#include <utilities/dsl/term.hpp>
#include <utilities/dsl/term_traits.hpp>
#include <utilities/dsl/n_ary_op.hpp>

namespace utilities::dsl {

/** @brief Code factorization for binary operations.
*
* @tparam DerivedType the operation *this is implementing.
* @tparam LHSType The const-qualified type of the object on the left side of
* the operation.
* @tparam RHSType The const-qualified type of the object on the right side of
* the operation.
* @tparam LHSType The const-qualified type of the object on the left side
* of the operation.
* @tparam RHSType The const-qualified type of the object on the right side
* of the operation.
*
* The DSL implementation of most of the binary operations are the same and is
* implemented by this class.
* The DSL implementation of most of the binary operations are the same and
* is implemented by this class.
*/
template<typename DerivedType, typename LHSType, typename RHSType>
class BinaryOp : public Term<DerivedType> {
class BinaryOp : public NAryOp<DerivedType, LHSType, RHSType> {
private:
/// Type *this inherits from
using base_type = NAryOp<DerivedType, LHSType, RHSType>;

/// Works out the types associated with LHSType
using lhs_traits = TermTraits<LHSType>;

Expand All @@ -46,7 +48,8 @@ class BinaryOp : public Term<DerivedType> {
/// Unqualified type of the object on the left side of the operator
using lhs_type = typename lhs_traits::value_type;

/// Type acting like `lhs_type&`, but respecting const-ness of @p LHSType
/// Type acting like `lhs_type&`, but respecting const-ness of @p
/// LHSType
using lhs_reference = typename lhs_traits::reference;

/// Type acting like `const lhs_type&`
Expand All @@ -55,91 +58,79 @@ class BinaryOp : public Term<DerivedType> {
/// Unqualified type of the object on the right side of the operator
using rhs_type = typename rhs_traits::value_type;

/// Type acting like `rhs_type&`, but respecting const-ness of @p RHSType
/// Type acting like `rhs_type&`, but respecting const-ness of @p
/// RHSType
using rhs_reference = typename rhs_traits::reference;

/// Type acting like `const rhs_type&`.
using const_rhs_reference = typename rhs_traits::const_reference;

/** @brief Creates a new binary operation by aliasing @p l and @p r.
*
* Generally speaking binary operations will want to alias the terms on
* the left and right of the operator (as opposed to copying them or taking
* ownership). This ctor takes references to the two objects and stores
* them internally as `TermTraits<T>::holder_type` objects (where T is
* @p LHSType and @p RHSType respectively for @p lhs and @p rhs). Thus
* whether *this ultimately owns the objects referenced by @p lhs and
* @p rhs are controlled by the respective specializations of `TermTraits`.
*
* @param[in] l An alias to the object on the left side of the operator.
* @param[in] r An alias to the object on the right side of the operator.
*
* @throw ??? Throws if converting either @p l or @p r to the holder type
* throws. Same throw guarantee.
*/
BinaryOp(lhs_reference l, rhs_reference r) : m_lhs_(l), m_rhs_(r) {}
/// Uses the base class's ctors
using base_type::base_type;

// -------------------------------------------------------------------------
// -- Getters and setters
// -------------------------------------------------------------------------

/** @brief Returns a (possibly) mutable reference to the object on the left
* of the operator.
/** @brief Returns a (possibly) mutable reference to the object on the
* left of the operator.
*
* *this is associated with two objects. The one that was on the left side
* of the operator is termed "lhs" and can be accessed via this method.
* *this is associated with two objects. The one that was on the left
* side of the operator is termed "lhs" and can be accessed via this
* method.
*
* @return A (possibly) mutable reference to the object which was on the
* left of the operator. The mutable-ness of the return is
* @return A (possibly) mutable reference to the object which was on
* the left of the operator. The mutable-ness of the return is
* controlled by TermTraits<LHSType>.
*
* @throw ??? Throws if converting from the held type to lhs_reference
* throws. Same throw guarantee.
*/
lhs_reference lhs() { return m_lhs_; }
lhs_reference lhs() { return this->template object<0>(); }

/** @brief Returns a read-only reference to the object on the left of the
* operator.
/** @brief Returns a read-only reference to the object on the left of
* the operator.
*
* This method is identical to the non-const version except that the return
* is guaranteed to be read-only.
* This method is identical to the non-const version except that the
* return is guaranteed to be read-only.
*
* @return A read-only reference to the object on the left of the
* operator.
*
* @throw ??? Throws if converting from the held type to
* const_lhs_reference throws. Same throw guarantee.
*/
const_lhs_reference lhs() const { return m_lhs_; }
const_lhs_reference lhs() const { return this->template object<0>(); }

/** @brief Returns a (possibly) mutable reference to the object on the right
* of the operator.
/** @brief Returns a (possibly) mutable reference to the object on the
* right of the operator.
*
* *this is associated with two objects. The one that was on the right side
* of the operator is termed "rhs" and can be accessed via this method.
* *this is associated with two objects. The one that was on the right
* side of the operator is termed "rhs" and can be accessed via this
* method.
*
* @return A (possibly) mutable reference to the object which was on the
* right of the operator. The mutable-ness of the return is
* @return A (possibly) mutable reference to the object which was on
* the right of the operator. The mutable-ness of the return is
* controlled by TermTraits<RHSType>.
*
* @throw ??? Throws if converting from the held type to rhs_reference
* throws. Same throw guarantee.
*/
rhs_reference rhs() { return m_rhs_; }
rhs_reference rhs() { return this->template object<1>(); }

/** @brief Returns a read-only reference to the object on the right of the
* operator.
/** @brief Returns a read-only reference to the object on the right of
* the operator.
*
* This method is identical to the non-const version except that the return
* is guaranteed to be read-only.
* This method is identical to the non-const version except that the
* return is guaranteed to be read-only.
*
* @return A read-only reference to the object on the right of the
* operator.
*
* @throw ??? Throws if converting from the held type to
* const_rhs_reference throws. Same throw guarantee.
*/
const_rhs_reference rhs() const { return m_rhs_; }
const_rhs_reference rhs() const { return this->template object<1>(); }

// -------------------------------------------------------------------------
// -- Utility methods
Expand All @@ -152,14 +143,15 @@ class BinaryOp : public Term<DerivedType> {
* @tparam RHSType2 The type of rhs in @p other.
*
* Two BinaryOp objects are the same if they:
* - Implement the same operation, e.g., both are implementing addition,
* - Implement the same operation, e.g., both are implementing
* addition,
* - Both have the same value of lhs, and
* - Both have the same value of rhs.
*
* It should be noted that following C++ convention, value comparisons are
* done with const references and thus the const-ness of @tparam LHSType
* and @tparam RHSType vs the respective const-ness of @tparam LHSType2
* and @tparam RHSType2 is not considered.
* It should be noted that following C++ convention, value comparisons
* are done with const references and thus the const-ness of @tparam
* LHSType and @tparam RHSType vs the respective const-ness of @tparam
* LHSType2 and @tparam RHSType2 is not considered.
*
* @param[in] other The object to compare to.
*
Expand All @@ -177,12 +169,13 @@ class BinaryOp : public Term<DerivedType> {
* @tparam LHSType2 The type of lhs in @p other.
* @tparam RHSType2 The type of rhs in @p other.
*
* This method defines "different" as not value equal. See the description
* for operator== for the definition of value equal.
* This method defines "different" as not value equal. See the
* description for operator== for the definition of value equal.
*
* @param[in] other The object to compare to *this.
*
* @return False if *this is value equal to @p other and true otherwise.
* @return False if *this is value equal to @p other and true
* otherwise.
*
* @throw None No throw guarantee.
*/
Expand Down
3 changes: 3 additions & 0 deletions include/utilities/dsl/dsl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@

#pragma once
#include <utilities/dsl/add.hpp>
#include <utilities/dsl/binary_op.hpp>
#include <utilities/dsl/divide.hpp>
#include <utilities/dsl/function_call.hpp>
#include <utilities/dsl/multiply.hpp>
#include <utilities/dsl/n_ary_op.hpp>
#include <utilities/dsl/subtract.hpp>
#include <utilities/dsl/term.hpp>
3 changes: 3 additions & 0 deletions include/utilities/dsl/dsl_fwd.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ class Divide;
template<typename LHSType, typename RHSType>
class Multiply;

template<typename DerivedType, typename... Args>
class NAryOp;

template<typename LHSType, typename RHSType>
class Subtract;

Expand Down
32 changes: 32 additions & 0 deletions include/utilities/dsl/dsl_traits.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright 2024 NWChemEx-Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once
#include <type_traits>
#include <utilities/dsl/dsl_fwd.hpp>

namespace utilities::dsl {

template<typename T>
struct IsTerm : public std::false_type {};

template<typename T>
struct IsTerm<Term<T>> : public std::true_type {};

template<typename T>
constexpr bool is_term_v = IsTerm<T>::value;

} // namespace utilities::dsl
47 changes: 47 additions & 0 deletions include/utilities/dsl/function_call.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright 2024 NWChemEx-Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once
#include <type_traits>
#include <utilities/dsl/n_ary_op.hpp>

namespace utilities::dsl {

/** @brief Represents calling operator(Args...) on an object
*
* @tparam Args The types of the arguments passed to operator(). Note that the
* first type in Args is the type of the object the implicit this
* pointer points to.
*
* This class is essentially a strong type over top of NaryOp to signal
* that the N-ary operation is a function call (or at the least represented
* with by `operator()`).
*/
template<typename... Args>
class FunctionCall : public NAryOp<FunctionCall<Args...>, Args...> {
private:
/// Type of *this
using my_type = FunctionCall<Args...>;

/// Type *this inherits from
using op_type = NAryOp<my_type, Args...>;

public:
/// Reuse the base class's ctor
using op_type::op_type;
};

} // namespace utilities::dsl
Loading
Loading