source: cppstreams/stream.h @ 2

Last change on this file since 2 was 2, checked in by gobi, 13 years ago

import

File size: 8.5 KB
Line 
1/*
2 * Legyen benne zipwith
3 *
4 * Itt az a trukk, hogy az iterator az impl**-ot tarol, igy a zipwith
5 * kiertekeles utan atirja az adatszerkezetet, tehat ketszer nem szamolja ki
6 * ugyanazt az erteket.
7 *
8 * Legnagyobb fajdalmamra nem sikerult osszeraknom ilyesmit:
9 * for(int i=0; i<10; ++i)
10 *    s=i<<s;
11 * Ez future plan...
12 *
13 */
14
15#ifndef __stream_h__
16#define __stream_h__
17
18#include <iostream>
19#include <utility>
20#include <ctime>
21#include <cassert>
22
23#if __GNUC__ > 4 || \
24          (__GNUC__ == 4 && (__GNUC_MINOR__ >= 7))
25#define HAVE_LITERALS
26#endif
27
28template<typename T>
29struct storage_type
30{
31    typedef typename std::conditional<
32        std::is_lvalue_reference<typename std::remove_const<T>::type>::value,
33        typename std::remove_const<T>::type,
34        typename std::remove_reference<typename std::remove_const<T>::type>::type
35    >::type type;
36};
37
38template<typename T>
39struct stream
40{
41protected:
42    struct impl;
43
44public:
45    typedef T value_type;
46
47    stream(const stream<T> &o)
48        : impl_(o.impl_->clone())
49    { 
50    }
51
52    stream(stream<T> &&o)
53        : impl_(0)
54    {
55        std::swap(impl_, o.impl_);
56    }
57   
58    stream<T> & operator = (stream<T> &&o)
59    {
60        if(this != &o) {
61                std::swap(impl_, o.impl_);
62                return *this;
63        }
64    }
65   
66    ~stream()
67    {
68        delete impl_;
69    }
70
71    struct iterator {
72        iterator& operator ++() 
73        {
74            (*impl_)->next(*this);
75            return *this;
76        }
77
78        const T& operator *() const
79        {
80            return (*impl_)->get(*this);
81        }
82
83        friend class stream<T>;
84
85    protected:
86        iterator(impl ** impl)
87            :impl_(impl)
88        { }
89
90        impl **impl_;
91    };
92
93    iterator begin() const
94    {
95        return iterator(&impl_);
96    }
97
98protected:
99
100    struct impl {
101        virtual ~impl() {}
102        virtual const T &get(const iterator &) = 0;
103        virtual void next(iterator &) = 0;
104        virtual impl* clone() = 0;
105    };
106
107    mutable impl * impl_;
108
109    stream(impl *i)
110        :impl_(i)
111    { }
112
113    template<typename ST>
114    struct addimpl: public impl {
115        addimpl(const T &a, ST &&s)
116            : a_(a), s_(std::forward<ST>(s)) 
117        { }
118
119        const T &get(const iterator &) 
120        {
121            return a_;
122        }
123
124        void next(iterator &it)
125        {
126            it.impl_ = const_cast<impl**>(&s_.impl_);
127        }
128
129        impl *clone() 
130        {
131            return new addimpl<ST>(a_, std::forward<ST>(s_));
132        }
133
134    private:
135        const T a_;
136        typename storage_type<ST>::type s_;
137    };
138
139    template<typename Op, typename ST>
140    struct mapimpl2: public impl {
141        mapimpl2(Op op, ST &&s)
142            :s_(std::forward<ST>(s)),
143            it1(s_.begin()), op_(op)
144        {
145        }
146
147        const T &get(const iterator &it)
148        { 
149            *(it.impl_)=new addimpl<stream<T>&&>(op_(*it1), stream<T>(this));
150            ++it1;
151            return *it;
152        }
153
154        void next(iterator &it) 
155        {
156            *(it.impl_)=new addimpl<stream<T>&&>(op_(*it1), stream<T>(this));
157            ++it1;
158            ++it;
159        }
160
161        impl *clone() 
162        {
163            return new mapimpl2<Op, ST>(op_, std::forward<ST>(s_));
164        }
165    private:
166        typename storage_type<ST>::type s_;
167        iterator it1;
168        Op op_;
169        };
170
171    template<typename Op, typename ST>
172    struct mapimpl: public impl {
173        mapimpl(Op op, ST &&s)
174            : s_(std::forward<ST>(s)), op_(op)
175        { }
176
177        const T &get(const iterator &it) 
178        {
179            impl *x = new mapimpl2<Op, ST>(op_, std::forward<ST>(s_));
180            *(it.impl_) = x;
181           
182            delete this;
183            return *it;
184        }
185
186        void next(iterator &it)
187        {
188            impl *x = new mapimpl2<Op, ST>(op_, std::forward<ST>(s_));
189            *(it.impl_) = x;
190            delete this;
191            ++it;
192        }
193
194        impl *clone() 
195        {
196            return new mapimpl<Op, ST>(op_, std::forward<ST>(s_));
197        }
198
199    private:
200        typename storage_type<ST>::type s_;
201                Op op_;
202    };
203
204    template<typename Op, typename ST1, typename ST2>
205    struct zipimpl: public impl
206    {
207        zipimpl(Op op, ST1 &&s1, ST2 &&s2)
208            :s1_(std::forward<ST1>(s1)), s2_(std::forward<ST2>(s2)), op_(op)
209        { }
210
211        const T &get(const iterator &it) 
212        { 
213            impl *x = new zipimpl2<Op, ST1, ST2>(op_, std::forward<ST1>(s1_), std::forward<ST2>(s2_));
214            *(it.impl_) = x;
215            delete this;
216            return *it;
217        }
218
219        void next(iterator &it) 
220        {
221            impl *x = new zipimpl2<Op, ST1, ST2>(op_, std::forward<ST1>(s1_), std::forward<ST2>(s2_));
222            *(it.impl_) = x;
223            delete this;
224            ++it;
225        }
226
227        impl *clone() 
228        {
229            return new zipimpl<Op, ST1, ST2>(op_, std::forward<ST1>(s1_), std::forward<ST2>(s2_));
230        }
231    private:
232        typename storage_type<ST1>::type s1_;
233        typename storage_type<ST2>::type s2_;
234        Op op_;
235    };
236
237    template<typename Op, typename ST1, typename ST2>
238    struct zipimpl2: public impl
239    {
240        zipimpl2(Op op, ST1 &&s1, ST2 &&s2)
241            :s1_(std::forward<ST1>(s1)),s2_(std::forward<ST2>(s2)),
242            it1(s1_.begin()), it2(s2_.begin()), op_(op)
243        {
244        }
245
246        const T &get(const iterator &it)
247        { 
248            *(it.impl_)=new addimpl<stream<T>&&>(op_(*it1, *it2), stream<T>(this));
249            ++it1;
250            ++it2;
251            return *it;
252        }
253
254        void next(iterator &it) 
255        {
256            *(it.impl_)=new addimpl<stream<T>&&>(op_(*it1, *it2), stream<T>(this));
257            ++it1;
258            ++it2;
259            ++it;
260        }
261
262        impl *clone() 
263        {
264            return new zipimpl2<Op, ST1, ST2>(op_, std::forward<ST1>(s1_), std::forward<ST2>(s2_));
265        }
266    private:
267        typename storage_type<ST1>::type s1_;
268        typename storage_type<ST2>::type s2_;
269        iterator it1, it2;
270        Op op_;
271    };
272
273public:
274        template <typename S, typename U>
275        friend stream<U> operator <<= (const U& a, S && s);
276   
277    template <typename Op, typename ST1, typename ST2>
278    static stream<T> zipwith(Op op, ST1 &&s1, ST2 &&s2)
279    {
280        return stream(new zipimpl<Op, decltype(s1), decltype(s2)>(op, std::forward<ST1>(s1), std::forward<ST2>(s2)));
281    }
282   
283        template <typename ST1, typename Op>
284    static stream<T> map(Op op, ST1 &&s1)
285    {
286        return stream(new mapimpl<Op, decltype(s1)>(op, std::forward<ST1>(s1)));
287    }
288
289        static stream<T> pure(const T& v)
290        {
291                stream<T> s = v<<=s;
292                return s;
293        }
294};
295
296template<typename ST>
297struct stream_value_type
298{
299        typedef typename std::remove_reference<ST>::type::value_type type;
300};
301
302template <typename S, typename U=typename stream_value_type<S>::type>
303stream<U> operator <<= (const U& a, S && s)
304{
305        return stream<U>(new typename stream<U>::template addimpl<decltype(s)>(a, std::forward<S>(s)));
306}
307   
308template<typename ST1, typename ST2, typename T=typename stream_value_type<ST1>::type>
309stream<T> operator +(ST1 &&s1, ST2 &&s2)
310{
311        return stream<T>::zipwith(std::plus<T>(), std::forward<ST1>(s1), std::forward<ST2>(s2));
312}
313
314template<typename ST1, typename ST2, typename T=typename stream_value_type<ST1>::type>
315stream<T> operator -(ST1 &&s1, ST2 &&s2)
316{
317        return stream<T>::zipwith(std::minus<T>(), std::forward<ST1>(s1), std::forward<ST2>(s2));
318}
319
320template<typename ST1, typename ST2, typename T=typename stream_value_type<ST1>::type>
321stream<T> operator *(ST1 &&s1, ST2 &&s2)
322{
323        return stream<T>::zipwith(std::multiplies<T>(), std::forward<ST1>(s1), std::forward<ST2>(s2));
324}
325
326template<typename ST1, typename ST2, typename T=typename stream_value_type<ST1>::type>
327stream<T> operator /(ST1 &&s1, ST2 &&s2)
328{
329        return stream<T>::zipwith(std::divides<T>(), std::forward<ST1>(s1), std::forward<ST2>(s2));
330}
331
332template<typename ST1, typename ST2, typename T=typename stream_value_type<ST1>::type>
333stream<T> operator %(ST1 &&s1, ST2 &&s2)
334{
335        return stream<T>::zipwith(std::modulus<T>(), std::forward<ST1>(s1), std::forward<ST2>(s2));
336}
337
338template<typename ST, typename T=typename stream_value_type<ST>::type>
339stream<T> operator -(ST &&s)
340{
341        return stream<T>::map(std::negate<T>(), std::forward<ST>(s));
342}
343
344#ifdef HAVE_LITERALS
345
346struct stream_proxy
347{
348        stream_proxy(unsigned long long i): x(i) {}
349        template <typename T>
350        operator stream<T> () {
351                stream<T> a = static_cast<T>(x)<<=a;
352                return a;
353        }
354        unsigned long long x;
355};
356
357stream_proxy operator "" _s (unsigned long long i)
358{
359        return stream_proxy(i);
360}
361
362#endif//HAVE_LITERALS
363
364#endif//__stream_h__
Note: See TracBrowser for help on using the repository browser.