~ai.tron/armagetronad/0.4-winlibs-updated

« back to all changes in this revision

Viewing changes to boost/includes/boost/coroutine/v1/detail/coroutine_object_result_0.ipp

  • Committer: Nik K.
  • Date: 2013-11-07 16:58:35 UTC
  • Revision ID: nik.karbaum@gmail.com-20131107165835-kq99jz23drfj4dkh
Forgot to add some files; here they are

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
//          Copyright Oliver Kowalke 2009.
 
3
// Distributed under the Boost Software License, Version 1.0.
 
4
//    (See accompanying file LICENSE_1_0.txt or copy at
 
5
//          http://www.boost.org/LICENSE_1_0.txt)
 
6
 
 
7
template<
 
8
    typename Signature,
 
9
    typename Fn, typename StackAllocator, typename Allocator,
 
10
    typename Caller,
 
11
    typename Result
 
12
>
 
13
class coroutine_object< Signature, Fn, StackAllocator, Allocator, Caller, Result, 0 > :
 
14
    private stack_tuple< StackAllocator >,
 
15
    public coroutine_base< Signature >
 
16
{
 
17
public:
 
18
    typedef typename Allocator::template rebind<
 
19
        coroutine_object<
 
20
            Signature, Fn, StackAllocator, Allocator, Caller, Result, 0
 
21
        >
 
22
    >::other                                            allocator_t;
 
23
 
 
24
private:
 
25
    typedef stack_tuple< StackAllocator >               pbase_type;
 
26
    typedef coroutine_base< Signature >                 base_type;
 
27
 
 
28
    Fn                      fn_;
 
29
    allocator_t             alloc_;
 
30
 
 
31
    static void destroy_( allocator_t & alloc, coroutine_object * p)
 
32
    {
 
33
        alloc.destroy( p);
 
34
        alloc.deallocate( p, 1);
 
35
    }
 
36
 
 
37
    coroutine_object( coroutine_object const&);
 
38
    coroutine_object & operator=( coroutine_object const&);
 
39
 
 
40
    void enter_()
 
41
    {
 
42
        holder< Result > * hldr_from(
 
43
            reinterpret_cast< holder< Result > * >(
 
44
                this->caller_.jump(
 
45
                    this->callee_,
 
46
                    reinterpret_cast< intptr_t >( this),
 
47
                    this->preserve_fpu() ) ) );
 
48
        this->callee_ = * hldr_from->ctx;
 
49
        this->result_ = hldr_from->data;
 
50
        if ( this->except_) rethrow_exception( this->except_);
 
51
    }
 
52
 
 
53
    void unwind_stack_() BOOST_NOEXCEPT
 
54
    {
 
55
        BOOST_ASSERT( ! this->is_complete() );
 
56
 
 
57
        this->flags_ |= flag_unwind_stack;
 
58
        holder< void > hldr_to( & this->caller_, true);
 
59
        this->caller_.jump(
 
60
            this->callee_,
 
61
            reinterpret_cast< intptr_t >( & hldr_to),
 
62
            this->preserve_fpu() );
 
63
        this->flags_ &= ~flag_unwind_stack;
 
64
 
 
65
        BOOST_ASSERT( this->is_complete() );
 
66
    }
 
67
 
 
68
public:
 
69
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
 
70
    coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
 
71
                      StackAllocator const& stack_alloc,
 
72
                      allocator_t const& alloc) :
 
73
        pbase_type( stack_alloc, attr.size),
 
74
        base_type(
 
75
            trampoline1< coroutine_object >,
 
76
            & this->stack_ctx,
 
77
            stack_unwind == attr.do_unwind,
 
78
            fpu_preserved == attr.preserve_fpu),
 
79
        fn_( forward< Fn >( fn) ),
 
80
        alloc_( alloc)
 
81
    { enter_(); }
 
82
#else
 
83
    coroutine_object( Fn fn, attributes const& attr,
 
84
                      StackAllocator const& stack_alloc,
 
85
                      allocator_t const& alloc) :
 
86
        pbase_type( stack_alloc, attr.size),
 
87
        base_type(
 
88
            trampoline1< coroutine_object >,
 
89
            & this->stack_ctx,
 
90
            stack_unwind == attr.do_unwind,
 
91
            fpu_preserved == attr.preserve_fpu),
 
92
        fn_( fn),
 
93
        alloc_( alloc)
 
94
    { enter_(); }
 
95
 
 
96
    coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
 
97
                      StackAllocator const& stack_alloc,
 
98
                      allocator_t const& alloc) :
 
99
        pbase_type( stack_alloc, attr.size),
 
100
        base_type(
 
101
            trampoline1< coroutine_object >,
 
102
            & this->stack_ctx,
 
103
            stack_unwind == attr.do_unwind,
 
104
            fpu_preserved == attr.preserve_fpu),
 
105
        fn_( fn),
 
106
        alloc_( alloc)
 
107
    { enter_(); }
 
108
#endif
 
109
 
 
110
    ~coroutine_object()
 
111
    {
 
112
        if ( ! this->is_complete() && this->force_unwind() )
 
113
            unwind_stack_();
 
114
    }
 
115
 
 
116
    void run()
 
117
    {
 
118
        coroutine_context callee;
 
119
        coroutine_context caller;
 
120
 
 
121
        {
 
122
            Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
 
123
            try
 
124
            { fn_( c); }
 
125
            catch ( forced_unwind const&)
 
126
            {}
 
127
            catch (...)
 
128
            { this->except_ = current_exception(); }
 
129
            callee = c.impl_->callee_;
 
130
        }
 
131
 
 
132
        this->flags_ |= flag_complete;
 
133
        holder< Result > hldr_to( & caller);
 
134
        caller.jump(
 
135
            callee,
 
136
            reinterpret_cast< intptr_t >( & hldr_to),
 
137
            this->preserve_fpu() );
 
138
        BOOST_ASSERT_MSG( false, "coroutine is complete");
 
139
    }
 
140
 
 
141
    void deallocate_object()
 
142
    { destroy_( alloc_, this); }
 
143
};
 
144
 
 
145
template<
 
146
    typename Signature,
 
147
    typename Fn, typename StackAllocator, typename Allocator,
 
148
    typename Caller,
 
149
    typename Result
 
150
>
 
151
class coroutine_object< Signature, reference_wrapper< Fn >, StackAllocator, Allocator, Caller, Result, 0 > :
 
152
    private stack_tuple< StackAllocator >,
 
153
    public coroutine_base< Signature >
 
154
{
 
155
public:
 
156
    typedef typename Allocator::template rebind<
 
157
        coroutine_object<
 
158
            Signature, Fn, StackAllocator, Allocator, Caller, Result, 0
 
159
        >
 
160
    >::other                                            allocator_t;
 
161
 
 
162
private:
 
163
    typedef stack_tuple< StackAllocator >               pbase_type;
 
164
    typedef coroutine_base< Signature >                 base_type;
 
165
 
 
166
    Fn                      fn_;
 
167
    allocator_t             alloc_;
 
168
 
 
169
    static void destroy_( allocator_t & alloc, coroutine_object * p)
 
170
    {
 
171
        alloc.destroy( p);
 
172
        alloc.deallocate( p, 1);
 
173
    }
 
174
 
 
175
    coroutine_object( coroutine_object const&);
 
176
    coroutine_object & operator=( coroutine_object const&);
 
177
 
 
178
    void enter_()
 
179
    {
 
180
        holder< Result > * hldr_from(
 
181
            reinterpret_cast< holder< Result > * >(
 
182
                this->caller_.jump(
 
183
                    this->callee_,
 
184
                    reinterpret_cast< intptr_t >( this),
 
185
                    this->preserve_fpu() ) ) );
 
186
        this->callee_ = * hldr_from->ctx;
 
187
        this->result_ = hldr_from->data;
 
188
        if ( this->except_) rethrow_exception( this->except_);
 
189
    }
 
190
 
 
191
    void unwind_stack_() BOOST_NOEXCEPT
 
192
    {
 
193
        BOOST_ASSERT( ! this->is_complete() );
 
194
 
 
195
        this->flags_ |= flag_unwind_stack;
 
196
        holder< void > hldr_to( & this->caller_, true);
 
197
        this->caller_.jump(
 
198
            this->callee_,
 
199
            reinterpret_cast< intptr_t >( & hldr_to),
 
200
            this->preserve_fpu() );
 
201
        this->flags_ &= ~flag_unwind_stack;
 
202
 
 
203
        BOOST_ASSERT( this->is_complete() );
 
204
    }
 
205
 
 
206
public:
 
207
    coroutine_object( reference_wrapper< Fn > fn, attributes const& attr,
 
208
                      StackAllocator const& stack_alloc,
 
209
                      allocator_t const& alloc) :
 
210
        pbase_type( stack_alloc, attr.size),
 
211
        base_type(
 
212
            trampoline1< coroutine_object >,
 
213
            & this->stack_ctx,
 
214
            stack_unwind == attr.do_unwind,
 
215
            fpu_preserved == attr.preserve_fpu),
 
216
        fn_( fn),
 
217
        alloc_( alloc)
 
218
    { enter_(); }
 
219
 
 
220
    ~coroutine_object()
 
221
    {
 
222
        if ( ! this->is_complete() && this->force_unwind() )
 
223
            unwind_stack_();
 
224
    }
 
225
 
 
226
    void run()
 
227
    {
 
228
        coroutine_context callee;
 
229
        coroutine_context caller;
 
230
 
 
231
        {
 
232
            Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
 
233
            try
 
234
            { fn_( c); }
 
235
            catch ( forced_unwind const&)
 
236
            {}
 
237
            catch (...)
 
238
            { this->except_ = current_exception(); }
 
239
            callee = c.impl_->callee_;
 
240
        }
 
241
 
 
242
        this->flags_ |= flag_complete;
 
243
        holder< Result > hldr_to( & caller);
 
244
        caller.jump(
 
245
            callee,
 
246
            reinterpret_cast< intptr_t >( & hldr_to),
 
247
            this->preserve_fpu() );
 
248
        BOOST_ASSERT_MSG( false, "coroutine is complete");
 
249
    }
 
250
 
 
251
    void deallocate_object()
 
252
    { destroy_( alloc_, this); }
 
253
};
 
254
 
 
255
template<
 
256
    typename Signature,
 
257
    typename Fn, typename StackAllocator, typename Allocator,
 
258
    typename Caller,
 
259
    typename Result
 
260
>
 
261
class coroutine_object< Signature, const reference_wrapper< Fn >, StackAllocator, Allocator, Caller, Result, 0 > :
 
262
    private stack_tuple< StackAllocator >,
 
263
    public coroutine_base< Signature >
 
264
{
 
265
public:
 
266
    typedef typename Allocator::template rebind<
 
267
        coroutine_object<
 
268
            Signature, Fn, StackAllocator, Allocator, Caller, Result, 0
 
269
        >
 
270
    >::other                                            allocator_t;
 
271
 
 
272
private:
 
273
    typedef stack_tuple< StackAllocator >               pbase_type;
 
274
    typedef coroutine_base< Signature >                 base_type;
 
275
 
 
276
    Fn                      fn_;
 
277
    allocator_t             alloc_;
 
278
 
 
279
    static void destroy_( allocator_t & alloc, coroutine_object * p)
 
280
    {
 
281
        alloc.destroy( p);
 
282
        alloc.deallocate( p, 1);
 
283
    }
 
284
 
 
285
    coroutine_object( coroutine_object const&);
 
286
    coroutine_object & operator=( coroutine_object const&);
 
287
 
 
288
    void enter_()
 
289
    {
 
290
        holder< Result > * hldr_from(
 
291
            reinterpret_cast< holder< Result > * >(
 
292
                this->caller_.jump(
 
293
                    this->callee_,
 
294
                    reinterpret_cast< intptr_t >( this),
 
295
                    this->preserve_fpu() ) ) );
 
296
        this->callee_ = hldr_from->ctx;
 
297
        this->result_ = hldr_from->data;
 
298
        if ( this->except_) rethrow_exception( this->except_);
 
299
    }
 
300
 
 
301
    void unwind_stack_() BOOST_NOEXCEPT
 
302
    {
 
303
        BOOST_ASSERT( ! this->is_complete() );
 
304
 
 
305
        this->flags_ |= flag_unwind_stack;
 
306
        holder< void > hldr_to( & this->caller_, true);
 
307
        this->caller_.jump(
 
308
            this->callee_,
 
309
            reinterpret_cast< intptr_t >( & hldr_to),
 
310
            this->preserve_fpu() );
 
311
        this->flags_ &= ~flag_unwind_stack;
 
312
 
 
313
        BOOST_ASSERT( this->is_complete() );
 
314
    }
 
315
 
 
316
public:
 
317
    coroutine_object( const reference_wrapper< Fn > fn, attributes const& attr,
 
318
                      StackAllocator const& stack_alloc,
 
319
                      allocator_t const& alloc) :
 
320
        pbase_type( stack_alloc, attr.size),
 
321
        base_type(
 
322
            trampoline1< coroutine_object >,
 
323
            & this->stack_ctx,
 
324
            stack_unwind == attr.do_unwind,
 
325
            fpu_preserved == attr.preserve_fpu),
 
326
        fn_( fn),
 
327
        alloc_( alloc)
 
328
    { enter_(); }
 
329
 
 
330
    ~coroutine_object()
 
331
    {
 
332
        if ( ! this->is_complete() && this->force_unwind() )
 
333
            unwind_stack_();
 
334
    }
 
335
 
 
336
    void run()
 
337
    {
 
338
        coroutine_context callee;
 
339
        coroutine_context caller;
 
340
 
 
341
        {
 
342
            Caller c( & this->caller_, false, this->preserve_fpu(), alloc_);
 
343
            try
 
344
            { fn_( c); }
 
345
            catch ( forced_unwind const&)
 
346
            {}
 
347
            catch (...)
 
348
            { this->except_ = current_exception(); }
 
349
            callee = c.impl_->callee_;
 
350
        }
 
351
 
 
352
        this->flags_ |= flag_complete;
 
353
        holder< Result > hldr_to( & caller);
 
354
        caller.jump(
 
355
            callee,
 
356
            reinterpret_cast< intptr_t >( & hldr_to),
 
357
            this->preserve_fpu() );
 
358
        BOOST_ASSERT_MSG( false, "coroutine is complete");
 
359
    }
 
360
 
 
361
    void deallocate_object()
 
362
    { destroy_( alloc_, this); }
 
363
};