19#ifndef ESPRESSO_BONDLIST_HPP
20#define ESPRESSO_BONDLIST_HPP
24#include <boost/container/vector.hpp>
25#include <boost/iterator/iterator_facade.hpp>
26#include <boost/serialization/access.hpp>
27#include <boost/serialization/array.hpp>
28#include <boost/version.hpp>
47 std::span<const int> m_partners;
51 BondView(
int id, std::span<const int> partners)
52 : m_id(id), m_partners(partners) {}
58 return m_id == rhs.m_id and std::ranges::equal(m_partners, rhs.m_partners);
89 using storage_iterator = storage_type::const_iterator;
97 static storage_iterator find_end(storage_iterator it) {
106 friend boost::serialization::access;
107 template <
class Archive>
void serialize(Archive &ar,
long int ) {
108 if (Archive::is_loading::value) {
111 m_storage.resize(
size);
114 if (Archive::is_saving::value) {
115 auto size = m_storage.size();
119 ar &boost::serialization::make_array(m_storage.data(), m_storage.size());
124 :
public boost::iterator_facade<Iterator, BondView,
125 boost::forward_traversal_tag, BondView> {
127 explicit Iterator(storage_iterator it) : m_it(it) {}
131 storage_iterator m_it;
134 friend boost::iterator_core_access;
135 void increment() { m_it = std::next(find_end(m_it)); }
136 bool equal(Iterator
const &other)
const {
return this->m_it == other.m_it; }
138 auto const id_pos = find_end(m_it);
139 auto const partners_begin = m_it;
140 auto const partners_end = id_pos;
141 auto const dist = std::distance(partners_begin, partners_end);
142 return {-(*id_pos) - 1, std::span(std::addressof(*partners_begin),
149 using reference = std::add_lvalue_reference_t<BondView>;
160 if (
this != std::addressof(rhs)) {
161 m_storage = rhs.m_storage;
168 if (
this != std::addressof(rhs)) {
169 std::swap(m_storage, rhs.m_storage);
190 std::ranges::copy(bond.
partner_ids(), std::back_inserter(m_storage));
192 m_storage.push_back(-(bond.
bond_id() + 1));
201 return Iterator{m_storage.erase(pos.m_it, std::next(find_end(pos.m_it)))};
220 bool empty()
const {
return m_storage.empty(); }
226 swap(lhs.m_storage, rhs.m_storage);
241 return (bond.bond_id() == bond_id) and
242 (bond.partner_ids()[0] == partner_id);
bool pair_bond_exists_on(BondList const &bonds, int partner_id, int bond_id)
Check if there is a specific bond in a bond list.
Iterator(storage_iterator it)
BondList(BondList const &)=default
const_iterator erase(const_iterator pos)
Erase a bond from the list.
BondList(BondList &&)=default
BondList & operator=(BondList const &rhs)
friend void swap(BondList &lhs, BondList &rhs)
const_iterator begin() const
Iterator to the beginning of the range of bonds in the list.
std::add_const_t< reference > const_reference
Utils::compact_vector< int > storage_type
void insert(BondView const &bond)
Add a bond to the list.
auto size() const
Number of bonds.
std::ptrdiff_t difference_type
void clear()
Erase all bonds from the list.
const_iterator end() const
Iterator past the end of the range of bonds in the list.
bool empty() const
Check if the are any bonds in the list.
std::add_lvalue_reference_t< BondView > reference
BondList & operator=(BondList &&rhs) noexcept
Immutable view on a bond.
auto const & partner_ids() const
bool operator!=(BondView const &rhs) const
bool operator==(BondView const &rhs) const
BondView(int id, std::span< const int > partners)