stlab.adobe.com Adobe Systems Incorporated
function.hpp
Go to the documentation of this file.
1 /*
2  Copyright 2005-2007 Adobe Systems Incorporated
3  Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt
4  or a copy at http://stlab.adobe.com/licenses.html)
5 */
6 
7 /**************************************************************************************************/
8 
9 #ifndef ADOBE_FUNCTION_HPP
10 #define ADOBE_FUNCTION_HPP
11 
12 #include <algorithm>
13 #include <exception>
14 
15 #include <tr1/functional>
16 #include <tr1/type_traits>
17 
18 #include <boost/bind.hpp>
19 
20 #include <adobe/cstdint.hpp>
21 #include <adobe/string.hpp>
22 
23 /**************************************************************************************************/
24 
25 namespace adobe {
26 
27 /**************************************************************************************************/
28 
29 class marshaled_exception : public std::exception {
30  public:
31  explicit marshaled_exception(string_t message) : message_m(move(message)) { }
32  ~marshaled_exception() throw() { }
33  const char* what() const throw() { return message_m.c_str(); }
34  private:
35  string_t message_m;
36 };
37 
38 const char* current_exception_what() {
39  const char* result = "unknown_exception";
40 
41  try { throw; }
42  catch (const std::exception& error) {
43  if (error.what()) result = error.what();
44  } catch (...) { }
45 
46  return result;
47 }
48 
49 struct void_;
50 typedef void_* null_ptr_t;
51 
52 /**************************************************************************************************/
53 
54 namespace implementation {
55 
56 template <typename T>
57 class function_base {
58  public:
59  // [3.7.2.2] function modifiers
60  void swap(T& x) { std::swap(self()->object_m, x.object_m); }
61 
62  // [3.7.2.3] function capacity
63  operator bool() const { return self()->object_m; }
64 
65  // [3.7.2.5] function target access
66  /* Not provided:
67  const std::type_info& target_type() const;
68  template <typename T> T* target();
69  template <typename T> const T* target() const;
70  */
71 
72  friend inline void swap(T& x, T& y) { x.swap(y); }
73  private:
74  operator int() const; // for safe bool cast
75 
76  T* self() { return static_cast<T*>(this); }
77  const T* self() const { return static_cast<const T*>(this); }
78 };
79 
80 template <typename Concept, typename Apply>
81 struct vtable {
82  void (*destroy)(Concept*);
83  Concept* (*copy)(const Concept*, string_t& message);
84  Apply apply;
85 };
86 
87 template <typename Concept, typename V>
88 struct concept_base_t {
89  explicit concept_base_t(const V* x) : vtable_m(x) { }
90 
91  Concept* copy() const {
92  string_t message;
93  Concept* result = vtable_m->copy(self(), message);
94  if (message) throw marshaled_exception(move(message));
95  return result;
96  }
97 
98  void destroy() { vtable_m->destroy(self()); }
99 
100  Concept* self() { return static_cast<Concept*>(this); }
101  const Concept* self() const { return static_cast<const Concept*>(this); }
102 
103  const V* vtable_m;
104 };
105 
106 template <typename Model,
107  typename Concept>
108 struct model_base : Concept {
109  template <typename T>
110  explicit model_base(T x) : Concept(x) { }
111 
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); }
114 
115  static void destroy(Concept* x) { delete self(x); }
116 
117  static Concept* copy(const Concept* x, string_t& message) {
118  Concept* result = 0;
119 
120  try {
121  result = new Model(*self(x));
122  } catch (...) {
123  message = current_exception_what();
124  }
125 
126  return result;
127  }
128 };
129 
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);
133 }
134 
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;
138 }
139 
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));
143 }
144 
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>());
148 }
149 
150 } // namespace implementation
151 
152 /**************************************************************************************************/
153 
154 namespace version_1 {
155 
156 /**************************************************************************************************/
157 
163 template <typename F> class function;
164 
165 /**************************************************************************************************/
166 
167 // [3.7.2.7] null pointer comparisons
168 template <typename F> bool operator==(const function<F>& x, null_ptr_t) { return !x; }
169 template <typename F> bool operator==(null_ptr_t, const function<F>& x) { return !x; }
170 template <typename F> bool operator!=(const function<F>& x, null_ptr_t) { return x; }
171 template <typename F> bool operator!=(null_ptr_t, const function<F>& x) { return x; }
172 
173 /**************************************************************************************************/
174 
175 template <typename R>
176 class function<R ()> : public implementation::function_base<function<R ()> >
177 {
178  public:
179  typedef R result_type;
180 
181  // [3.7.2.1] construction/copy/destroy
182  function() : object_m(0) { }
183  function(null_ptr_t) : 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)) { }
186 
187  function& operator=(function x) { swap(*this, x); return *this; }
188  function& operator=(null_ptr_t) { if (object_m) object_m->destroy(); object_m = 0; }
189  template <typename T> function& operator=(T x) { return *this = function(x); }
190  // template<class F> function& operator=(reference_wrapper<F>);
191 
192  ~function() { if (object_m) object_m->destroy(); }
193 
194  // [3.7.2.4] function invocation
195  R operator()() const {
196  if (!object_m) throw std::tr1::bad_function_call();
197  return object_m->apply();
198  }
199 
200  struct concept_t; // implementation
201 
202  private:
203  friend class implementation::function_base<function<R ()> >;
204 
205  typedef implementation::vtable<concept_t, R (*)(concept_t*, string_t&)> vtable_type;
206 
207  /*
208  REVISIT (sparent) : This section is an implementation detail - made public until I can figure
209  out how to make template friends.
210  */
211 
212  public:
213 
214  struct concept_t : implementation::concept_base_t<concept_t, vtable_type> {
215  typedef implementation::concept_base_t<concept_t, vtable_type> base_type;
216 
217  explicit concept_t(const vtable_type* x) : base_type(x) { }
218  R apply() {
219  return apply(typename std::tr1::is_void<R>());
220  }
221 
222  void apply(std::tr1::true_type) {
223  string_t message;
224  this->vtable_m->apply(this, message);
225  if (message) throw marshaled_exception(move(message));
226  }
227 
228  R apply(std::tr1::false_type) {
229  string_t message;
230  R result = this->vtable_m->apply(this, message);
231  if (message) throw marshaled_exception(move(message));
232  return result;
233  }
234  };
235 
236  template <typename T>
237  struct model : implementation::model_base<model<T>, concept_t> {
238  typedef implementation::model_base<model<T>, concept_t> base_type;
239 
240  explicit model(T x) : base_type(&vtable_s), function_m(x) { }
241 
242  static R apply(concept_t* x, string_t& message) {
243  return apply(x, message, typename std::tr1::is_void<R>());
244  }
245 
246  static void apply(concept_t* x, string_t& message, std::tr1::true_type) {
247  try {
248  static_cast<model*>(x)->function_m();
249  } catch (...) {
250  message = current_exception_what();
251  }
252  }
253 
254  static R apply(concept_t* x, string_t& message, std::tr1::false_type) {
255  R result;
256  try {
257  result = static_cast<model*>(x)->function_m();
258  } catch (...) {
259  message = current_exception_what();
260  }
261  return result;
262  }
263 
264  static const vtable_type vtable_s;
266  };
267 
268  private:
269  concept_t* object_m;
270 };
271 
272 template <typename R>
273 template <typename T>
274 const typename function<R ()>::vtable_type function<R ()>::model<T>::vtable_s = {
276  &model::copy,
277  &model::apply
278 };
279 
280 /**************************************************************************************************/
281 
282 } // namespace version_1
283 using namespace version_1;
284 } // namespace adobe
285 
286 /**************************************************************************************************/
287 
288 #endif
289 
290 /**************************************************************************************************/
static void apply(concept_t *x, string_t &message, std::tr1::true_type)
Definition: function.hpp:246
void swap(adobe::lex_stream_t &, adobe::lex_stream_t &)
Definition: lex_stream.hpp:68
void_ * null_ptr_t
Definition: function.hpp:49
void destroy(T *p)
Definition: memory.hpp:626
static const vtable_type vtable_s
Definition: function.hpp:264
OutputIterator copy(const InputRange &range, OutputIterator result)
copy implementation
Definition: copy.hpp:43
implementation::concept_base_t< concept_t, vtable_type > base_type
Definition: function.hpp:215
marshaled_exception(string_t message)
Definition: function.hpp:31
const char * what() const
Definition: function.hpp:33
implementation::model_base< model< T >, concept_t > base_type
Definition: function.hpp:238
const char * c_str() const
Definition: string.hpp:327
const char * current_exception_what()
Definition: function.hpp:38
bool operator!=(const function< F > &x, null_ptr_t)
Definition: function.hpp:170
void swap(circular_queue< T > &, circular_queue< T > &)
bool operator==(const function< F > &x, null_ptr_t)
Definition: function.hpp:168
function & operator=(function x)
Definition: function.hpp:187
static R apply(concept_t *x, string_t &message)
Definition: function.hpp:242
function & operator=(null_ptr_t)
Definition: function.hpp:188
static R apply(concept_t *x, string_t &message, std::tr1::false_type)
Definition: function.hpp:254

Copyright © 2006-2007 Adobe Systems Incorporated.

Use of this website signifies your agreement to the Terms of Use and Online Privacy Policy.

Search powered by Google