Gemmi C++ API
Loading...
Searching...
No Matches
span.hpp
Go to the documentation of this file.
1// Copyright 2019 Global Phasing Ltd.
2//
3// Span - span of array or std::vector.
4// MutableVectorSpan - span of std::vector with insert() and erase()
5
6#ifndef GEMMI_SPAN_HPP_
7#define GEMMI_SPAN_HPP_
8
9#include <algorithm> // for find_if, find_if_not
10#include <vector>
11#include <stdexcept> // for out_of_range
12#include <type_traits> // for remove_cv, conditional, is_const
13
14namespace gemmi {
15
16template<typename Item> struct MutableVectorSpan;
17
18// Minimalistic Span, somewhat similar to C++20 std::span.
19template<typename Item> struct Span {
20 using iterator = Item*;
21 using const_iterator = Item const*;
22 using element_type = Item;
23 using value_type = typename std::remove_cv<Item>::type;
24
27
28 Span() = default;
29 Span(iterator begin, std::size_t n) : begin_(begin), size_(n) {}
30
31#if !defined(_MSC_VER) || _MSC_VER-0 >= 1926
32 // constructor only for const Item, to allow non-const -> const conversion
33 template<typename T=Item>
35 typename std::enable_if<std::is_const<T>::value>::type* = 0)
36#else
37 // older MSVC don't like the version above
38 Span(const Span<value_type>& o)
39#endif
40 : begin_(o.begin_), size_(o.size_) {}
41
42 void set_begin(iterator begin) { begin_ = begin; }
43 void set_size(std::size_t n) { size_ = n; }
44 const_iterator begin() const { return begin_; }
45 const_iterator end() const { return begin_ + size_; }
46 iterator begin() { return begin_; }
47 iterator end() { return begin_ + size_; }
48
49 Item& front() { return *begin_; }
50 const Item& front() const { return *begin_; }
51 Item& back() { return *(begin_ + size_ - 1); }
52 const Item& back() const { return *(begin_ + size_ - 1); }
53
54 const Item& operator[](std::size_t i) const { return *(begin_ + i); }
55 Item& operator[](std::size_t i) { return *(begin_ + i); }
56
57 Item& at(std::size_t i) {
58 if (i >= size())
59 throw std::out_of_range("item index ouf of range: #" + std::to_string(i));
60 return *(begin_ + i);
61 }
62 const Item& at(std::size_t i) const {
63 return const_cast<Span*>(this)->at(i);
64 }
65
66 std::size_t size() const { return size_; }
67 bool empty() const { return size_ == 0; }
68 explicit operator bool() const { return size_ != 0; }
69
70 template<typename Iter> Span<Item> sub(Iter first, Iter last) {
71 return Span<Item>(&*first, last - first);
72 }
73
74 template<typename F, typename V=Item> Span<V> subspan(F&& func) {
75 auto group_begin = std::find_if(this->begin(), this->end(), func);
76 auto group_end = std::find_if_not(group_begin, this->end(), func);
77 return Span<V>(&*group_begin, group_end - group_begin);
78 }
79 template<typename F> Span<const value_type> subspan(F&& func) const {
80 using V = const value_type;
81 return const_cast<Span*>(this)->subspan<F, V>(std::forward<F>(func));
82 }
83
84 // we use children() to iterate over Model, Chain, etc
85 Span& children() { return *this; }
86 const Span& children() const { return *this; }
87
88private:
89 iterator begin_ = nullptr;
90 std::size_t size_ = 0;
91};
92
93// Span of std::vector, implements insert() and erase().
94template<typename Item> struct MutableVectorSpan : Span<Item> {
95 using vector_type = std::vector<typename Span<Item>::value_type>;
97 //friend Span<const value_type>;
98 MutableVectorSpan() = default;
100 : Span<Item>(p), vector_(v) {}
102 : Span<Item>(begin, n), vector_(&v) {}
103
104 template<typename Iter> MutableVectorSpan<Item> sub(Iter first, Iter last) {
105 return {Span<Item>::sub(first, last), vector_};
106 }
107
108 template<typename F> MutableVectorSpan<Item> subspan(F&& func) {
109 return {Span<Item>::subspan(std::forward<F>(func)), vector_};
110 }
111 template<typename F> MutableVectorSpan<const Item> subspan(F&& func) const {
112 return {Span<const Item>::subspan(std::forward<F>(func)), vector_};
113 }
114
115 iterator insert(iterator pos, Item&& item) {
116 auto offset = this->begin_ - this->vector_->data();
117 auto iter = vector_->begin() + (pos - this->vector_->data());
118 auto ret = vector_->insert(iter, std::move(item));
119 this->begin_ = vector_->data() + offset;
120 ++this->size_;
121 return &*ret;
122 }
123
124 void erase(iterator pos) {
125 vector_->erase(vector_->begin() + (pos - vector_->data()));
126 --this->size_;
127 }
128
129 bool is_beginning() const { return this->begin() == vector_->data(); }
130 bool is_ending() const { return this->end() == vector_->data() + vector_->size(); }
131
132private:
133 vector_type* vector_ = nullptr; // for insert() and erase()
134};
135
136} // namespace gemmi
137#endif
bool is_ending() const
Definition span.hpp:130
MutableVectorSpan(Span< Item > &&p, vector_type *v)
Definition span.hpp:99
typename Span< Item >::iterator iterator
Definition span.hpp:96
void erase(iterator pos)
Definition span.hpp:124
std::vector< typename Span< Item >::value_type > vector_type
Definition span.hpp:95
MutableVectorSpan< Item > sub(Iter first, Iter last)
Definition span.hpp:104
iterator insert(iterator pos, Item &&item)
Definition span.hpp:115
bool is_beginning() const
Definition span.hpp:129
MutableVectorSpan< const Item > subspan(F &&func) const
Definition span.hpp:111
MutableVectorSpan(vector_type &v, iterator begin, std::size_t n)
Definition span.hpp:101
MutableVectorSpan< Item > subspan(F &&func)
Definition span.hpp:108
const Item & back() const
Definition span.hpp:52
iterator end()
Definition span.hpp:47
const Item & operator[](std::size_t i) const
Definition span.hpp:54
Item * iterator
Definition span.hpp:20
Span< V > subspan(F &&func)
Definition span.hpp:74
Item & back()
Definition span.hpp:51
const_iterator begin() const
Definition span.hpp:44
void set_size(std::size_t n)
Definition span.hpp:43
const Span & children() const
Definition span.hpp:86
bool empty() const
Definition span.hpp:67
void set_begin(iterator begin)
Definition span.hpp:42
Span()=default
Span & children()
Definition span.hpp:85
Span(const Span< value_type > &o, typename std::enable_if< std::is_const< T >::value >::type *=0)
Definition span.hpp:34
Span< Item > sub(Iter first, Iter last)
Definition span.hpp:70
Item & front()
Definition span.hpp:49
Item & at(std::size_t i)
Definition span.hpp:57
Span< const value_type > subspan(F &&func) const
Definition span.hpp:79
Span(iterator begin, std::size_t n)
Definition span.hpp:29
const_iterator end() const
Definition span.hpp:45
iterator begin()
Definition span.hpp:46
std::size_t size() const
Definition span.hpp:66
const Item & front() const
Definition span.hpp:50
Item element_type
Definition span.hpp:22
typename std::remove_cv< Item >::type value_type
Definition span.hpp:23
Item & operator[](std::size_t i)
Definition span.hpp:55
const Item & at(std::size_t i) const
Definition span.hpp:62