Skip to content
Merged
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
1 change: 1 addition & 0 deletions SeQuant/core/expr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <SeQuant/core/expressions/constant.hpp>
#include <SeQuant/core/expressions/expr.hpp>
#include <SeQuant/core/expressions/expr_algorithms.hpp>
#include <SeQuant/core/expressions/expr_iterator.hpp>
#include <SeQuant/core/expressions/expr_operators.hpp>
#include <SeQuant/core/expressions/expr_ptr.hpp>
#include <SeQuant/core/expressions/expr_range.hpp>
Expand Down
47 changes: 47 additions & 0 deletions SeQuant/core/expressions/expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <SeQuant/core/expressions/abstract_tensor.hpp>
#include <SeQuant/core/expressions/constant.hpp>
#include <SeQuant/core/expressions/expr.hpp>
#include <SeQuant/core/expressions/expr_iterator.hpp>
#include <SeQuant/core/expressions/tensor.hpp>
#include <SeQuant/core/io/latex/latex.hpp>
#include <SeQuant/core/logger.hpp>
Expand All @@ -30,6 +31,52 @@

namespace sequant {

ExprIterator Expr::begin() { return begin_subexpr(); }

ExprIterator Expr::end() { return end_subexpr(); }

ConstExprIterator Expr::begin() const { return begin_subexpr(); }

ConstExprIterator Expr::end() const { return end_subexpr(); }

ConstExprIterator Expr::cbegin() const { return begin_subexpr(); }

ConstExprIterator Expr::cend() const { return end_subexpr(); }

ExprIterator Expr::begin_subexpr() { return ExprIterator{}; }

ExprIterator Expr::end_subexpr() { return ExprIterator{}; }

ConstExprIterator Expr::begin_subexpr() const { return ConstExprIterator{}; }

ConstExprIterator Expr::end_subexpr() const { return ConstExprIterator{}; }

std::size_t Expr::size() const { return end() - begin(); }

bool Expr::empty() const { return size() == 0; }

ExprPtr &Expr::operator[](std::size_t idx) {
SEQUANT_ASSERT(idx < size());
return begin()[idx];
}

const ExprPtr &Expr::operator[](std::size_t idx) const {
SEQUANT_ASSERT(idx < size());
return begin()[idx];
}

ExprPtr &Expr::at(std::size_t idx) { return (*this)[idx]; }

const ExprPtr &Expr::at(std::size_t idx) const { return (*this)[idx]; }

ExprPtr &Expr::front() { return at(0); }

const ExprPtr &Expr::front() const { return at(0); }

ExprPtr &Expr::back() { return at(size() - 1); }

const ExprPtr &Expr::back() const { return at(size() - 1); }

ExprPtr ExprPtr::clone() const & {
if (!*this) return {};
return ExprPtr(as_shared_ptr()->clone());
Expand Down
116 changes: 40 additions & 76 deletions SeQuant/core/expressions/expr.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef SEQUANT_EXPRESSIONS_EXPR_HPP
#define SEQUANT_EXPRESSIONS_EXPR_HPP

#include <SeQuant/core/expressions/expr_iterator.hpp>
#include <SeQuant/core/expressions/expr_ptr.hpp>
#include <SeQuant/core/options.hpp>
#include <SeQuant/core/utility/macros.hpp>
Expand All @@ -10,9 +11,7 @@
#include <atomic>
#include <memory>
#include <optional>

#include <range/v3/range/primitives.hpp>
#include <range/v3/view/facade.hpp>
#include <ranges>

namespace sequant {

Expand Down Expand Up @@ -58,18 +57,16 @@ static const wchar_t adjoint_label = L'\u207A';
/// for(const auto& e: c.expr()) { // iterates over subexpressions
/// }
/// @endcode
class Expr : public std::enable_shared_from_this<Expr>,
public ranges::view_facade<Expr> {
class Expr : public std::enable_shared_from_this<Expr> {
public:
using range_type = ranges::view_facade<Expr>;
using hash_type = std::size_t;
using type_id_type = int; // to speed up comparisons

Expr() = default;
virtual ~Expr() = default;

/// @return true if this is a leaf
bool is_atom() const { return ranges::empty(*this); }
bool is_atom() const { return empty(); }

/// @return true if this is zero
virtual bool is_zero() const { return false; }
Expand Down Expand Up @@ -149,14 +146,6 @@ class Expr : public std::enable_shared_from_this<Expr>,
return visit_impl(*this, std::forward<Visitor>(visitor), atoms_only);
}

auto begin_subexpr() { return range_type::begin(); }

auto end_subexpr() { return range_type::end(); }

auto begin_subexpr() const { return range_type::begin(); }

auto end_subexpr() const { return range_type::end(); }

Expr &expr() { return *this; }
const Expr &expr() const { return *this; }

Expand All @@ -180,7 +169,7 @@ class Expr : public std::enable_shared_from_this<Expr>,
/// overridden for scalar leaf types.
virtual bool is_scalar() const {
if (is_atom()) return false;
for (auto it = begin_subexpr(); it != end_subexpr(); ++it) {
for (auto it = begin(); it != end(); ++it) {
if (!(*it)->is_scalar()) return false;
}
return true;
Expand All @@ -199,7 +188,7 @@ class Expr : public std::enable_shared_from_this<Expr>,
return true;
else {
bool result = true;
for (auto it = begin_subexpr(); result && it != end_subexpr(); ++it) {
for (auto it = begin(); result && it != end(); ++it) {
result &= (*it)->is_cnumber();
}
return result;
Expand All @@ -226,14 +215,12 @@ class Expr : public std::enable_shared_from_this<Expr>,
this->is_cnumber() || that.is_cnumber() || commutes_with_atom(that);
} else if (this_is_atom) {
if (!this->is_cnumber()) {
for (auto it = that.begin_subexpr(); result && it != that.end_subexpr();
++it) {
for (auto it = that.begin(); result && it != that.end(); ++it) {
result &= this->commutes_with(**it);
}
}
} else {
for (auto it = this->begin_subexpr(); result && it != this->end_subexpr();
++it) {
for (auto it = this->begin(); result && it != this->end(); ++it) {
result &= (*it)->commutes_with(that);
}
}
Expand Down Expand Up @@ -375,9 +362,35 @@ class Expr : public std::enable_shared_from_this<Expr>,

///@}

private:
friend ranges::range_access;
ExprIterator begin();
ExprIterator end();
ConstExprIterator begin() const;
ConstExprIterator end() const;
ConstExprIterator cbegin() const;
ConstExprIterator cend() const;

virtual ExprIterator begin_subexpr();
virtual ExprIterator end_subexpr();
virtual ConstExprIterator begin_subexpr() const;
virtual ConstExprIterator end_subexpr() const;

std::size_t size() const;

bool empty() const;

ExprPtr &operator[](std::size_t idx);
const ExprPtr &operator[](std::size_t idx) const;

ExprPtr &at(std::size_t idx);
const ExprPtr &at(std::size_t idx) const;

ExprPtr &front();
const ExprPtr &front() const;

ExprPtr &back();
const ExprPtr &back() const;

private:
template <
typename E, typename Visitor,
typename = std::enable_if_t<std::is_same_v<std::remove_cvref_t<E>, Expr>>>
Expand Down Expand Up @@ -414,59 +427,6 @@ class Expr : public std::enable_shared_from_this<Expr>,
Expr &operator=(Expr &&) = default;
Expr &operator=(const Expr &) = default;

struct cursor {
using value_type = ExprPtr;

cursor() = default;
constexpr explicit cursor(ExprPtr *subexpr_ptr) noexcept
: ptr_{subexpr_ptr} {}
/// when take const ptr note runtime const flag
constexpr explicit cursor(const ExprPtr *subexpr_ptr) noexcept
: ptr_{const_cast<ExprPtr *>(subexpr_ptr)}, const_{true} {}
bool equal(const cursor &that) const { return ptr_ == that.ptr_; }
void next() { ++ptr_; }
void prev() { --ptr_; }
// TODO figure out why can't return const here if want to be able to assign
// to *begin(Expr&)
ExprPtr &read() const {
RANGES_EXPECT(ptr_);
return *ptr_;
}
ExprPtr &read() {
RANGES_EXPECT(const_ == false);
RANGES_EXPECT(ptr_);
return *ptr_;
}
void assign(const ExprPtr &that_ptr) {
RANGES_EXPECT(ptr_);
*ptr_ = that_ptr;
}
std::ptrdiff_t distance_to(cursor const &that) const {
return that.ptr_ - ptr_;
}
void advance(std::ptrdiff_t n) { ptr_ += n; }

private:
ExprPtr *ptr_ =
nullptr; // both begin and end will be represented by this, so Expr
// without subexpressions begin() equals end() automatically
bool const_ = false; // assert in nonconst ops
};

/// @return the cursor for the beginning of the range (must override in a
/// derived Expr that has subexpressions)
virtual cursor begin_cursor() { return cursor{}; }
/// @return the cursor for the end of the range (must override in a derived
/// Expr that has subexpressions)
virtual cursor end_cursor() { return cursor{}; }

/// @return the cursor for the beginning of the range (must override in a
/// derived Expr that has subexpressions)
virtual cursor begin_cursor() const { return cursor{}; }
/// @return the cursor for the end of the range (must override in a derived
/// Expr that has subexpressions)
virtual cursor end_cursor() const { return cursor{}; }

mutable std::optional<hash_type> hash_value_; // not initialized by default
virtual hash_type memoizing_hash() const {
static const hash_type default_hash_value = 0;
Expand Down Expand Up @@ -531,6 +491,10 @@ class Expr : public std::enable_shared_from_this<Expr>,
Exception not_implemented(const char *fn) const;
}; // class Expr

static_assert(std::ranges::sized_range<Expr>);
static_assert(std::ranges::bidirectional_range<Expr>);
static_assert(std::ranges::random_access_range<Expr>);

template <>
struct Expr::is_shared_ptr_of_expr<ExprPtr, void> : std::true_type {};
template <>
Expand Down
Loading
Loading