-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvector.h
210 lines (168 loc) · 4.62 KB
/
vector.h
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
#ifndef __VECTOR__H__
#define __VECTOR__H__
#include <string>
#include <vector>
#include <boost/concept_check.hpp>
#include <boost/concept/assert.hpp>
#include <boost/concept/requires.hpp>
class VectorTestSupport {
public:
static int streamToVector;
};
// Defines Stream concept.
template<class X>
struct IsStream {
public:
// A stream is something
BOOST_CONCEPT_USAGE(IsStream) {
// With size() method
size_t size = x.size();
// begin() method returning ::Iterator type
typename X::Iterator i = x.begin();
// ++ iterator advancing operator
++i;
// and end() checker
bool atEnd = x.end(i);
// and subscript operator.
double d = x[i];
}
private:
X x;
};
template<class X>
struct IsOpObject {
public:
BOOST_CONCEPT_USAGE(IsOpObject) {
double d1, d2;
double r = x(d1, d2);
}
private:
X x;
};
template<typename Op, class Stream1, class Stream2>
struct ZippedStream {
BOOST_CONCEPT_ASSERT((IsOpObject<Op>));
BOOST_CONCEPT_ASSERT((IsStream<Stream1>));
BOOST_CONCEPT_ASSERT((IsStream<Stream2>));
typedef typename Stream1::Iterator Iterator1;
typedef typename Stream2::Iterator Iterator2;
ZippedStream(const Stream1& s1, const Stream2& s2) : op_(), s1_(s1), s2_(s2) { }
const Op op_;
const Stream1& s1_;
const Stream2& s2_;
size_t size() const {
size_t size1 = s1_.size();
size_t size2 = s2_.size();
if (size1 < size2) {
return size1;
} else {
return size2;
}
}
struct Iterator {
Iterator(Iterator1 it1, Iterator2 it2) : it1_(it1), it2_(it2) { }
Iterator1 it1_;
Iterator2 it2_;
void operator++() {
++it1_;
++it2_;
}
};
Iterator begin() const { return Iterator(s1_.begin(), s2_.begin()); }
bool end(const Iterator& it) const {
return s1_.end(it.it1_) || s2_.end(it.it2_);
}
double operator[](const Iterator& it) const {
return op_(s1_[it.it1_], s2_[it.it2_]);
}
};
template<typename Op, class Stream1, class Stream2>
BOOST_CONCEPT_REQUIRES(
((IsStream<Stream1>))
((IsStream<Stream2>)),
(ZippedStream<Op, Stream1, Stream2>)) ZipWith(const Stream1& s1, const Stream2& s2) {
return ZippedStream<Op, Stream1, Stream2>(s1, s2);
}
template<typename Op, class Stream>
BOOST_CONCEPT_REQUIRES(
((IsOpObject<Op>))
((IsStream<Stream>)),
(double)) Fold(const Stream& stream, double init) {
Op op;
double result = init;
for (auto it = stream.begin(); !stream.end(it); ++it) {
result = op(result, stream[it]);
}
return result;
}
//-----------------------
struct Plus : public std::binary_function<double, double, double> {
double operator()(double d1, double d2) const { return d1 + d2; }
};
struct Mul : public std::binary_function<double, double, double> {
double operator()(double d1, double d2) const { return d1 * d2; }
};
//-----------------------
class Vector {
public:
explicit Vector(size_t size) {
data_.resize(size);
}
typedef int Iterator;
int begin() const { return 0; }
bool end(int i) const { return i >= size(); }
size_t size() const { return data_.size(); }
double operator[](size_t i) const {
return data_[i];
}
double& operator[](size_t i) {
return data_[i];
}
double length() {
return Fold<Plus>(ZipWith<Mul>(*this, *this), 0);
}
std::vector<double> data_;
};
template<class S>
class VectorFromStream {
public:
BOOST_CONCEPT_ASSERT((IsStream<S>));
typedef S Stream;
VectorFromStream(const Stream& stream) : stream_(stream) { }
operator Vector() const {
#ifdef VECTOR_TEST
VectorTestSupport::streamToVector++;
#endif
printf("VectorFromStream->Vector\n");
size_t size = stream_.size();
Vector result(size);
int i = 0;
for (auto it = stream_.begin(); !stream_.end(it); ++it, ++i) {
result[i] = stream_.get(it);
}
return result;
}
typedef typename Stream::Iterator Iterator;
Iterator begin() const { return stream_.begin(); }
bool end(const Iterator& i) const { return stream_.end(i); }
double operator[](const Iterator& i) const { return stream_[i]; }
size_t size() const { return stream_.size(); }
double length() {
return Fold<Plus>(ZipWith<Mul>(*this, *this), 0);
}
const Stream& stream_;
};
template<class Stream>
struct FromStream {
BOOST_CONCEPT_ASSERT((IsStream<Stream>));
typedef VectorFromStream<Stream> Result;
Result operator()(const Stream& s) {
return VectorFromStream<Stream>(s);
}
};
template<typename Vector1, typename Vector2>
typename FromStream<ZippedStream<Plus, Vector1, Vector2> >::Result
operator+(const Vector1& v1, const Vector2& v2) {
return FromStream<ZippedStream<Plus, Vector1, Vector2> >()(ZipWith<Plus>(v1, v2));
}
#endif