Skip to content
Open
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
2 changes: 0 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,10 @@ target_compile_options(${PROJECT_NAME}_warnings
-Wfloat-conversion
-Wpedantic
-Wno-sign-compare
$<$<CXX_COMPILER_ID:GNU>:-Wno-comma-subscript>
$<$<CXX_COMPILER_ID:GNU>:-Wno-psabi> # Disable notes about ABI changes
$<$<CXX_COMPILER_ID:GNU>:-Wshadow=local>
$<$<CXX_COMPILER_ID:GNU>:-Wno-attributes>
$<$<CXX_COMPILER_ID:GNU>:-Wno-deprecated-declarations>
$<$<CXX_COMPILER_ID:AppleClang,Clang,IntelLLVM>:-Wno-deprecated-comma-subscript>
$<$<CXX_COMPILER_ID:AppleClang,Clang,IntelLLVM>:-Wno-unknown-warning-option>
$<$<CXX_COMPILER_ID:AppleClang,Clang,IntelLLVM>:-Wshadow>
$<$<CXX_COMPILER_ID:AppleClang,Clang,IntelLLVM>:-Wno-gcc-compat>
Expand Down
2 changes: 1 addition & 1 deletion c++/nda/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ add_library(${PROJECT_NAME}::${PROJECT_NAME}_c ALIAS ${PROJECT_NAME}_c)
target_link_libraries(${PROJECT_NAME}_c PRIVATE $<BUILD_INTERFACE:${PROJECT_NAME}_warnings>)

# Configure target and compilation
target_compile_features(${PROJECT_NAME}_c PUBLIC cxx_std_20)
target_compile_features(${PROJECT_NAME}_c PUBLIC cxx_std_23)
set_target_properties(${PROJECT_NAME}_c PROPERTIES
POSITION_INDEPENDENT_CODE ON
VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
Expand Down
87 changes: 39 additions & 48 deletions c++/nda/_impl_basic_array_view_common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,23 +159,23 @@ static constexpr bool has_no_boundcheck = true;

public:
/**
* @brief Implementation of the function call operator.
* @brief Implementation of the subscript operator.
*
* @details This function is an implementation detail an should be private. Since the Green's function library in
* @details This function is an implementation detail and should be private. Since the Green's function library in
* TRIQS uses this function, it is kept public (for now).
*
* @tparam ResultAlgebra Algebra of the resulting view/array.
* @tparam SelfIsRvalue True if the view/array is an rvalue.
* @tparam Self Type of the calling view/array.
* @tparam T Types of the arguments.
* @tparam Ts Types of the arguments.
*
* @param self Calling view.
* @param self Calling view/array.
* @param idxs Multi-dimensional index consisting of `long`, `nda::range`, `nda::range::all_t`, nda::ellipsis or lazy
* arguments.
* @return Result of the function call depending on the given arguments and type of the view/array.
* @return Result of the subscript operation depending on the given arguments and type of the view/array.
*/
template <char ResultAlgebra, bool SelfIsRvalue, typename Self, typename... Ts>
FORCEINLINE static decltype(auto) call(Self &&self, Ts const &...idxs) noexcept(has_no_boundcheck) {
FORCEINLINE static decltype(auto) subscript(Self &&self, Ts const &...idxs) noexcept(has_no_boundcheck) {
// resulting value type
using r_v_t = std::conditional_t<std::is_const_v<std::remove_reference_t<Self>>, ValueType const, ValueType>;

Expand Down Expand Up @@ -219,9 +219,10 @@ FORCEINLINE static decltype(auto) call(Self &&self, Ts const &...idxs) noexcept(

public:
/**
* @brief Function call operator to access the view/array.
* @brief Subscript operator to access the view/array.
*
* @details Depending on the type of the calling object and the given arguments, this function call does the following:
* @details Depending on the type of the calling object and the given arguments, this subscript operation does the
* following:
* - If any of the arguments is lazy, an nda::clef::expr with the nda::clef::tags::function tag is returned.
* - If no arguments are given, a full view of the calling object is returned:
* - If the calling object itself or its value type is const, a view with a const value type is returned.
Expand All @@ -234,69 +235,59 @@ FORCEINLINE static decltype(auto) call(Self &&self, Ts const &...idxs) noexcept(
* the calling object. The algebra of the slice is the same as well, except if a 1-dimensional slice of a matrix is
* taken. In this case, the algebra is changed to 'V'.
*
* @tparam Ts Types of the function arguments.
* @tparam Ts Types of the arguments.
* @param idxs Multi-dimensional index consisting of `long`, `nda::range`, `nda::range::all_t`, nda::ellipsis or lazy
* arguments.
* @return Result of the function call depending on the given arguments and type of the view/array.
* @return Result of the subscript operation depending on the given arguments and type of the view/array.
*/
template <typename... Ts>
FORCEINLINE decltype(auto) operator()(Ts const &...idxs) const & noexcept(has_no_boundcheck) {
FORCEINLINE decltype(auto) operator[](Ts const &...idxs) const & noexcept(has_no_boundcheck) {
static_assert((rank == -1) or (sizeof...(Ts) == rank) or (sizeof...(Ts) == 0) or (ellipsis_is_present<Ts...> and (sizeof...(Ts) <= rank + 1)),
"Error in array/view: Incorrect number of parameters in call operator");
return call<Algebra, false>(*this, idxs...);
"Error in array/view: Incorrect number of parameters in subscript operator");
return subscript<Algebra, false>(*this, idxs...);
}

/// Non-const overload of `nda::basic_array_view::operator()(Ts const &...) const &`.
/// Non-const overload of `nda::basic_array_view::operator[](Ts const &...) const &`.
template <typename... Ts>
FORCEINLINE decltype(auto) operator()(Ts const &...idxs) & noexcept(has_no_boundcheck) {
FORCEINLINE decltype(auto) operator[](Ts const &...idxs) & noexcept(has_no_boundcheck) {
static_assert((rank == -1) or (sizeof...(Ts) == rank) or (sizeof...(Ts) == 0) or (ellipsis_is_present<Ts...> and (sizeof...(Ts) <= rank + 1)),
"Error in array/view: Incorrect number of parameters in call operator");
return call<Algebra, false>(*this, idxs...);
"Error in array/view: Incorrect number of parameters in subscript operator");
return subscript<Algebra, false>(*this, idxs...);
}

/// Rvalue overload of `nda::basic_array_view::operator()(Ts const &...) const &`.
/// Rvalue overload of `nda::basic_array_view::operator[](Ts const &...) const &`.
template <typename... Ts>
FORCEINLINE decltype(auto) operator()(Ts const &...idxs) && noexcept(has_no_boundcheck) {
FORCEINLINE decltype(auto) operator[](Ts const &...idxs) && noexcept(has_no_boundcheck) {
static_assert((rank == -1) or (sizeof...(Ts) == rank) or (sizeof...(Ts) == 0) or (ellipsis_is_present<Ts...> and (sizeof...(Ts) <= rank + 1)),
"Error in array/view: Incorrect number of parameters in call operator");
return call<Algebra, true>(*this, idxs...);
"Error in array/view: Incorrect number of parameters in subscript operator");
return subscript<Algebra, true>(*this, idxs...);
}

/**
* @brief Subscript operator to access the 1-dimensional view/array.
* @brief Function call operator to access the view/array.
*
* @details Depending on the type of the calling object and the given argument, this subscript operation does the
* following:
* - If the argument is lazy, an nda::clef::expr with the nda::clef::tags::function tag is returned.
* - If the argument is convertible to `long`, a single element is accessed:
* - If the calling object is a view or an lvalue, a (const) reference to the element is returned.
* - Otherwise, a copy of the element is returned.
* - Otherwise a slice of the calling object is returned with the same value type, algebra and accessor and owning
* policies as the calling object.
* @details Forwards to the subscript operator. See `nda::basic_array_view::operator[]` for details.
*
* @tparam T Type of the argument.
* @param idx 1-dimensional index that is either a `long`, `nda::range`, `nda::range::all_t`, nda::ellipsis or a lazy
* argument.
* @return Result of the subscript operation depending on the given argument and type of the view/array.
* @tparam Ts Types of the function arguments.
* @param idxs Multi-dimensional index consisting of `long`, `nda::range`, `nda::range::all_t`, nda::ellipsis or lazy
* arguments.
* @return Result of the function call depending on the given arguments and type of the view/array.
*/
template <typename T>
decltype(auto) operator[](T const &idx) const & noexcept(has_no_boundcheck) {
static_assert((rank == 1), "Error in array/view: Subscript operator is only available for rank 1 views/arrays in C++17/20");
return call<Algebra, false>(*this, idx);
template <typename... Ts>
FORCEINLINE decltype(auto) operator()(Ts const &...idxs) const & noexcept(has_no_boundcheck) {
return (*this)[idxs...];
}

/// Non-const overload of `nda::basic_array_view::operator[](T const &) const &`.
template <typename T>
decltype(auto) operator[](T const &x) & noexcept(has_no_boundcheck) {
static_assert((rank == 1), "Error in array/view: Subscript operator is only available for rank 1 views/arrays in C++17/20");
return call<Algebra, false>(*this, x);
/// Non-const overload of `nda::basic_array_view::operator()(Ts const &...) const &`.
template <typename... Ts>
FORCEINLINE decltype(auto) operator()(Ts const &...idxs) & noexcept(has_no_boundcheck) {
return (*this)[idxs...];
}

/// Rvalue overload of `nda::basic_array_view::operator[](T const &) const &`.
template <typename T>
decltype(auto) operator[](T const &x) && noexcept(has_no_boundcheck) {
static_assert((rank == 1), "Error in array/view: Subscript operator is only available for rank 1 views/arrays in C++17/20");
return call<Algebra, true>(*this, x);
/// Rvalue overload of `nda::basic_array_view::operator()(Ts const &...) const &`.
template <typename... Ts>
FORCEINLINE decltype(auto) operator()(Ts const &...idxs) && noexcept(has_no_boundcheck) {
return std::move(*this)[idxs...];
}

/// Rank of the nda::array_iterator for the view/array.
Expand Down
79 changes: 46 additions & 33 deletions c++/nda/arithmetic.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,18 +53,32 @@ namespace nda {
A a;

/**
* @brief Function call operator.
* @brief Subscript operator.
*
* @details Forwards the arguments to the nda::Array operand and negates the result.
*
* @tparam Args Types of the arguments.
* @param args Function call arguments.
* @return If the result of the forwarded function call is another nda::Array, a new lazy expression is returned.
* @param args Subscript arguments.
* @return If the result of the forwarded subscript is another nda::Array, a new lazy expression is returned.
* Otherwise the result is negated and returned.
*/
template <typename... Args>
auto operator[](Args &&...args) const {
return -a[std::forward<Args>(args)...];
}

/**
* @brief Function call operator.
*
* @details Forwards to the subscript operator.
*
* @tparam Args Types of the arguments.
* @param args Function call arguments.
* @return Result of the corresponding subscript operation.
*/
template <typename... Args>
auto operator()(Args &&...args) const {
return -a(std::forward<Args>(args)...);
return (*this)[std::forward<Args>(args)...];
}

/**
Expand Down Expand Up @@ -157,38 +171,38 @@ namespace nda {
}

/**
* @brief Function call operator.
* @brief Subscript operator.
*
* @details Forwards the arguments to the nda::Array operands and performs the binary operation.
*
* @tparam Args Types of the arguments.
* @param args Function call arguments.
* @return If the result of the forwarded function calls contains another nda::Array, a new lazy expression is
* @param args Subscript arguments.
* @return If the result of the forwarded subscript operations contains another nda::Array, a new lazy expression is
* returned. Otherwise the result of the binary operation is returned.
*/
template <typename... Args>
auto operator()(Args const &...args) const {
auto operator[](Args const &...args) const {
// addition
if constexpr (OP == '+') {
if constexpr (l_is_scalar) {
// lhs is a scalar
if constexpr (algebra == 'M')
// rhs is a matrix
return (std::equal_to{}(args...) ? l + r(args...) : r(args...));
return (std::equal_to{}(args...) ? l + r[args...] : r[args...]);
else
// rhs is an array
return l + r(args...);
return l + r[args...];
} else if constexpr (r_is_scalar) {
// rhs is a scalar
if constexpr (algebra == 'M')
// lhs is a matrix
return (std::equal_to{}(args...) ? l(args...) + r : l(args...));
return (std::equal_to{}(args...) ? l[args...] + r : l[args...]);
else
// lhs is an array
return l(args...) + r;
return l[args...] + r;
} else
// both are arrays or matrices
return l(args...) + r(args...);
return l[args...] + r[args...];
}

// subtraction
Expand All @@ -197,35 +211,35 @@ namespace nda {
// lhs is a scalar
if constexpr (algebra == 'M')
// rhs is a matrix
return (std::equal_to{}(args...) ? l - r(args...) : -r(args...));
return (std::equal_to{}(args...) ? l - r[args...] : -r[args...]);
else
// rhs is an array
return l - r(args...);
return l - r[args...];
} else if constexpr (r_is_scalar) {
// rhs is a scalar
if constexpr (algebra == 'M')
// lhs is a matrix
return (std::equal_to{}(args...) ? l(args...) - r : l(args...));
return (std::equal_to{}(args...) ? l[args...] - r : l[args...]);
else
// lhs is an array
return l(args...) - r;
return l[args...] - r;
} else
// both are arrays or matrices
return l(args...) - r(args...);
return l[args...] - r[args...];
}

// multiplication
if constexpr (OP == '*') {
if constexpr (l_is_scalar)
// lhs is a scalar
return l * r(args...);
return l * r[args...];
else if constexpr (r_is_scalar)
// rhs is a scalar
return l(args...) * r;
return l[args...] * r;
else {
// both are arrays (matrix product is not supported here)
static_assert(algebra != 'M', "Error in nda::expr: Matrix algebra not supported");
return l(args...) * r(args...);
return l[args...] * r[args...];
}
}

Expand All @@ -234,31 +248,30 @@ namespace nda {
if constexpr (l_is_scalar) {
// lhs is a scalar
static_assert(algebra != 'M', "Error in nda::expr: Matrix algebra not supported");
return l / r(args...);
return l / r[args...];
} else if constexpr (r_is_scalar)
// rhs is a scalar
return l(args...) / r;
return l[args...] / r;
else {
// both are arrays (matrix division is not supported here)
static_assert(algebra != 'M', "Error in nda::expr: Matrix algebra not supported");
return l(args...) / r(args...);
return l[args...] / r[args...];
}
}
}

/**
* @brief Subscript operator.
* @brief Function call operator.
*
* @details Simply forwards the argument to the function call operator.
* @details Forwards to the subscript operator.
*
* @tparam Arg Type of the argument.
* @param arg Subscript argument.
* @return Result of the corresponding function call.
* @tparam Args Types of the arguments.
* @param args Function call arguments.
* @return Result of the corresponding subscript operation.
*/
template <typename Arg>
auto operator[](Arg &&arg) const {
static_assert(get_rank<expr> == 1, "Error in nda::expr: Subscript operator only available for expressions of rank 1");
return operator()(std::forward<Arg>(arg));
template <typename... Args>
auto operator()(Args const &...args) const {
return (*this)[args...];
}
};

Expand Down
16 changes: 14 additions & 2 deletions c++/nda/array_adapter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,29 @@ namespace nda {
[[nodiscard]] long size() const { return stdutil::product(myshape); }

/**
* @brief Function call operator simply forwards the arguments to the callable object.
* @brief Subscript operator simply forwards the arguments to the callable object.
*
* @tparam Ints Integer types (convertible to long).
* @param i0 First argument.
* @param is Rest of the arguments.
*/
template <typename... Ints>
auto operator()(long i0, Ints... is) const {
auto operator[](long i0, Ints... is) const {
static_assert((std::is_convertible_v<Ints, long> and ...), "Error in nda::array_adapter: Arguments must be convertible to long");
return f(i0, is...);
}

/**
* @brief Function call operator simply forwards the arguments to the subscript operator.
*
* @tparam Ints Integer types (convertible to long).
* @param i0 First argument.
* @param is Rest of the arguments.
*/
template <typename... Ints>
auto operator()(long i0, Ints... is) const {
return (*this)[i0, is...];
}
};

// Class template argument deduction guides.
Expand Down
Loading
Loading