9 #ifndef ADOBE_FUNCTION_HPP
10 #define ADOBE_FUNCTION_HPP
15 #include <tr1/functional>
16 #include <tr1/type_traits>
18 #include <boost/bind.hpp>
33 const char*
what()
const throw() {
return message_m.
c_str(); }
39 const char* result =
"unknown_exception";
42 catch (
const std::exception& error) {
43 if (error.what()) result = error.what();
54 namespace implementation {
63 operator bool()
const {
return self()->object_m; }
72 friend inline void swap(T& x, T& y) { x.swap(y); }
76 T*
self() {
return static_cast<T*
>(
this); }
77 const T*
self()
const {
return static_cast<const T*
>(
this); }
80 template <
typename Concept,
typename Apply>
83 Concept* (*copy)(
const Concept*, string_t& message);
87 template <
typename Concept,
typename V>
88 struct concept_base_t {
89 explicit concept_base_t(
const V* x) : vtable_m(x) { }
91 Concept*
copy()
const {
93 Concept* result = vtable_m->copy(
self(), message);
94 if (message)
throw marshaled_exception(
move(message));
98 void destroy() { vtable_m->destroy(
self()); }
100 Concept*
self() {
return static_cast<Concept*
>(
this); }
101 const Concept*
self()
const {
return static_cast<const Concept*
>(
this); }
106 template <
typename Model,
108 struct model_base : Concept {
109 template <
typename T>
110 explicit model_base(T x) : Concept(x) { }
112 static Model*
self(Concept* x) {
return static_cast<Model*
>(x); }
113 static const Model*
self(
const Concept* x) {
return static_cast<const Model*
>(x); }
115 static void destroy(Concept* x) {
delete self(x); }
117 static Concept*
copy(
const Concept* x, string_t& message) {
121 result =
new Model(*
self(x));
130 template <
typename F,
typename T>
131 typename F::concept_t* make_model(
const T& x) {
132 return new typename F::template model<T>(x);
135 template <
typename F,
typename T>
136 typename F::concept_t* create_model(
const T& x, std::tr1::true_type) {
137 return x ? make_model<F>(boost::bind<typename F::result_type>(x)) : 0;
140 template <
typename F,
typename T>
141 typename F::concept_t* create_model(
const T& x, std::tr1::false_type) {
142 return make_model<F>(boost::bind<typename F::result_type>(x));
145 template <
typename F,
typename T>
146 typename F::concept_t* create_model(
const T& x) {
147 return create_model<F>(x, std::tr1::is_pointer<T>());
154 namespace version_1 {
163 template <
typename F>
class function;
175 template <
typename R>
176 class function<R ()> :
public implementation::function_base<function<R ()> >
182 function() : object_m(0) { }
184 function(
const function& x) : object_m(x.object_m ? x.object_m->copy() : 0) { }
185 template <
typename T>
function(T x) : object_m(implementation::create_model<function>(x)) { }
189 template <
typename T>
function&
operator=(T x) {
return *
this =
function(x); }
196 if (!object_m)
throw std::tr1::bad_function_call();
197 return object_m->apply();
203 friend class implementation::function_base<function<R ()> >;
205 typedef implementation::vtable<concept_t, R (*)(concept_t*, string_t&)> vtable_type;
214 struct concept_t : implementation::concept_base_t<concept_t, vtable_type> {
215 typedef implementation::concept_base_t<concept_t, vtable_type>
base_type;
219 return apply(
typename std::tr1::is_void<R>());
224 this->vtable_m->apply(
this, message);
230 R result = this->vtable_m->apply(
this, message);
236 template <
typename T>
237 struct model : implementation::model_base<model<T>, concept_t> {
243 return apply(x, message,
typename std::tr1::is_void<R>());
248 static_cast<model*
>(x)->function_m();
257 result =
static_cast<model*
>(x)->function_m();
272 template <
typename R>
273 template <
typename T>
274 const typename function<R ()>::vtable_type function<R ()>::model<T>::vtable_s = {
283 using namespace version_1;