Adobe Source Libraries 1.49.0
A collection of C++ libraries.
Loading...
Searching...
No Matches
function.hpp
Go to the documentation of this file.
1/*
2 Copyright 2013 Adobe
3 Distributed under the Boost Software License, Version 1.0.
4 (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5*/
6/**************************************************************************************************/
7
8#ifndef ADOBE_FUNCTION_HPP
9#define ADOBE_FUNCTION_HPP
10
11#include <algorithm>
12#include <exception>
13#include <functional>
14#include <type_traits>
15
16#include <adobe/string.hpp>
17
18/**************************************************************************************************/
19
20namespace adobe {
21
22/**************************************************************************************************/
23
24class marshaled_exception : public std::exception {
25public:
26 explicit marshaled_exception(string_t message) : message_m(move(message)) {}
28 const char* what() const throw() { return message_m.c_str(); }
29
30private:
31 string_t message_m;
32};
33
35 const char* result = "unknown_exception";
36
37 try {
38 throw;
39 } catch (const std::exception& error) {
40 if (error.what())
41 result = error.what();
42 } catch (...) {
43 }
44
45 return result;
46}
47
48struct void_;
49typedef void_* null_ptr_t;
50
51/**************************************************************************************************/
52
53namespace implementation {
54
55template <typename T>
56class function_base {
57public:
58 // [3.7.2.2] function modifiers
59 void swap(T& x) { std::swap(self()->object_m, x.object_m); }
60
61 // [3.7.2.3] function capacity
62 operator bool() const { return self()->object_m; }
63
64 // [3.7.2.5] function target access
65 /* Not provided:
66 const std::type_info& target_type() const;
67 template <typename T> T* target();
68 template <typename T> const T* target() const;
69 */
70
71 friend inline void swap(T& x, T& y) { x.swap(y); }
72
73private:
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
80template <typename Concept, typename Apply>
81struct vtable {
82 void (*destroy)(Concept*);
83 Concept* (*copy)(const Concept*, string_t& message);
84 Apply apply;
85};
86
87template <typename Concept, typename V>
88struct 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)
95 throw marshaled_exception(move(message));
96 return result;
97 }
98
99 void destroy() { vtable_m->destroy(self()); }
100
101 Concept* self() { return static_cast<Concept*>(this); }
102 const Concept* self() const { return static_cast<const Concept*>(this); }
103
104 const V* vtable_m;
105};
106
107template <typename Model, typename Concept>
108struct 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
130template <typename F, typename T>
131typename F::concept_t* make_model(const T& x) {
132 return new typename F::template model<T>(x);
133}
134
135template <typename F, typename T>
136typename F::concept_t* create_model(const T& x, std::true_type) {
137 return x ? make_model<F>(std::bind<typename F::result_type>(x)) : 0;
138}
139
140template <typename F, typename T>
141typename F::concept_t* create_model(const T& x, std::false_type) {
142 return make_model<F>(std::bind<typename F::result_type>(x));
143}
144
145template <typename F, typename T>
146typename F::concept_t* create_model(const T& x) {
147 return create_model<F>(x, std::is_pointer<T>());
148}
149
150} // namespace implementation
151
152/**************************************************************************************************/
153
154inline namespace version_1 {
155
156/**************************************************************************************************/
157
158
159template <typename F>
161
162/**************************************************************************************************/
163
164// [3.7.2.7] null pointer comparisons
165template <typename F>
167 return !x;
168}
169template <typename F>
171 return !x;
172}
173template <typename F>
175 return x;
176}
177template <typename F>
179 return x;
180}
181
182/**************************************************************************************************/
183
184template <typename R>
185class function<R()> : public implementation::function_base<function<R()>> {
186public:
187 typedef R result_type;
188
189 // [3.7.2.1] construction/copy/destroy
190 function() : object_m(0) {}
191 function(null_ptr_t) : object_m(0) {}
192 function(const function& x) : object_m(x.object_m ? x.object_m->copy() : 0) {}
193 template <typename T>
194 function(T x) : object_m(implementation::create_model<function>(x)) {}
195
197 swap(*this, x);
198 return *this;
199 }
201 if (object_m)
202 object_m->destroy();
203 object_m = 0;
204 }
205 template <typename T>
207 return *this = function(x);
208 }
209 // template<class F> function& operator=(reference_wrapper<F>);
210
212 if (object_m)
213 object_m->destroy();
214 }
215
216 // [3.7.2.4] function invocation
217 R operator()() const {
218 if (!object_m)
219 throw std::bad_function_call();
220 return object_m->apply();
221 }
222
223 struct concept_t; // implementation
224
225private:
226 friend class implementation::function_base<function<R()>>;
227
228 typedef implementation::vtable<concept_t, R (*)(concept_t*, string_t&)> vtable_type;
229
230 /*
231 REVISIT (sparent) : This section is an implementation detail - made public until I can
232 figure
233 out how to make template friends.
234 */
235
236public:
237 struct concept_t : implementation::concept_base_t<concept_t, vtable_type> {
238 typedef implementation::concept_base_t<concept_t, vtable_type> base_type;
239
240 explicit concept_t(const vtable_type* x) : base_type(x) {}
241 R apply() { return apply(typename std::is_void<R>()); }
242
243 void apply(std::true_type) {
244 string_t message;
245 this->vtable_m->apply(this, message);
246 if (message)
247 throw marshaled_exception(move(message));
248 }
249
250 R apply(std::false_type) {
251 string_t message;
252 R result = this->vtable_m->apply(this, message);
253 if (message)
254 throw marshaled_exception(move(message));
255 return result;
256 }
257 };
258
259 template <typename T>
260 struct model : implementation::model_base<model<T>, concept_t> {
261 typedef implementation::model_base<model<T>, concept_t> base_type;
262
263 explicit model(T x) : base_type(&vtable_s), function_m(x) {}
264
265 static R apply(concept_t* x, string_t& message) {
266 return apply(x, message, typename std::is_void<R>());
267 }
268
269 static void apply(concept_t* x, string_t& message, std::true_type) {
270 try {
271 static_cast<model*>(x)->function_m();
272 } catch (...) {
273 message = current_exception_what();
274 }
275 }
276
277 static R apply(concept_t* x, string_t& message, std::false_type) {
278 R result;
279 try {
280 result = static_cast<model*>(x)->function_m();
281 } catch (...) {
282 message = current_exception_what();
283 }
284 return result;
285 }
286
287 static const vtable_type vtable_s;
289 };
290
291private:
292 concept_t* object_m;
293};
294
295template <typename R>
296template <typename T>
297const typename function<R()>::vtable_type function<R()>::model<T>::vtable_s = {
298 &model::destroy, &model::copy, &model::apply};
299
300/**************************************************************************************************/
301
302} // namespace version_1
303} // namespace adobe
304
305/**************************************************************************************************/
306
307#endif
308
309/**************************************************************************************************/
marshaled_exception(string_t message)
Definition function.hpp:26
const char * what() const
Definition function.hpp:28
function & operator=(null_ptr_t)
Definition function.hpp:200
function & operator=(function x)
Definition function.hpp:196
OutputIterator copy(const InputRange &range, OutputIterator result)
copy implementation
Definition copy.hpp:42
void swap(any_regular_t &x, any_regular_t &y)
bool operator!=(const function< F > &x, null_ptr_t)
Definition function.hpp:174
bool operator==(const any_regular_t &x, const any_regular_t &y)
void destroy(T *p)
Definition memory.hpp:341
void_ * null_ptr_t
Definition function.hpp:49
const char * current_exception_what()
Definition function.hpp:34
void swap(adobe::extents_t::slice_t &x, adobe::extents_t::slice_t &y) BOOST_NOEXCEPT
Definition extents.hpp:120
implementation::concept_base_t< concept_t, vtable_type > base_type
Definition function.hpp:238
static void apply(concept_t *x, string_t &message, std::true_type)
Definition function.hpp:269
static const vtable_type vtable_s
Definition function.hpp:287
static R apply(concept_t *x, string_t &message, std::false_type)
Definition function.hpp:277
implementation::model_base< model< T >, concept_t > base_type
Definition function.hpp:261
static R apply(concept_t *x, string_t &message)
Definition function.hpp:265