Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r54305 - in sandbox/fiber: boost boost/fiber boost/fiber/detail libs/fiber libs/fiber/build libs/fiber/doc libs/fiber/test
From: oliver.kowalke_at_[hidden]
Date: 2009-06-24 11:21:17


Author: olli
Date: 2009-06-24 11:21:16 EDT (Wed, 24 Jun 2009)
New Revision: 54305
URL: http://svn.boost.org/trac/boost/changeset/54305

Log:
* initial import

Added:
   sandbox/fiber/boost/fiber/
   sandbox/fiber/boost/fiber.hpp (contents, props changed)
   sandbox/fiber/boost/fiber/context.hpp (contents, props changed)
   sandbox/fiber/boost/fiber/detail/
   sandbox/fiber/boost/fiber/detail/context.hpp (contents, props changed)
   sandbox/fiber/boost/fiber/detail/fiber_base.hpp (contents, props changed)
   sandbox/fiber/boost/fiber/detail/fiber_base_posix.hpp (contents, props changed)
   sandbox/fiber/boost/fiber/detail/fiber_base_windows.hpp (contents, props changed)
   sandbox/fiber/boost/fiber/exceptions.hpp (contents, props changed)
   sandbox/fiber/boost/fiber/fiber.hpp (contents, props changed)
   sandbox/fiber/boost/fiber/result.hpp (contents, props changed)
   sandbox/fiber/boost/fiber/stacksize.hpp (contents, props changed)
   sandbox/fiber/boost/fiber/wrapper.hpp (contents, props changed)
   sandbox/fiber/libs/fiber/
   sandbox/fiber/libs/fiber/build/
   sandbox/fiber/libs/fiber/doc/
   sandbox/fiber/libs/fiber/test/

Added: sandbox/fiber/boost/fiber.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber.hpp 2009-06-24 11:21:16 EDT (Wed, 24 Jun 2009)
@@ -0,0 +1,16 @@
+// Copyright (c) 2008 Oliver Kowalke. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_FIBERS_FIBERS_H
+#define BOOST_FIBERS_FIBERS_H
+
+#include <boost/fibers/fiber.hpp>
+#include <boost/fibers/context.hpp>
+#include <boost/fibers/exceptions.hpp>
+#include <boost/fibers/result.hpp>
+#include <boost/fibers/stacksize.hpp>
+#include <boost/fibers/wrapper.hpp>
+
+#endif // BOOST_FIBERS_FIBERS_H
+

Added: sandbox/fiber/boost/fiber/context.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/context.hpp 2009-06-24 11:21:16 EDT (Wed, 24 Jun 2009)
@@ -0,0 +1,18 @@
+// Copyright (c) 2008 Oliver Kowalke. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_FIBERS_CONTEXT_H
+#define BOOST_FIBERS_CONTEXT_H
+
+#include <boost/fibers/detail/context.hpp>
+#include <boost/fibers/detail/fiber_base.hpp>
+
+namespace boost {
+namespace fibers
+{
+typedef detail::context< detail::fiber_base > context;
+} }
+
+#endif // BOOST_FIBERS_CONTEXT_H
+

Added: sandbox/fiber/boost/fiber/detail/context.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/detail/context.hpp 2009-06-24 11:21:16 EDT (Wed, 24 Jun 2009)
@@ -0,0 +1,32 @@
+// Copyright (c) 2008 Oliver Kowalke. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_FIBERS_DETAIL_CONTEXT_H
+#define BOOST_FIBERS_DETAIL_CONTEXT_H
+
+namespace boost { namespace fibers {
+namespace detail
+{
+template< typename FiberBase >
+class context
+{
+private:
+ FiberBase & fib_;
+
+public:
+ context( FiberBase & fib)
+ : fib_( fib)
+ {}
+
+ void yield()
+ { fib_.yield(); }
+
+ template< typename Fiber >
+ void yield_to( Fiber & to)
+ { fib_.yield_to( * to.impl_); }
+};
+} } }
+
+#endif // BOOST_FIBERS_DETAIL_CONTEXT_H
+

Added: sandbox/fiber/boost/fiber/detail/fiber_base.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/detail/fiber_base.hpp 2009-06-24 11:21:16 EDT (Wed, 24 Jun 2009)
@@ -0,0 +1,18 @@
+// Copyright (c) 2008 Oliver Kowalke. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_FIBERS_DETAIL_FIBER_BASE_H
+#define BOOST_FIBERS_DETAIL_FIBER_BASE_H
+
+#include <boost/config.hpp>
+
+#if defined(_POSIX_VERSION)
+#include <boost/fibers/detail/fiber_base_posix.hpp>
+#elif defined(BOOST_WINDOWS)
+#include <boost/fibers/detail/fiber_base_windows.hpp>
+#else
+#error "Boost fibers unavailable on this platform"
+#endif
+
+#endif // BOOST_FIBERS_DETAIL_FIBER_BASE_H

Added: sandbox/fiber/boost/fiber/detail/fiber_base_posix.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/detail/fiber_base_posix.hpp 2009-06-24 11:21:16 EDT (Wed, 24 Jun 2009)
@@ -0,0 +1,195 @@
+// Copyright (c) 2008 Oliver Kowalke. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_FIBERS_DETAIL_FIBER_BASE_POSIX_H
+#define BOOST_FIBERS_DETAIL_FIBER_BASE_POSIX_H
+
+extern "C"
+{
+#include <ucontext.h>
+}
+
+#include <cstddef>
+#include <utility>
+
+#include <boost/assert.hpp>
+#include <boost/function.hpp>
+#include <boost/shared_array.hpp>
+#include <boost/system/system_error.hpp>
+
+#include <boost/fibers/detail/context.hpp>
+
+namespace boost { namespace fibers {
+namespace detail
+{
+template< typename Fiber >
+void trampoline( Fiber * fib)
+{
+ BOOST_ASSERT( fib);
+ context< Fiber > ctxt( * fib);
+ BOOST_ASSERT( ! fib->fn_.empty() );
+ fib->fn_( ctxt);
+ fib->exit();
+}
+
+class fiber_base
+{
+private:
+ enum st_state
+ {
+ st_uninitialized = 0,
+ st_ready = 1,
+ st_running = 2,
+ st_exited = 3
+ };
+
+ template< typename Fiber >
+ friend
+ void trampoline( Fiber *);
+
+ function< void( context< fiber_base > &) > fn_;
+ std::size_t stack_size_;
+ ::ucontext_t caller_;
+ ::ucontext_t callee_;
+ shared_array< char > stack_;
+ st_state state_;
+
+ bool uninitialized_() const
+ { return state_ == st_uninitialized; }
+
+ bool ready_() const
+ { return state_ == st_ready; }
+
+ bool running_() const
+ { return state_ == st_running; }
+
+ bool exited_() const
+ { return state_ == st_exited; }
+
+ void yield_()
+ {
+ if ( ::swapcontext( & callee_, & caller_) == -1)
+ throw system::system_error(
+ system::error_code(
+ errno,
+ system::system_category) );
+ }
+
+ void yield_to_( fiber_base & to)
+ {
+ std::swap( caller_, to.caller_);
+ std::swap( state_, to.state_);
+ if ( ::swapcontext( & callee_, & to.callee_) == -1)
+ throw system::system_error(
+ system::error_code(
+ errno,
+ system::system_category) );
+ }
+
+ void run_()
+ {
+ if ( ::swapcontext( & caller_, & callee_) == -1)
+ throw system::system_error(
+ system::error_code(
+ errno,
+ system::system_category) );
+ }
+
+ void init_()
+ {
+ BOOST_ASSERT( state_ == st_uninitialized);
+
+ if ( ::getcontext( & caller_) == -1)
+ throw system::system_error(
+ system::error_code(
+ errno,
+ system::system_category) );
+ BOOST_ASSERT( stack_);
+ if ( ::getcontext( & callee_) == -1)
+ throw system::system_error(
+ system::error_code(
+ errno,
+ system::system_category) );
+ callee_.uc_stack.ss_sp = stack_.get();
+ callee_.uc_stack.ss_size = stack_size_;
+ callee_.uc_link = 0;
+ typedef void fn_type( fiber_base *);
+ typedef void ( * st_fn)();
+ fn_type * fn_ptr( trampoline< fiber_base >);
+
+ ::makecontext(
+ & callee_,
+ ( st_fn)( fn_ptr),
+ 1,
+ this);
+
+ state_ = st_ready;
+ }
+
+public:
+ fiber_base(
+ function< void( context< fiber_base > &) > fn,
+ std::size_t stack_size)
+ :
+ fn_( fn),
+ stack_size_( stack_size),
+ caller_(),
+ callee_(),
+ stack_( new char[stack_size]),
+ state_( st_uninitialized)
+ {
+ BOOST_ASSERT( ! fn_.empty() );
+ BOOST_ASSERT( stack_size_ > 0);
+ }
+
+ ~fiber_base()
+ { BOOST_ASSERT( ! running_() ); }
+
+ bool ready() const
+ { return uninitialized_() || ready_(); }
+
+ bool running() const
+ { return running_(); }
+
+ bool exited() const
+ { return exited_(); }
+
+ void yield()
+ {
+ BOOST_ASSERT( running_() );
+ state_ = st_ready;
+ yield_();
+ BOOST_ASSERT( running_() );
+ }
+
+ void yield_to( fiber_base & to)
+ {
+ BOOST_ASSERT( running_() );
+ if ( to.uninitialized_() ) to.init_();
+ yield_to_( to);
+ BOOST_ASSERT( running_() );
+ }
+
+ void run()
+ {
+ BOOST_ASSERT( uninitialized_() || ready_() );
+ if ( uninitialized_() ) init_();
+ BOOST_ASSERT( ready_() );
+ state_ = st_running;
+ run_();
+ BOOST_ASSERT( ready_() || exited_() );
+ }
+
+ void exit()
+ {
+ BOOST_ASSERT( running_() ) ;
+ state_ = st_exited;
+ yield_();
+ BOOST_ASSERT(!"should never be reached");
+ }
+};
+} } }
+
+#endif // BOOST_FIBERS_DETAIL_FIBER_BASE_POSIX_H
+

Added: sandbox/fiber/boost/fiber/detail/fiber_base_windows.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/detail/fiber_base_windows.hpp 2009-06-24 11:21:16 EDT (Wed, 24 Jun 2009)
@@ -0,0 +1,255 @@
+// Copyright (c) 2008 Oliver Kowalke. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_FIBERS_DETAIL_FIBER_BASE_WINDOWS_H
+#define BOOST_FIBERS_DETAIL_FIBER_BASE_WINDOWS_H
+
+extern "C"
+{
+#include <windows.h>
+#include <winnt.h>
+}
+
+#include <cstddef>
+
+#include <boost/assert.hpp>
+#include <boost/function.hpp>
+#include <boost/system/system_error.hpp>
+
+#include <boost/fibers/detail/context.hpp>
+
+namespace boost { namespace fibers {
+namespace detail
+{
+template< typename Fiber >
+VOID CALLBACK trampoline( LPVOID vp)
+{
+ Fiber * fib( static_cast< Fiber * >( vp) );
+ BOOST_ASSERT( fib);
+ context< Fiber > ctxt( * fib);
+ BOOST_ASSERT( ! fib->fn_.empty() );
+ fib->fn_( ctxt);
+ fib->exit();
+}
+
+class fiber_base
+{
+private:
+ enum st_state
+ {
+ st_uninitialized = 0,
+ st_ready = 1,
+ st_running = 2,
+ st_exited = 3
+ };
+
+ template< typename Fiber >
+ friend
+ VOID CALLBACK trampoline( LPVOID);
+
+ function< void( context< fiber_base > &) > fn_;
+ std::size_t stack_size_;
+ LPVOID caller_;
+ LPVOID callee_;
+ st_state state_;
+
+ bool uninitialized_() const
+ { return state_ == st_uninitialized; }
+
+ bool ready_() const
+ { return state_ == st_ready; }
+
+ bool running_() const
+ { return state_ == st_running; }
+
+ bool exited_() const
+ { return state_ == st_exited; }
+
+ bool is_fiber_()
+ {
+#if (_WIN32_WINNT >= 0x0600)
+ return ::IsThreadAFiber() == TRUE;
+#else
+ LPVOID current( ::GetCurrentFiber() );
+ return current != 0 && current != reinterpret_cast< LPVOID >( 0x1E00);
+#endif
+ }
+
+ void yield_()
+ {
+ if( ! is_fiber_() )
+ {
+ BOOST_ASSERT( ! callee_);
+ callee_ = ::ConvertThreadToFiber( 0);
+ if ( ! callee_)
+ throw system::system_error(
+ system::error_code(
+ ::GetLastError(),
+ system::system_category) );
+ ::SwitchToFiber( caller_);
+ BOOL result = ::ConvertFiberToThread();
+ if ( ! result)
+ throw system::system_error(
+ system::error_code(
+ ::GetLastError(),
+ system::system_category) );
+ caller_ = 0;
+ }
+ else
+ {
+ if ( ! callee_)
+ callee_ = ::GetCurrentFiber();
+ ::SwitchToFiber( caller_);
+ if ( ! callee_)
+ callee_ = 0;
+ }
+ }
+
+ void yield_to_( fiber_base & to)
+ {
+ std::swap( caller_, to.caller_);
+ std::swap( state_, to.state_);
+ if( ! is_fiber_() )
+ {
+ BOOST_ASSERT( ! callee_);
+ callee_ = ::ConvertThreadToFiber( 0);
+ if ( ! callee_)
+ throw system::system_error(
+ system::error_code(
+ ::GetLastError(),
+ system::system_category) );
+ ::SwitchToFiber( to.callee_);
+ BOOL result = ::ConvertFiberToThread();
+ if ( ! result)
+ throw system::system_error(
+ system::error_code(
+ ::GetLastError(),
+ system::system_category) );
+ caller_ = 0;
+ }
+ else
+ {
+ if ( ! callee_)
+ callee_ = ::GetCurrentFiber();
+ ::SwitchToFiber( to.callee_);
+ if ( ! callee_)
+ callee_ = 0;
+ }
+ }
+
+ void run_()
+ {
+ if( ! is_fiber_() )
+ {
+ BOOST_ASSERT( ! caller_);
+ caller_ = ::ConvertThreadToFiber( 0);
+ if ( ! caller_)
+ throw system::system_error(
+ system::error_code(
+ ::GetLastError(),
+ system::system_category) );
+ ::SwitchToFiber( callee_);
+ BOOL result = ::ConvertFiberToThread();
+ if ( ! result)
+ throw system::system_error(
+ system::error_code(
+ ::GetLastError(),
+ system::system_category) );
+ caller_ = 0;
+ }
+ else
+ {
+ if ( ! caller_)
+ caller_ = ::GetCurrentFiber();
+ ::SwitchToFiber( callee_);
+ if ( ! caller_)
+ caller_ = 0;
+ }
+ }
+
+ void init_()
+ {
+ BOOST_ASSERT( state_ == st_uninitialized);
+
+ callee_ = ::CreateFiber(
+ stack_size_,
+ static_cast< LPFIBER_START_ROUTINE >( & trampoline< fiber_base >),
+ static_cast< LPVOID >( this) );
+ if ( ! callee_)
+ throw system::system_error(
+ system::error_code(
+ ::GetLastError(),
+ system::system_category) );
+
+ state_ = st_ready;
+ }
+
+public:
+ fiber_base(
+ function< void( context< fiber_base > &) > fn,
+ std::size_t stack_size)
+ :
+ fn_( fn),
+ stack_size_( stack_size),
+ caller_( 0),
+ callee_( 0),
+ state_( st_uninitialized)
+ {
+ BOOST_ASSERT( ! fn_.empty() );
+ BOOST_ASSERT( stack_size_ > 0);
+ }
+
+ ~fiber_base()
+ {
+ BOOST_ASSERT( ! running_() );
+ ::DeleteFiber( callee_);
+ }
+
+ bool ready() const
+ { return uninitialized_() || ready_(); }
+
+ bool running() const
+ { return running_(); }
+
+ bool exited() const
+ { return exited_(); }
+
+ void yield()
+ {
+ BOOST_ASSERT( running_() );
+ state_ = st_ready;
+ yield_();
+ BOOST_ASSERT( running_() );
+ }
+
+ void yield_to( fiber_base & to)
+ {
+ BOOST_ASSERT( running_() );
+ if ( to.uninitialized_() ) to.init_();
+ yield_to_( to);
+ BOOST_ASSERT( running_() );
+ }
+
+ void run()
+ {
+ BOOST_ASSERT( uninitialized_() || ready_() );
+ if ( uninitialized_() ) init_();
+ BOOST_ASSERT( ready_() );
+ state_ = st_running;
+ run_();
+ BOOST_ASSERT( ready_() || exited_() );
+ }
+
+ void exit()
+ {
+ BOOST_ASSERT( running_() || ready_() ) ;
+ state_ = st_exited;
+ yield_();
+ BOOST_ASSERT(!"should never be reached");
+ }
+};
+} } }
+
+#endif // BOOST_FIBERS_DETAIL_FIBER_BASE_WINDOWS_H
+

Added: sandbox/fiber/boost/fiber/exceptions.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/exceptions.hpp 2009-06-24 11:21:16 EDT (Wed, 24 Jun 2009)
@@ -0,0 +1,24 @@
+// Copyright (c) 2008 Oliver Kowalke. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_FIBERS_EXCEPTIONS_H
+#define BOOST_FIBERS_EXCEPTIONS_H
+
+#include <stdexcept>
+#include <string>
+
+namespace boost {
+namespace fibers
+{
+class invalid_stacksize
+: public std::invalid_argument
+{
+public:
+ invalid_stacksize( std::string const& msg)
+ : std::invalid_argument( msg)
+ {}
+};
+} }
+
+#endif // BOOST_FIBERS_EXCEPTIONS_H

Added: sandbox/fiber/boost/fiber/fiber.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/fiber.hpp 2009-06-24 11:21:16 EDT (Wed, 24 Jun 2009)
@@ -0,0 +1,60 @@
+// Copyright (c) 2008 Oliver Kowalke. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_FIBERS_FIBER_H
+#define BOOST_FIBERS_FIBER_H
+
+#include <boost/bind.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/fibers/detail/fiber_base.hpp>
+#include <boost/fibers/stacksize.hpp>
+
+namespace boost {
+namespace fibers
+{
+class fiber
+: private noncopyable
+{
+private:
+ template< typename Fiber >
+ friend
+ class detail::context;
+
+ shared_ptr< detail::fiber_base > impl_;
+
+public:
+ enum { default_stack_size = 16384 };
+
+ template< typename Act >
+ fiber(
+ Act act,
+ stacksize const& stack_size = stacksize( default_stack_size) )
+ : impl_( new detail::fiber_base( act, stack_size) )
+ {}
+
+ bool exited() const
+ { return impl_->exited(); }
+
+ bool ready() const
+ { return impl_->ready(); }
+
+ bool running() const
+ { return impl_->running(); }
+
+ void run()
+ { impl_->run(); }
+
+ void yield()
+ { impl_->yield(); }
+
+ void yield_to( fiber & to)
+ { impl_->yield_to( * to.impl_); }
+};
+
+} }
+
+#endif // BOOST_FIBERS_FIBER_H
+

Added: sandbox/fiber/boost/fiber/result.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/result.hpp 2009-06-24 11:21:16 EDT (Wed, 24 Jun 2009)
@@ -0,0 +1,235 @@
+// Copyright (c) 2008 Oliver Kowalke. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_FIBERS_RESULT_H
+#define BOOST_FIBERS_RESULT_H
+
+#include <boost/exception.hpp>
+#include <boost/exception_ptr.hpp>
+#include <boost/function.hpp>
+#include <boost/thread.hpp>
+
+#include <boost/fibers/context.hpp>
+
+namespace boost {
+namespace fibers
+{
+#define CATCH_ENABLE_CURRENT_EXCEPTION( Exception) \
+ catch ( Exception const& e) \
+ { throw boost::enable_current_exception( e); }
+
+template< typename R >
+class result
+{
+private:
+ struct impl
+ {
+ virtual ~impl() {}
+ virtual void operator()( context &) = 0;
+ virtual bool ready() const = 0;
+ virtual bool has_value() const = 0;
+ virtual bool has_exception() const = 0;
+ virtual R get() const = 0;
+ };
+
+ template< typename Act >
+ class impl_wrapper
+ : public impl
+ {
+ private:
+ Act act_;
+ R r_;
+ bool ready_;
+ exception_ptr except_ptr_;
+
+ public:
+ impl_wrapper( Act const& act)
+ :
+ act_( act),
+ r_(),
+ ready_( false),
+ except_ptr_()
+ {}
+
+ void operator()( context & ctxt)
+ {
+ try
+ {
+ try
+ { r_ = act_( ctxt); }
+ CATCH_ENABLE_CURRENT_EXCEPTION( thread_interrupted )
+ CATCH_ENABLE_CURRENT_EXCEPTION( exception )
+
+ CATCH_ENABLE_CURRENT_EXCEPTION( std::domain_error )
+ CATCH_ENABLE_CURRENT_EXCEPTION( std::invalid_argument )
+ CATCH_ENABLE_CURRENT_EXCEPTION( std::length_error )
+ CATCH_ENABLE_CURRENT_EXCEPTION( std::out_of_range )
+ CATCH_ENABLE_CURRENT_EXCEPTION( std::logic_error )
+
+ CATCH_ENABLE_CURRENT_EXCEPTION( std::overflow_error )
+ CATCH_ENABLE_CURRENT_EXCEPTION( std::range_error )
+ CATCH_ENABLE_CURRENT_EXCEPTION( std::underflow_error)
+ CATCH_ENABLE_CURRENT_EXCEPTION( std::runtime_error )
+
+ CATCH_ENABLE_CURRENT_EXCEPTION( std::bad_alloc )
+ CATCH_ENABLE_CURRENT_EXCEPTION( std::bad_cast )
+ CATCH_ENABLE_CURRENT_EXCEPTION( std::bad_typeid )
+ CATCH_ENABLE_CURRENT_EXCEPTION( std::bad_exception )
+
+ // iostreams library
+ CATCH_ENABLE_CURRENT_EXCEPTION( std::ios_base::failure )
+ }
+ catch ( ... )
+ { except_ptr_ = current_exception(); }
+ ready_ = true;
+ }
+
+ bool ready() const
+ { return ready_; }
+
+ bool has_value() const
+ { return ready() && ! except_ptr_; }
+
+ bool has_exception() const
+ { return ready() && except_ptr_; }
+
+ R get() const
+ {
+ if ( except_ptr_) rethrow_exception( except_ptr_);
+ return r_;
+ }
+ };
+
+ shared_ptr< impl > impl_;
+
+public:
+ template< typename Act >
+ result( Act act)
+ : impl_( new impl_wrapper< Act >( act) )
+ {}
+
+ void operator()( context & ctxt)
+ { ( * impl_)( ctxt); }
+
+ bool ready() const
+ { return impl_->ready(); }
+
+ bool has_value() const
+ { return impl_->has_value(); }
+
+ bool has_exception() const
+ { return impl_->has_exception(); }
+
+ R get() const
+ { return impl_->get(); }
+};
+
+
+template<>
+class result< void >
+{
+private:
+ struct impl
+ {
+ virtual ~impl() {}
+ virtual void operator()( context &) = 0;
+ virtual bool ready() const = 0;
+ virtual bool has_value() const = 0;
+ virtual bool has_exception() const = 0;
+ virtual void get() const = 0;
+ };
+
+ template< typename Act >
+ class impl_wrapper
+ : public impl
+ {
+ private:
+ Act act_;
+ bool ready_;
+ exception_ptr except_ptr_;
+
+ public:
+ impl_wrapper( Act const& act)
+ :
+ act_( act),
+ ready_( false),
+ except_ptr_()
+ {}
+
+ void operator()( context & ctxt)
+ {
+ try
+ {
+ try
+ { act_( ctxt); }
+ CATCH_ENABLE_CURRENT_EXCEPTION( thread_interrupted )
+ CATCH_ENABLE_CURRENT_EXCEPTION( exception )
+
+ CATCH_ENABLE_CURRENT_EXCEPTION( std::overflow_error )
+ CATCH_ENABLE_CURRENT_EXCEPTION( std::range_error )
+ CATCH_ENABLE_CURRENT_EXCEPTION( std::underflow_error)
+ CATCH_ENABLE_CURRENT_EXCEPTION( std::runtime_error )
+
+ // logic_error standard subclasses
+ CATCH_ENABLE_CURRENT_EXCEPTION( std::domain_error )
+ CATCH_ENABLE_CURRENT_EXCEPTION( std::invalid_argument )
+ CATCH_ENABLE_CURRENT_EXCEPTION( std::length_error )
+ CATCH_ENABLE_CURRENT_EXCEPTION( std::out_of_range )
+ CATCH_ENABLE_CURRENT_EXCEPTION( std::logic_error )
+
+ CATCH_ENABLE_CURRENT_EXCEPTION( std::bad_alloc )
+ CATCH_ENABLE_CURRENT_EXCEPTION( std::bad_cast )
+ CATCH_ENABLE_CURRENT_EXCEPTION( std::bad_typeid )
+ CATCH_ENABLE_CURRENT_EXCEPTION( std::bad_exception )
+
+ // iostreams library
+ CATCH_ENABLE_CURRENT_EXCEPTION( std::ios_base::failure )
+ }
+ catch ( ... )
+ { except_ptr_ = current_exception(); }
+ ready_ = true;
+ }
+
+ bool ready() const
+ { return ready_; }
+
+ bool has_value() const
+ { return ready() && ! except_ptr_; }
+
+ bool has_exception() const
+ { return ready() && except_ptr_; }
+
+ void get() const
+ { if ( except_ptr_) rethrow_exception( except_ptr_); }
+ };
+
+ shared_ptr< impl > impl_;
+
+public:
+ template< typename Act >
+ result( Act act)
+ : impl_( new impl_wrapper< Act >( act) )
+ {}
+
+ void operator()( context & ctxt)
+ { ( * impl_)( ctxt); }
+
+ bool ready() const
+ { return impl_->ready(); }
+
+ bool has_value() const
+ { return impl_->has_value(); }
+
+ bool has_exception() const
+ { return impl_->has_exception(); }
+
+ void get() const
+ { impl_->get(); }
+};
+
+#undef CATCH_ENABLE_CURRENT_EXCEPTION
+} }
+
+#endif // BOOST_FIBERS_RESULT_H
+

Added: sandbox/fiber/boost/fiber/stacksize.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/stacksize.hpp 2009-06-24 11:21:16 EDT (Wed, 24 Jun 2009)
@@ -0,0 +1,30 @@
+// Copyright (c) 2008 Oliver Kowalke. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_FIBERS_STACKSIZE_H
+#define BOOST_FIBERS_STACKSIZE_H
+
+#include <cstddef>
+
+#include <boost/fibers/exceptions.hpp>
+
+namespace boost {
+namespace fibers
+{
+class stacksize
+{
+private:
+ std::size_t value_;
+
+public:
+ explicit stacksize( std::size_t value)
+ : value_( value)
+ { if ( value <= 0) throw invalid_stacksize("stacksize must be greater than zero"); }
+
+ operator std::size_t () const
+ { return value_; }
+};
+} }
+
+#endif // BOOST_FIBERS_STACKSIZE_H

Added: sandbox/fiber/boost/fiber/wrapper.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/wrapper.hpp 2009-06-24 11:21:16 EDT (Wed, 24 Jun 2009)
@@ -0,0 +1,34 @@
+// Copyright (c) 2008 Oliver Kowalke. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_FIBERS_WRAPPER_H
+#define BOOST_FIBERS_WRAPPER_H
+
+#include <boost/fibers/context.hpp>
+
+namespace boost {
+namespace fibers
+{
+template< typename Act >
+class wrapper
+{
+private:
+ Act act_;
+
+public:
+ wrapper( Act act)
+ : act_( act)
+ {}
+
+ typename Act::result_type operator()( context &)
+ { return act_(); }
+};
+
+template< typename Act >
+wrapper< Act > wrap( Act act)
+{ return wrapper< Act >( act); }
+} }
+
+#endif // BOOST_FIBERS_WRAPPER_H
+


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk