Skip to content

Commit 570a5cf

Browse files
authored
Introduce concept of segmented/ragged container. (#741)
This extends the PVector class, which previously had been relegated to use only in `simpdiv`, to be a general "ragged" 2-dimensional container. It exposes a simple API focused on the mechanics of keeping track of the segments, and a container-like view for iterating over each segment. It is also templated to allow both Array and Vector as storage types.
1 parent 2ff522b commit 570a5cf

5 files changed

Lines changed: 170 additions & 96 deletions

File tree

Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ core_SOURCES = \
247247
src/core/util.h \
248248
src/core/array.h \
249249
src/core/vector.h \
250+
src/core/segment.h \
250251
src/core/recarray.h \
251252
src/core/matrix.h \
252253
src/core/integer.cc \

src/core/core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "recarray.h"
2929
#include "vector.h"
3030
#include "matrix.h"
31+
#include "segment.h"
3132
#include "rational.h"
3233

3334
#endif // GAMBIT_CORE_CORE_H

src/core/segment.h

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
//
2+
// This file is part of Gambit
3+
// Copyright (c) 1994-2026, The Gambit Project (https://www.gambit-project.org)
4+
//
5+
// FILE: src/core/segment.h
6+
// A container segmenter, with versions for array and vector
7+
//
8+
// This program is free software; you can redistribute it and/or modify
9+
// it under the terms of the GNU General Public License as published by
10+
// the Free Software Foundation; either version 2 of the License, or
11+
// (at your option) any later version.
12+
//
13+
// This program is distributed in the hope that it will be useful,
14+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
// GNU General Public License for more details.
17+
//
18+
// You should have received a copy of the GNU General Public License
19+
// along with this program; if not, write to the Free Software
20+
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21+
//
22+
23+
#ifndef GAMBIT_CORE_SEGMENT_H
24+
#define GAMBIT_CORE_SEGMENT_H
25+
26+
#include "vector.h"
27+
28+
namespace Gambit {
29+
30+
template <class Storage> class Segmented {
31+
Storage m_values;
32+
Array<size_t> m_offsets;
33+
Array<size_t> m_shape;
34+
35+
public:
36+
using value_type = typename Storage::value_type;
37+
38+
template <class U> class SegmentView {
39+
U *m_data{nullptr};
40+
size_t m_size{0};
41+
42+
public:
43+
using value_type = U;
44+
using pointer = U *;
45+
using reference = U &;
46+
using iterator = U *;
47+
using const_iterator = const U *;
48+
49+
SegmentView() = default;
50+
SegmentView(U *data, const size_t size) : m_data(data), m_size(size) {}
51+
52+
size_t size() const { return m_size; }
53+
bool empty() const { return m_size == 0; }
54+
55+
U *data() { return m_data; }
56+
const U *data() const { return m_data; }
57+
58+
U &operator[](const size_t i) { return m_data[i - 1]; }
59+
const U &operator[](const size_t i) const { return m_data[i - 1]; }
60+
61+
iterator begin() { return m_data; }
62+
iterator end() { return m_data + m_size; }
63+
const_iterator begin() const { return m_data; }
64+
const_iterator end() const { return m_data + m_size; }
65+
};
66+
67+
Segmented() = delete;
68+
explicit Segmented(const Array<size_t> &p_shape)
69+
: m_values(std::accumulate(p_shape.begin(), p_shape.end(), 0)), m_offsets(p_shape.size()),
70+
m_shape(p_shape)
71+
{
72+
for (size_t index = 0, i = 1; i <= m_shape.size(); i++) {
73+
m_offsets[i] = index;
74+
index += m_shape[i];
75+
}
76+
}
77+
Segmented(const Segmented &) = default;
78+
Segmented(Segmented &&) noexcept = default;
79+
~Segmented() = default;
80+
81+
Segmented &operator=(const Segmented &) = default;
82+
Segmented &operator=(Segmented &&) noexcept = default;
83+
Segmented &operator=(const value_type &c)
84+
{
85+
m_values = c;
86+
return *this;
87+
}
88+
89+
const Array<size_t> &GetShape() const { return m_shape; }
90+
91+
SegmentView<value_type> segment(const size_t a)
92+
{
93+
return SegmentView<value_type>(&m_values[m_offsets[a] + 1], m_shape[a]);
94+
}
95+
SegmentView<const value_type> segment(const size_t a) const
96+
{
97+
return SegmentView<const value_type>(&m_values[m_offsets[a] + 1], m_shape[a]);
98+
}
99+
100+
void SetFlattened(const Storage &v) { m_values = v; }
101+
const Storage &GetFlattened() const { return m_values; }
102+
};
103+
104+
template <class T> using SegmentedArray = Segmented<Array<T>>;
105+
template <class T> using SegmentedVector = Segmented<Vector<T>>;
106+
107+
} // namespace Gambit
108+
109+
#endif // GAMBIT_CORE_SEGMENT_H

src/core/vector.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ template <class T> class Vector {
4141
}
4242

4343
public:
44+
using value_type = typename Array<T>::value_type;
4445
using iterator = typename Array<T>::iterator;
4546
using const_iterator = typename Array<T>::const_iterator;
4647

0 commit comments

Comments
 (0)