Adobe Source Libraries 1.49.0
A collection of C++ libraries.
Loading...
Searching...
No Matches
dictionary_arg_stream.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#ifndef ADOBE_DICTIONARY_ARG_STREAM_HPP
7#define ADOBE_DICTIONARY_ARG_STREAM_HPP
8
10
11#include <adobe/dictionary.hpp>
12#include <adobe/is_range.hpp>
13
14#include <boost/range/begin.hpp>
15#include <boost/range/end.hpp>
16#include <boost/range/value_type.hpp>
17#include <boost/utility/value_init.hpp>
18
19#include <array>
20#include <new> // std::nothrow_t
21
22namespace adobe {
23
24
37template <typename R>
39 // throws bad_cast if result is not castable to R
40 return get_value(dict, key).cast<R>();
41}
42template <typename R>
43bool get_dictionary_entry(adobe::dictionary_t const& dict, adobe::name_t const& key, R& r) {
44 // returns false (and leaves r alone) if key not in dictionary
45 return get_value(dict, key, r);
46}
47
48
49template <typename Dictionary, typename InputRange /*to get the keys*/,
50 typename NoThrow = void /* or std::nothrow_t */>
52 typedef Dictionary dictionary_type;
53 typedef InputRange range_type;
54 typedef typename boost::range_iterator<InputRange const>::type iterator;
55
59
61 : dict(d), range(key_range), curr(boost::begin(key_range)) {}
62
63 bool eof() const { return curr == boost::end(range); }
64
65 void throw_if_eof() const {
66 if (eof()) {
68 }
69 }
70
71 void reset() { curr = boost::begin(range); }
72};
73
89template <typename Dictionary, typename InputRange /*to get the keys*/,
90 typename NoThrow = void /* or std::nothrow_t */>
91struct dictionary_arg_stream : dictionary_arg_stream_base<Dictionary, InputRange> {
92 // we use this-> because otherwise the compiler doesn't actually know that it is in the base
93 // class
94 // (becaue the base is a template, so if specialized, it might not be there!
96 using _inherited::curr;
97 using _inherited::dict;
101
107 dictionary_arg_stream(Dictionary& d, InputRange const& key_range)
108 : dictionary_arg_stream_base<Dictionary, InputRange>(d, key_range) {}
109
110 template <typename R>
112 throw_if_eof();
113
114 // can throw if the result of get_value is not castable to R
116 }
117};
118template <typename Dictionary, typename InputRange /*to get the keys*/>
119struct dictionary_arg_stream<Dictionary, InputRange, std::nothrow_t>
120 : dictionary_arg_stream_base<Dictionary, InputRange> {
121 dictionary_arg_stream(Dictionary& d, InputRange const& key_range)
122 : dictionary_arg_stream_base<Dictionary, InputRange>(d, key_range) {}
123
124 template <typename R>
126 this->throw_if_eof();
127
128 R r = boost::initialized_value;
129 get_dictionary_entry(this->dict, *this->curr++, r);
130 return r;
131 }
132};
133
134
135template <typename Dictionary, typename InputRange /*to get the keys*/>
136dictionary_arg_stream<Dictionary, InputRange, void>
137make_dictionary_arg_stream(Dictionary& dict, InputRange const& key_range) {
139}
140
141template <typename Dictionary, typename InputRange /*to get the keys*/>
142dictionary_arg_stream<Dictionary, InputRange, std::nothrow_t>
143make_dictionary_arg_stream(Dictionary& dict, InputRange const& key_range, std::nothrow_t) {
145}
146
147
149template <size_t>
151
153template <typename R>
155
156template <typename Dictionary, typename Key>
158 static Dictionary* dict;
159 static Key* key;
160 static adobe::detail::yes_struct SFINAE(int);
161 static adobe::detail::no_struct SFINAE(function_not_present const&);
162 static const bool value =
163 sizeof(SFINAE(get_dictionary_entry<int>(*dict, *key))) == sizeof(adobe::detail::yes_struct);
164};
165template <typename Dictionary, typename Key, typename R>
167 static Dictionary* dict;
168 static Key* key;
169 static R* r;
170 static adobe::detail::yes_struct SFINAE(int);
171 static adobe::detail::no_struct SFINAE(function_not_present const&);
172 static const bool value =
173 sizeof(SFINAE(get_dictionary_entry(*dict, *key, *r))) == sizeof(adobe::detail::yes_struct);
174};
175
176template <typename Dictionary, typename Range>
178 static const bool value =
180 typename boost::range_value<Range>::type>::value;
181};
182
183static const int test =
185
187
188template <typename Dictionary, typename DefaultKey,
189 bool has_type = ADOBE_HAS_TYPE(Dictionary, key_type)>
190struct key_type;
191
192template <typename Dictionary, typename DefaultKey>
193struct key_type<Dictionary, DefaultKey, false> {
194 typedef DefaultKey type;
195};
196template <typename Dictionary, typename DefaultKey>
197struct key_type<Dictionary, DefaultKey, true> {
198 typedef typename Dictionary::key_type type;
199};
200
201
202// for the single arg case (single arg after dict arg)
203// is that arg a key to the dictionary representing an arg,
204// or is it a range of keys for the dictionary
205template <typename NoThrow = std::nothrow_t, bool isRange = true>
207 template <typename F, typename Dictionary, typename InputRange>
208 static typename arg_stream::result_type<F>::type call(F f, Dictionary const& dict,
209 InputRange const& range) {
210 return arg_stream::call(f, make_dictionary_arg_stream(dict, range, std::nothrow));
211 }
212};
213template <>
214struct if_range_base<void, true> {
215 template <typename F, typename Dictionary, typename InputRange>
216 static typename arg_stream::result_type<F>::type call(F f, Dictionary const& dict,
217 InputRange const& range) {
218 return arg_stream::call(f, make_dictionary_arg_stream(dict, range));
219 }
220};
221
222template <>
223struct if_range_base<std::nothrow_t, false> {
224 template <typename F, typename Dictionary, typename Key>
225 static typename arg_stream::result_type<F>::type call(F f, Dictionary const& dict,
226 Key const& keyable) {
228 key_type key(keyable);
229 std::pair<key_type const*, key_type const*> key_range(&key, &key + 1);
230 return arg_stream::call(f, make_dictionary_arg_stream(dict, key_range, std::nothrow));
231 }
232};
233template <>
234struct if_range_base<void, false> {
235 template <typename F, typename Dictionary, typename Key>
236 static typename arg_stream::result_type<F>::type call(F f, Dictionary const& dict,
237 Key const& keyable) {
239 key_type key(keyable);
240 std::pair<key_type const*, key_type const*> key_range(&key, &key + 1);
241 return arg_stream::call(f, make_dictionary_arg_stream(dict, key_range));
242 }
243};
244
245template <typename NoThrow, typename Dictionary, typename T>
246struct if_range_else_key : if_range_base<NoThrow, is_range_for_dictionary<Dictionary, T>::value> {};
247} // namespace dictionary_arg_stream_detail
248
255template <typename F, typename Dictionary, typename SingleArg>
256typename arg_stream::result_type<F>::type call_with_dictionary(F f, Dictionary const& dict,
257 SingleArg const& key_or_key_range) {
259 f, dict, key_or_key_range);
260}
261
262// nothrow case:
263template <typename F, typename Dictionary, typename SingleArg>
265 Dictionary const& dict,
266 SingleArg const& key_or_key_range) {
267 return dictionary_arg_stream_detail::if_range_else_key<std::nothrow_t, Dictionary,
268 SingleArg>::call(f, dict,
269 key_or_key_range);
270}
271
272// member function cases
273template <class T, typename F, typename Dictionary, typename SingleArg>
275call_member_with_dictionary(T* that, F f, Dictionary const& dict,
276 SingleArg const& key_or_key_range) {
278 that, f, dict, key_or_key_range);
279}
280
281template <class T, typename F, typename Dictionary, typename SingleArg>
283call_member_with_dictionary(T* that, F f, std::nothrow_t, Dictionary const& dict,
284 SingleArg const& key_or_key_range) {
285 return dictionary_arg_stream_detail::if_range_else_key<std::nothrow_t, Dictionary,
286 SingleArg>::call(that, f, dict,
287 key_or_key_range);
288}
289
290
292template <typename F, typename Dictionary, typename T1, typename T2>
293typename arg_stream::result_type<F>::type call_with_dictionary(F f, Dictionary const& dict,
294 T1 const& key1, T2 const& key2) {
296 std::array<key_type, 2> arr = {key_type(key1), key_type(key2)};
297 return call_with_dictionary(f, dict, arr);
298}
299
300template <typename X, typename F, typename Dictionary, typename T1, typename T2>
302call_member_with_dictionary(X& x, F f, Dictionary const& dict, T1 const& key1, T2 const& key2) {
304 std::array<key_type, 2> arr = {key_type(key1), key_type(key2)};
305 return call_member_with_dictionary(x, f, dict, arr);
306}
307
308template <typename F, typename Dictionary, typename T1, typename T2>
310call_with_dictionary(F f, std::nothrow_t, Dictionary const& dict, T1 const& key1, T2 const& key2) {
312 std::array<key_type, 2> arr = {key_type(key1), key_type(key2)};
313 return call_with_dictionary(f, std::nothrow, dict, arr);
314}
315
316template <typename X, typename F, typename Dictionary, typename T1, typename T2>
318call_member_with_dictionary(X x, F f, std::nothrow_t, Dictionary const& dict, T1 const& key1,
319 T2 const& key2) {
321 std::array<key_type, 2> arr = {key_type(key1), key_type(key2)};
322 return call_member_with_dictionary(x, f, std::nothrow, dict, arr);
323}
324
326template <typename F, typename Dictionary, typename T1, typename T2, typename T3>
328call_with_dictionary(F f, Dictionary const& dict, T1 const& key1, T2 const& key2, T3 const& key3) {
330 std::array<key_type, 3> arr = {key_type(key1), key_type(key2), key_type(key3)};
331 return call_with_dictionary(f, dict, arr);
332}
333
334template <typename X, typename F, typename Dictionary, typename T1, typename T2, typename T3>
336call_member_with_dictionary(X& x, F f, Dictionary const& dict, T1 const& key1, T2 const& key2,
337 T3 const& key3) {
339 std::array<key_type, 3> arr = {key_type(key1), key_type(key2), key_type(key3)};
340 return call_member_with_dictionary(x, f, dict, arr);
341}
342
343template <typename F, typename Dictionary, typename T1, typename T2, typename T3>
345call_with_dictionary(F f, std::nothrow_t, Dictionary const& dict, T1 const& key1, T2 const& key2,
346 T3 const& key3) {
348 std::array<key_type, 3> arr = {key_type(key1), key_type(key2), key_type(key3)};
349 return call_with_dictionary(f, std::nothrow, dict, arr);
350}
351
352template <typename X, typename F, typename Dictionary, typename T1, typename T2, typename T3>
354call_member_with_dictionary(X x, F f, std::nothrow_t, Dictionary const& dict, T1 const& key1,
355 T2 const& key2, T3 const& key3) {
357 std::array<key_type, 3> arr = {key_type(key1), key_type(key2), key_type(key3)};
358 return call_member_with_dictionary(x, f, std::nothrow, dict, arr);
359}
360
362template <typename F, typename Dictionary, typename T1, typename T2, typename T3, typename T4>
363typename arg_stream::result_type<F>::type call_with_dictionary(F f, Dictionary const& dict,
364 T1 const& key1, T2 const& key2,
365 T3 const& key3, T4 const& key4) {
367 std::array<key_type, 4> arr = {key_type(key1), key_type(key2), key_type(key3), key_type(key4)};
368 return call_with_dictionary(f, dict, arr);
369}
370
371template <typename X, typename F, typename Dictionary, typename T1, typename T2, typename T3,
372 typename T4>
374call_member_with_dictionary(X& x, F f, Dictionary const& dict, T1 const& key1, T2 const& key2,
375 T3 const& key3, T4 const& key4) {
377 std::array<key_type, 4> arr = {key_type(key1), key_type(key2), key_type(key3), key_type(key4)};
378 return call_member_with_dictionary(x, f, dict, arr);
379}
380
381template <typename F, typename Dictionary, typename T1, typename T2, typename T3, typename T4>
383call_with_dictionary(F f, std::nothrow_t, Dictionary const& dict, T1 const& key1, T2 const& key2,
384 T3 const& key3, T4 const& key4) {
386 std::array<key_type, 4> arr = {key_type(key1), key_type(key2), key_type(key3), key_type(key4)};
387 return call_with_dictionary(f, std::nothrow, dict, arr);
388}
389
390template <typename X, typename F, typename Dictionary, typename T1, typename T2, typename T3,
391 typename T4>
393call_member_with_dictionary(X x, F f, std::nothrow_t, Dictionary const& dict, T1 const& key1,
394 T2 const& key2, T3 const& key3, T4 const& key4) {
396 std::array<key_type, 4> arr = {key_type(key1), key_type(key2), key_type(key3), key_type(key4)};
397 return call_member_with_dictionary(x, f, std::nothrow, dict, arr);
398}
399
400
401} // namespace adobe
402
403#endif // include guard
result_type< F >::type call(F f, ArgStream &astream)
Calls function/callable-object f with function arguments supplied by the arg_stream.
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....
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
#define ADOBE_HAS_TYPE_IMPL(TypeInQuestion)
Implementation part of ADOBE_HAS_TYPE macro. Required before using ADOBE_HAS_TYPE.
#define ADOBE_HAS_TYPE(C, TypeInQuestion)
returns true iff C has an internal type named 'TypeInQuestion'. ie returns true iff C::TypeInQuestion...
function_not_present get_dictionary_entry(...)
closed_hash_map< name_t, any_regular_t > dictionary_t
bool get_value(const dictionary_t &dict, name_t key, T &value)
dictionary_arg_stream< Dictionary, InputRange, void > make_dictionary_arg_stream(Dictionary &dict, InputRange const &key_range)
arg_stream::result_type< F >::type call_member_with_dictionary(T *that, F f, Dictionary const &dict, SingleArg const &key_or_key_range)
STL namespace.
boost::function_types::result_type< typenamesignature< F >::type >::type type
boost::range_iterator< InputRangeconst >::type iterator
dictionary_arg_stream_base(dictionary_type &d, range_type const &key_range)
static Dictionary * dict
static const bool value
static adobe::detail::yes_struct SFINAE(int)
static R * r
static Key * key
static adobe::detail::no_struct SFINAE(function_not_present const &)
static Dictionary * dict
static const bool value
static adobe::detail::yes_struct SFINAE(int)
static Key * key
static adobe::detail::no_struct SFINAE(function_not_present const &)
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, Key const &keyable)
static arg_stream::result_type< F >::type call(F f, Dictionary const &dict, InputRange const &range)
static arg_stream::result_type< F >::type call(F f, Dictionary const &dict, InputRange const &range)
dictionary_arg_stream implements the arg_stream interface
dictionary_arg_stream(Dictionary &d, InputRange const &key_range)
dictionary_arg_stream_base< Dictionary, InputRange > _inherited
A character string class for immutable strings.
Definition name.hpp:220