stlab.adobe.com Adobe Systems Incorporated
dictionary_arg_stream.hpp
Go to the documentation of this file.
1 /*************************************************************************
2 *
3 * ADOBE CONFIDENTIAL
4 * ___________________
5 *
6 * Copyright 2008 Adobe Systems Incorporated
7 * All Rights Reserved.
8 *
9 * NOTICE: All information contained herein is, and remains
10 * the property of Adobe Systems Incorporated and its suppliers,
11 * if any. The intellectual and technical concepts contained
12 * herein are proprietary to Adobe Systems Incorporated and its
13 * suppliers and may be covered by U.S. and Foreign Patents,
14 * patents in process, and are protected by trade secret or copyright law.
15 * Dissemination of this information or reproduction of this material
16 * is strictly forbidden unless prior written permission is obtained
17 * from Adobe Systems Incorporated.
18 **************************************************************************/
19 
20 #ifndef ADOBE_DICTIONARY_ARG_STREAM_HPP
21 #define ADOBE_DICTIONARY_ARG_STREAM_HPP
22 
23 #include <adobe/arg_stream.hpp>
24 
25 #include <adobe/is_range.hpp>
26 #include <adobe/dictionary.hpp>
27 
28 #include <boost/range/begin.hpp>
29 #include <boost/range/end.hpp>
30 #include <boost/range/value_type.hpp>
31 #include <boost/array.hpp>
32 #include <boost/utility/value_init.hpp>
33 
34 #include <new> // std::nothrow_t
35 
36 namespace adobe
37 {
38 
39 
52 template <typename R>
54 {
55  // throws bad_cast if result is not castable to R
56  return get_value(dict, key).cast<R>();
57 }
58 template <typename R>
59 bool get_dictionary_entry(adobe::dictionary_t const & dict, adobe::name_t const & key, R & r)
60 {
61  // returns false (and leaves r alone) if key not in dictionary
62  return get_value(dict, key, r);
63 }
64 
65 
66 template <typename Dictionary, typename InputRange /*to get the keys*/, typename NoThrow = void /* or std::nothrow_t */>
68 {
69  typedef Dictionary dictionary_type;
70  typedef InputRange range_type;
71  typedef typename boost::range_iterator<InputRange const>::type iterator;
72 
73  dictionary_type dict;
74  range_type range;
75  iterator curr;
76 
77  dictionary_arg_stream_base(dictionary_type & d, range_type const & key_range)
78  : dict(d), range(key_range), curr(boost::begin(key_range))
79  {
80  }
81 
82  bool eof() const
83  {
84  return curr == boost::end(range);
85  }
86 
87  void throw_if_eof() const
88  {
89  if (eof())
90  {
92  }
93  }
94 
95  void reset()
96  {
97  curr = boost::begin(range);
98  }
99 };
100 
114 template <typename Dictionary, typename InputRange /*to get the keys*/, typename NoThrow = void /* or std::nothrow_t */>
115 struct dictionary_arg_stream : dictionary_arg_stream_base<Dictionary, InputRange>
116 {
117 // we use this-> because otherwise the compiler doesn't actually know that it is in the base class
118 // (becaue the base is a template, so if specialized, it might not be there!
123  using _inherited::dict;
124  using _inherited::curr;
125 
131  dictionary_arg_stream(Dictionary & d, InputRange const & key_range)
132  : dictionary_arg_stream_base<Dictionary, InputRange>(d, key_range)
133  {
134  }
135 
136  template <typename R>
138  {
139  throw_if_eof();
140 
141  // can throw if the result of get_value is not castable to R
142  return get_dictionary_entry<R>(dict, *curr++);
143  }
144 };
145 template <typename Dictionary, typename InputRange /*to get the keys*/>
146 struct dictionary_arg_stream<Dictionary, InputRange, std::nothrow_t>
147  : dictionary_arg_stream_base<Dictionary, InputRange>
148 {
149  dictionary_arg_stream(Dictionary & d, InputRange const & key_range)
150  : dictionary_arg_stream_base<Dictionary, InputRange>(d, key_range)
151  {
152  }
153 
154  template <typename R>
156  {
157  this->throw_if_eof();
158 
159  R r = boost::initialized_value;
160  get_dictionary_entry(this->dict, *this->curr++, r);
161  return r;
162  }
163 };
164 
165 
166 template <typename Dictionary, typename InputRange /*to get the keys*/>
167 dictionary_arg_stream<Dictionary, InputRange, void>
169  Dictionary & dict, InputRange const & key_range)
170 {
172 }
173 
174 template <typename Dictionary, typename InputRange /*to get the keys*/>
175 dictionary_arg_stream<Dictionary, InputRange, std::nothrow_t>
177  Dictionary & dict, InputRange const & key_range, std::nothrow_t)
178 {
180 }
181 
182 
183 namespace dictionary_arg_stream_detail
184 {
185  template<size_t>
187  {
188  };
189 
191  template <typename R>
193 
194  template <typename Dictionary, typename Key>
196  {
197  static Dictionary * dict;
198  static Key * key;
199  static adobe::detail::yes_struct SFINAE(int);
201  static const bool value = sizeof(SFINAE(get_dictionary_entry<int>(*dict, *key))) == sizeof(adobe::detail::yes_struct);
202  };
203  template <typename Dictionary, typename Key, typename R>
205  {
206  static Dictionary * dict;
207  static Key * key;
208  static R * r;
209  static adobe::detail::yes_struct SFINAE(int);
211  static const bool value = sizeof(SFINAE(get_dictionary_entry(*dict, *key, *r))) == sizeof(adobe::detail::yes_struct);
212  };
213 
214  template <typename Dictionary, typename Range>
216  {
218  };
219 
221 
223 
224  template <typename Dictionary, typename DefaultKey, bool has_type = ADOBE_HAS_TYPE(Dictionary, key_type)>
225  struct key_type;
226 
227  template <typename Dictionary, typename DefaultKey>
228  struct key_type<Dictionary, DefaultKey, false>
229  {
230  typedef DefaultKey type;
231  };
232  template <typename Dictionary, typename DefaultKey>
233  struct key_type<Dictionary, DefaultKey, true>
234  {
235  typedef typename Dictionary::key_type type;
236  };
237 
238 
239  // for the single arg case (single arg after dict arg)
240  // is that arg a key to the dictionary representing an arg,
241  // or is it a range of keys for the dictionary
242  template <typename NoThrow = std::nothrow_t, bool isRange = true>
244  {
245  template <typename F, typename Dictionary, typename InputRange>
246  static typename arg_stream::result_type<F>::type
247  call(F f, Dictionary const & dict, InputRange const & range)
248  {
249  return arg_stream::call(f, make_dictionary_arg_stream(dict, range, std::nothrow));
250  }
251  };
252  template <>
253  struct if_range_base<void, true>
254  {
255  template <typename F, typename Dictionary, typename InputRange>
256  static typename arg_stream::result_type<F>::type
257  call(F f, Dictionary const & dict, InputRange const & range)
258  {
259  return arg_stream::call(f, make_dictionary_arg_stream(dict, range));
260  }
261  };
262 
263  template <>
264  struct if_range_base<std::nothrow_t, false>
265  {
266  template <typename F, typename Dictionary, typename Key>
267  static typename arg_stream::result_type<F>::type
268  call(F f, Dictionary const & dict, Key const & keyable)
269  {
270  typedef typename key_type<Dictionary, Key>::type key_type;
271  key_type key(keyable);
272  std::pair<key_type const *, key_type const *> key_range(&key, &key + 1);
273  return arg_stream::call(f, make_dictionary_arg_stream(dict, key_range, std::nothrow));
274  }
275  };
276  template <>
277  struct if_range_base<void, false>
278  {
279  template <typename F, typename Dictionary, typename Key>
280  static typename arg_stream::result_type<F>::type
281  call(F f, Dictionary const & dict, Key const & keyable)
282  {
283  typedef typename key_type<Dictionary, Key>::type key_type;
284  key_type key(keyable);
285  std::pair<key_type const *, key_type const *> key_range(&key, &key + 1);
286  return arg_stream::call(f, make_dictionary_arg_stream(dict, key_range));
287  }
288  };
289 
290  template <typename NoThrow, typename Dictionary, typename T>
292  : if_range_base<NoThrow, is_range_for_dictionary<Dictionary, T>::value>
293  {
294  };
295 }
296 
303 template <typename F, typename Dictionary, typename SingleArg>
305  call_with_dictionary(F f, Dictionary const & dict, SingleArg const & key_or_key_range)
306 {
308 }
309 
310 // nothrow case:
311 template <typename F, typename Dictionary, typename SingleArg>
312  typename arg_stream::result_type<F>::type
313  call_with_dictionary(F f, std::nothrow_t, Dictionary const & dict, SingleArg const & key_or_key_range)
314 {
316 }
317 
318 // member function cases
319 template <class T, typename F, typename Dictionary, typename SingleArg>
320  typename arg_stream::result_type<F>::type
321  call_member_with_dictionary(T * that, F f, Dictionary const & dict, SingleArg const & key_or_key_range)
322 {
324 }
325 
326 template <class T, typename F, typename Dictionary, typename SingleArg>
327  typename arg_stream::result_type<F>::type
328  call_member_with_dictionary(T* that, F f, std::nothrow_t, Dictionary const & dict, SingleArg const & key_or_key_range)
329 {
331 }
332 
333 
335 template <typename F, typename Dictionary, typename T1, typename T2 >
336  typename arg_stream::result_type<F>::type
337  call_with_dictionary(F f, Dictionary const & dict,
338  T1 const & key1, T2 const & key2)
339 {
341  boost::array<key_type, 2> arr = { key_type(key1), key_type(key2) };
342  return call_with_dictionary(f, dict, arr);
343 }
344 
345 template <typename X, typename F, typename Dictionary, typename T1, typename T2 >
346  typename arg_stream::result_type<F>::type
347  call_member_with_dictionary(X & x, F f, Dictionary const & dict,
348  T1 const & key1, T2 const & key2)
349 {
351  boost::array<key_type, 2> arr = { key_type(key1), key_type(key2) };
352  return call_member_with_dictionary(x, f, dict, arr);
353 }
354 
355 template <typename F, typename Dictionary, typename T1, typename T2 >
356  typename arg_stream::result_type<F>::type
357  call_with_dictionary(F f, std::nothrow_t, Dictionary const & dict,
358  T1 const & key1, T2 const & key2)
359 {
361  boost::array<key_type, 2> arr = { key_type(key1), key_type(key2) };
362  return call_with_dictionary(f, std::nothrow, dict, arr);
363 }
364 
365 template <typename X, typename F, typename Dictionary, typename T1, typename T2 >
366  typename arg_stream::result_type<F>::type
367  call_member_with_dictionary(X x, F f, std::nothrow_t, Dictionary const & dict,
368  T1 const & key1, T2 const & key2)
369 {
371  boost::array<key_type, 2> arr = { key_type(key1), key_type(key2) };
372  return call_member_with_dictionary(x, f, std::nothrow, dict, arr);
373 }
374 
376 template <typename F, typename Dictionary, typename T1, typename T2, typename T3>
377  typename arg_stream::result_type<F>::type
378  call_with_dictionary(F f, Dictionary const & dict,
379  T1 const & key1, T2 const & key2, T3 const & key3)
380 {
382  boost::array<key_type, 3> arr = { key_type(key1), key_type(key2), key_type(key3) };
383  return call_with_dictionary(f, dict, arr);
384 }
385 
386 template <typename X, typename F, typename Dictionary, typename T1, typename T2, typename T3>
387  typename arg_stream::result_type<F>::type
388  call_member_with_dictionary(X & x, F f, Dictionary const & dict,
389  T1 const & key1, T2 const & key2, T3 const & key3)
390 {
392  boost::array<key_type, 3> arr = { key_type(key1), key_type(key2), key_type(key3) };
393  return call_member_with_dictionary(x, f, dict, arr);
394 }
395 
396 template <typename F, typename Dictionary, typename T1, typename T2, typename T3>
397  typename arg_stream::result_type<F>::type
398  call_with_dictionary(F f, std::nothrow_t, Dictionary const & dict,
399  T1 const & key1, T2 const & key2, T3 const & key3)
400 {
402  boost::array<key_type, 3> arr = { key_type(key1), key_type(key2), key_type(key3) };
403  return call_with_dictionary(f, std::nothrow, dict, arr);
404 }
405 
406 template <typename X, typename F, typename Dictionary, typename T1, typename T2, typename T3>
407  typename arg_stream::result_type<F>::type
408  call_member_with_dictionary(X x, F f, std::nothrow_t, Dictionary const & dict,
409  T1 const & key1, T2 const & key2, T3 const & key3)
410 {
412  boost::array<key_type, 3> arr = { key_type(key1), key_type(key2), key_type(key3) };
413  return call_member_with_dictionary(x, f, std::nothrow, dict, arr);
414 }
415 
417 template <typename F, typename Dictionary, typename T1, typename T2, typename T3, typename T4>
418  typename arg_stream::result_type<F>::type
419  call_with_dictionary(F f, Dictionary const & dict,
420  T1 const & key1, T2 const & key2, T3 const & key3, T4 const & key4)
421 {
423  boost::array<key_type, 4> arr = { key_type(key1), key_type(key2), key_type(key3), key_type(key4) };
424  return call_with_dictionary(f, dict, arr);
425 }
426 
427 template <typename X, typename F, typename Dictionary, typename T1, typename T2, typename T3, typename T4>
428  typename arg_stream::result_type<F>::type
429  call_member_with_dictionary(X & x, F f, Dictionary const & dict,
430  T1 const & key1, T2 const & key2, T3 const & key3, T4 const & key4)
431 {
433  boost::array<key_type, 4> arr = { key_type(key1), key_type(key2), key_type(key3), key_type(key4) };
434  return call_member_with_dictionary(x, f, dict, arr);
435 }
436 
437 template <typename F, typename Dictionary, typename T1, typename T2, typename T3, typename T4>
438  typename arg_stream::result_type<F>::type
439  call_with_dictionary(F f, std::nothrow_t, Dictionary const & dict,
440  T1 const & key1, T2 const & key2, T3 const & key3, T4 const & key4)
441 {
443  boost::array<key_type, 4> arr = { key_type(key1), key_type(key2), key_type(key3), key_type(key4) };
444  return call_with_dictionary(f, std::nothrow, dict, arr);
445 }
446 
447 template <typename X, typename F, typename Dictionary, typename T1, typename T2, typename T3, typename T4>
448  typename arg_stream::result_type<F>::type
449  call_member_with_dictionary(X x, F f, std::nothrow_t, Dictionary const & dict,
450  T1 const & key1, T2 const & key2, T3 const & key3, T4 const & key4)
451 {
453  boost::array<key_type, 4> arr = { key_type(key1), key_type(key2), key_type(key3), key_type(key4) };
454  return call_member_with_dictionary(x, f, std::nothrow, dict, arr);
455 }
456 
457 
458 } // namespace adobe
459 
460 #endif // include guard
461 
dictionary_arg_stream implements the arg_stream interface
arg_stream::result_type< F >::type call_with_dictionary(F f, Dictionary const &dict, SingleArg const &key_or_key_range)
call the function/callable-object f with args pulled from dictionary dict via keys from key_range ...
static Key * key
static Key * key
static arg_stream::result_type< F >::type call(F f, Dictionary const &dict, Key const &keyable)
R get_dictionary_entry(adobe::dictionary_t const &dict, adobe::name_t const &key)
dictionary_arg_stream requires specializations of get_dictionary_entry for the dictionary. For example, the adobe::dictionary_t specializations.
static Dictionary * dict
STL namespace.
dictionary_arg_stream_base< Dictionary, InputRange > _inherited
static R * r
boost::function_types::result_type< typename signature< F >::type >::type type
Definition: arg_stream.hpp:242
boost::range_iterator< InputRange const >::type iterator
function_not_present get_dictionary_entry(...)
dictionary_arg_stream< Dictionary, InputRange, void > make_dictionary_arg_stream(Dictionary &dict, InputRange const &key_range)
static arg_stream::result_type< F >::type call(F f, Dictionary const &dict, InputRange const &range)
static Dictionary * dict
static adobe::detail::yes_struct SFINAE(int)
arg_stream::result_type< F >::type call_member_with_dictionary(T *that, F f, Dictionary const &dict, SingleArg const &key_or_key_range)
dictionary_arg_stream_base(dictionary_type &d, range_type const &key_range)
result_type< F >::type call(F f, ArgStream &astream)
Calls function/callable-object f with function arguments supplied by the arg_stream.
Definition: arg_stream.hpp:306
bool get_value(const dictionary_t &dict, name_t key, T &value)
Definition: dictionary.hpp:38
static adobe::detail::yes_struct SFINAE(int)
static const bool value
dictionary_arg_stream(Dictionary &d, InputRange const &key_range)
static arg_stream::result_type< F >::type call(F f, Dictionary const &dict, Key const &keyable)
static arg_stream::result_type< F >::type call(F f, Dictionary const &dict, InputRange const &range)

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