9 #ifndef IMPKERNEL_INDEX_H
10 #define IMPKERNEL_INDEX_H
12 #include <IMP/kernel_config.h>
16 #include <cereal/access.hpp>
19 IMPKERNEL_BEGIN_NAMESPACE
29 friend class cereal::access;
31 template<
class Archive>
void serialize(Archive &ar) {
36 explicit Index(
int i) : i_(i) {}
54 inline unsigned int get_as_unsigned_int(
Index<Tag> i) {
58 inline Index<Tag> get_invalid_index() {
59 return Index<Tag>(-1);
68 static const unsigned char COMP_NONE = 0;
71 static const unsigned char COMP_RLE = 1;
76 static const unsigned char COMP_END = 100;
80 template <
class Tag,
class T>
84 friend class cereal::access;
87 template<
class Archive>
void save(Archive &ar)
const {
88 size_t sz = P::size();
92 ar(COMP_NONE); ar(sz);
101 template<
class Archive>
void load(Archive &ar) {
106 unsigned char comp_type;
108 while(comp_type != COMP_END) {
109 if (comp_type == COMP_NONE) {
116 }
else if (comp_type == COMP_RLE) {
131 IndexVector(
unsigned int sz,
const T &t = T()) :
P(sz, t) {}
134 return P::operator[](get_as_unsigned_int(i)));
139 template <
class Tag,
class T>
140 class CompressedIndexVector :
public IndexVector<Tag, T> {
143 template<
class Archive>
void write_no_compression(
144 Archive &ar,
typename P::const_iterator start,
145 typename P::const_iterator end)
const {
146 size_t sz = end - start;
147 ar(COMP_NONE); ar(sz);
148 while(start != end) {
153 template<
class Archive>
void write_rle(
154 Archive &ar,
typename P::const_iterator start,
155 typename P::const_iterator end)
const {
156 size_t sz = end - start;
157 ar(COMP_RLE); ar(sz);
161 friend class cereal::access;
162 template<
class Archive>
void save(Archive &ar)
const {
163 size_t sz = P::size();
165 typename P::const_iterator pos = P::begin(), start = P::begin(), runend;
166 while (pos != P::end()) {
170 for (runend = pos + 1; runend != P::end() && *runend == val; ++runend) {}
172 if (runend - pos > 10) {
173 if (pos > P::begin() && pos > start) {
175 write_no_compression(ar, start, pos);
177 write_rle(ar, pos, runend);
182 if (start != P::end()) {
183 write_no_compression(ar, start, P::end());
189 template <
class Tag,
class Container,
class T>
190 void resize_to_fit(Container &v, Index<Tag> i,
const T &default_value = T()) {
191 if (v.size() <= get_as_unsigned_int(i)) {
192 v.resize(get_as_unsigned_int(i) + 1, default_value);
196 IMPKERNEL_END_NAMESPACE
199 template <
class Archive,
class Tag,
class T>
200 struct specialize<Archive, IMP::IndexVector<Tag, T>,
201 cereal::specialization::member_load_save> {};
205 template <
class Archive,
class Tag,
class T>
206 struct specialize<Archive, IMP::CompressedIndexVector<Tag, T>,
207 cereal::specialization::member_load_save> {};
#define IMP_SHOWABLE_INLINE(Name, how_to_show)
Declare the methods needed by an object that can be printed.
#define IMP_HASHABLE_INLINE(name, hashret)
#define IMP_BRACKET(Value, Index, bounds_check_expr, expr)
Implement operator[] and at() for C++, and getitem for Python.
A more IMP-like version of the std::vector.
#define IMP_INTERNAL_CHECK(expr, message)
An assertion to check for internal errors in IMP. An IMP::ErrorException will be thrown.
Macros to handle array indexing.
Base class for a simple primitive-like type.
Ints get_index(const ParticlesTemp &particles, const Subset &subset, const Subsets &excluded)
Implements a vector tied to a particular index of type Index<Tag>.
A class for storing lists of IMP items.
#define IMP_THROW(message, exception_name)
Throw an exception with a message.
Base class for a simple primitive-like type.
#define IMP_COMPARISONS_1(Name, field)
Implement comparison in a class using field as the variable to compare.
An exception for an invalid value being passed to IMP.
Macros to help with objects that can be printed to a stream.