-
Notifications
You must be signed in to change notification settings - Fork 0
/
one_index_vector.hh
86 lines (75 loc) · 3.04 KB
/
one_index_vector.hh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#ifndef ONE_INDEX_VECTOR_H
#define ONE_INDEX_VECTOR_H
#include <climits>
#include <iostream>
#include <vector>
namespace one_index_vector {
template <typename T> struct OneIndexVector : public ::std::vector<T> {
// Storage allocation is performed by the base class, so none is needed here.
OneIndexVector() : std::vector<T>() {}
OneIndexVector(size_t n) : std::vector<T>(n) {}
OneIndexVector(size_t s, T val) : std::vector<T>(s, val) {}
// Causes GCC overload resolution to fail.
// OneIndexVector(::std::vector<T> vec) : std::vector<T>(vec) {}
template <typename ForwardIterator>
OneIndexVector(ForwardIterator first, ForwardIterator last)
: std::vector<T>(first, last) {}
OneIndexVector(::std::vector<T> &&vec);
OneIndexVector(const ::std::vector<T> &vec) = delete;
OneIndexVector &operator=(std::vector<T> &&vec);
// ULONG_MAX is what std::vector::size() returns for a default-constructed
// vector.
bool empty() const {
return ((0 == std::vector<T>::size()) ||
(ULONG_MAX == std::vector<T>::size()));
}
// Return an error indication or the expected value in a pair.
std::pair<bool, T &> make_result(bool b, T &res, size_t idx = 0) {
if (!b) {
std::cerr << "Index " << idx << " out of range." << std::endl;
return std::pair<bool, T &>(false, res);
}
return std::pair<bool, T &>(true, res);
}
// Only the member functions that know about indices need to be overridden.
// std:vector's element access functions work for indices 0 to size()-1.
std::pair<bool, T &> at(size_t n) {
if ((n < 1u) || (n > std::vector<T>::size())) {
return make_result(false, *(std::vector<T>::end()), n);
}
return make_result(true, std::vector<T>::at(n - 1));
}
// https://en.cppreference.com/w/cpp/language/override
// clang-format off
/*
* In a member function declaration or definition, override ensures that the
* function is virtual and is overriding a virtual function from a base class.
*
* ‘const T& one_index_vector::OneIndexVector<T>::at(size_t) const [with T = int; size_t = long unsigned int]’ marked ‘override’, but does not override
* const T &at(size_t n) const override {
*
* Override fails since the STL functions are not marked virtual.
*/
// clang-format on
std::pair<bool, const T &> at(size_t n) const {
if ((n < 1u) || (n > std::vector<T>::size())) {
return make_result(false, *(std::vector<T>::end()), n);
}
return make_result(true, std::vector<T>::at(n - 1));
}
std::pair<bool, T &> operator[](size_t n) {
if ((n < 1u) || (n > std::vector<T>::size())) {
return make_result(false, *(std::vector<T>::end()), n);
}
return make_result(true, std::vector<T>::operator[](n - 1));
}
std::pair<bool, const T &> operator[](size_t n) const {
if ((n < 1u) || (n > std::vector<T>::size())) {
return make_result(false, *(std::vector<T>::end()), n);
}
return make_result(true, std::vector<T>::operator[](n - 1));
}
};
} // namespace one_index_vector
#include "one_index_vector_impl.hh"
#endif