From: Foster B. <fos...@us...> - 2006-02-03 18:34:26
|
Update of /cvsroot/adobe-source/sandbox/adobe-source/adobe/documentation/sources/tutorials In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6755/adobe/documentation/sources/tutorials Modified Files: array_tutorial.dox dictionary_tutorial.dox eve_tutorial.dox forest_tutorial.dox namespaces_tutorial.dox value_tutorial.dox Log Message: asl 1.0.13 Index: value_tutorial.dox =================================================================== RCS file: /cvsroot/adobe-source/sandbox/adobe-source/adobe/documentation/sources/tutorials/value_tutorial.dox,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** value_tutorial.dox 19 Mar 2005 00:16:42 -0000 1.1 --- value_tutorial.dox 3 Feb 2006 18:33:36 -0000 1.2 *************** *** 10,14 **** \par adobe::value_t is a pseudo-discriminated union. Before we can go any further we must first understand what a discriminated type is. Kevin Henney best describes discriminated types in his documentation of <a href="http://www.boost.org/doc/html/any.html#id447427">boost::any</a>: ! - <i>Discriminated types ... contain values of different types but do not attempt conversion between them, i.e. <code>5</code> is held strictly as an <code>int</code> and is not implicitly convertible either to <code>"5"</code> or to <code>5.0</code>. Their indifference to interpretation but awareness of type effectively makes them safe, generic containers of single values, with no scope for surprises from ambiguous conversions.</i> \par A discriminated union, then, is a type that can retain any one of a collection of discriminated types, but then only one at a time. In the case of adobe::value_t its storable type range is limited to any type modeling the \ref background_data_type_requirements. --- 10,14 ---- \par adobe::value_t is a pseudo-discriminated union. Before we can go any further we must first understand what a discriminated type is. Kevin Henney best describes discriminated types in his documentation of <a href="http://www.boost.org/doc/html/any.html#id447427">boost::any</a>: ! - <i>Discriminated types ... contain values of different types but do not attempt conversion between them, i.e. <code>5</code> is held strictly as an <code>int</code> and is not implicitly convertible either to <code>"5"</code> or to <code>5.0</code>. Their indifference to interpretation but awareness of type effectively makes them safe, generic containers of single values, with no scope for surprises from ambiguous conversions.</i> \par A discriminated union, then, is a type that can retain any one of a collection of discriminated types, but then only one at a time. In the case of adobe::value_t its storable type range is limited to any type modeling the \ref background_data_type_requirements. *************** *** 19,26 **** \par \code ! adobe::value_t my_int(5); ! adobe::value_t my_string(std::string("Hello, world!")); ! adobe::value_t my_whizzy_class(whizzy_class(/*...*/)); ! adobe::value_t my_some_other_regular_type(/*...*/); \endcode \par --- 19,26 ---- \par \code ! adobe::value_t my_int(5); ! adobe::value_t my_string(std::string("Hello, world!")); ! adobe::value_t my_whizzy_class(whizzy_class(/*...*/)); ! adobe::value_t my_some_other_regular_type(/*...*/); \endcode \par *************** *** 55,59 **** struct promote { ! typedef T type; // promote<T>::type is, by default, T }; \endcode --- 55,59 ---- struct promote { ! typedef T type; // promote<T>::type is, by default, T }; \endcode *************** *** 65,69 **** struct promote<int> { ! typedef double type; // promote<int>::type is now a double }; \endcode --- 65,69 ---- struct promote<int> { ! typedef double type; // promote<int>::type is now a double }; \endcode *************** *** 75,79 **** struct promote<double> { ! typedef int type; // Legal, but bad: possible data loss }; \endcode --- 75,79 ---- struct promote<double> { ! typedef int type; // Legal, but bad: possible data loss }; \endcode *************** *** 102,114 **** \par \code ! typedef std::vector<adobe::value_t> my_vector_value_type; ! my_vector_value_type my_vector_value; ! my_vector_value.push_back(adobe::value_t(5)); ! my_vector_value.push_back(adobe::value_t('A')); ! my_vector_value.push_back(adobe::value_t(std::string("hello, world!")); ! adobe::value_t my_vector_value_value(my_vector_value); \endcode --- 102,114 ---- \par \code ! typedef std::vector<adobe::value_t> my_vector_value_type; ! my_vector_value_type my_vector_value; ! my_vector_value.push_back(adobe::value_t(5)); ! my_vector_value.push_back(adobe::value_t('A')); ! my_vector_value.push_back(adobe::value_t(std::string("hello, world!")); ! adobe::value_t my_vector_value_value(my_vector_value); \endcode *************** *** 124,132 **** if (my_value.type() == typeid(std::string)) { ! // ... } else if (my_value.type() == typeid(double)) { ! // ... } \endcode --- 124,132 ---- if (my_value.type() == typeid(std::string)) { ! // ... } else if (my_value.type() == typeid(double)) { ! // ... } \endcode *************** *** 139,147 **** if (my_int_value.type() == typeid(int)) { ! // not here! } else if (my_int_value.type() == typeid(double)) { ! // you'll end up in here } \endcode --- 139,147 ---- if (my_int_value.type() == typeid(int)) { ! // not here! } else if (my_int_value.type() == typeid(double)) { ! // you'll end up in here } \endcode *************** *** 173,185 **** try { ! int x = my_value.get<int>(); } catch(const std::exception& err) { ! std::cerr << err.what() << std::endl; } catch(...) { ! std::cerr << "don't know what happened!" << std::endl; } \endcode --- 173,185 ---- try { ! int x = my_value.get<int>(); } catch(const std::exception& err) { ! std::cerr << err.what() << std::endl; } catch(...) { ! std::cerr << "don't know what happened!" << std::endl; } \endcode *************** *** 203,211 **** int main(/*...*/) { ! adobe::value_t my_value(std::string("Hello, world!"); ! std::cout << my_value << std::endl; // Prints "Hello, world!" ! return 0; } \endcode --- 203,211 ---- int main(/*...*/) { ! adobe::value_t my_value(std::string("Hello, world!"); ! std::cout << my_value << std::endl; // Prints "Hello, world!" ! return 0; } \endcode Index: forest_tutorial.dox =================================================================== RCS file: /cvsroot/adobe-source/sandbox/adobe-source/adobe/documentation/sources/tutorials/forest_tutorial.dox,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** forest_tutorial.dox 19 Mar 2005 00:16:42 -0000 1.1 --- forest_tutorial.dox 3 Feb 2006 18:33:36 -0000 1.2 *************** *** 36,53 **** \par There are several types of iterators available to \c adobe::forest. They are: ! - <b><code>forest::iterator</code></b>: (also known as the fullorder iterator.) ! Visits the nodes by \<parent\>\<children\>\<children\>\<parent\>. ! Each node in the forest is visted twice. ! - <b><code>forest::preorder_iterator</code></b>: ! Visits the nodes by \<parent\>\<children\>. ! Each node in the forest is visted once. ! - <b><code>forest::postorder_iterator</code></b>: ! Visits the nodes by \<children\>\<parent\>. ! Each node in the forest is visted once. ! - <b><code>forest::child_iterator</code></b>: From any given node, \c child_iterator is ! a bidirectional iterator that walks a range of <i>siblings</i> (not the node's children) ! by "pivoting" on each node. There is a \c child_begin() and \c child_end() function to ! give you a range for the children of any node. Thus the \c child_iterator only applies ! to the first level of siblings, not to grandchildren or beyond. \par There are also \c reverse_ versions of the \c fullorder and \c child iterators, and \c const_ versions of the \c fullorder and \c child iterators. --- 36,53 ---- \par There are several types of iterators available to \c adobe::forest. They are: ! - <b><code>forest::iterator</code></b>: (also known as the fullorder iterator.) ! Visits the nodes by \<parent\>\<children\>\<children\>\<parent\>. ! Each node in the forest is visted twice. ! - <b><code>forest::preorder_iterator</code></b>: ! Visits the nodes by \<parent\>\<children\>. ! Each node in the forest is visted once. ! - <b><code>forest::postorder_iterator</code></b>: ! Visits the nodes by \<children\>\<parent\>. ! Each node in the forest is visted once. ! - <b><code>forest::child_iterator</code></b>: From any given node, \c child_iterator is ! a bidirectional iterator that walks a range of <i>siblings</i> (not the node's children) ! by "pivoting" on each node. There is a \c child_begin() and \c child_end() function to ! give you a range for the children of any node. Thus the \c child_iterator only applies ! to the first level of siblings, not to grandchildren or beyond. \par There are also \c reverse_ versions of the \c fullorder and \c child iterators, and \c const_ versions of the \c fullorder and \c child iterators. *************** *** 58,65 **** \par Consider the simple forest example above. Now let's say we wanted to insert a new node, <code>D</code>, somewhere around any given node in the tree (in this case we'll use node <code>A</code>). Given node \c A there are four distinct relationships \c D will have to \c A after insertion. The four possible relationships are: ! -# As the previous sibling to \c A. Note the iterator is pointing to \c A. ! -# As the next sibling to \c A. Note the iterator is pointing to \c forest::end(). ! -# As the first child of \c A, or the previous sibling of \c B. Note the iterator is pointing to \c B. ! -# As the last child of \c A, or the next sibling of \c C. Note the iterator is pointing to \c A. \par Observe that the last two relationships are similar to the first two. Consider this visual of the above situation: --- 58,65 ---- \par Consider the simple forest example above. Now let's say we wanted to insert a new node, <code>D</code>, somewhere around any given node in the tree (in this case we'll use node <code>A</code>). Given node \c A there are four distinct relationships \c D will have to \c A after insertion. The four possible relationships are: ! -# As the previous sibling to \c A. Note the iterator is pointing to \c A. ! -# As the next sibling to \c A. Note the iterator is pointing to \c forest::end(). ! -# As the first child of \c A, or the previous sibling of \c B. Note the iterator is pointing to \c B. ! -# As the last child of \c A, or the next sibling of \c C. Note the iterator is pointing to \c A. \par Observe that the last two relationships are similar to the first two. Consider this visual of the above situation: Index: namespaces_tutorial.dox =================================================================== RCS file: /cvsroot/adobe-source/sandbox/adobe-source/adobe/documentation/sources/tutorials/namespaces_tutorial.dox,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** namespaces_tutorial.dox 28 Apr 2005 05:33:26 -0000 1.1 --- namespaces_tutorial.dox 3 Feb 2006 18:33:36 -0000 1.2 *************** *** 64,70 **** In specifying these guidelines the following goals were considered: ! - Any set of libraries, even those providing overlapping functionality, with different primary namespaces, should not conflict. ! - Any set of declarations with matching semantics should have matching names, including namespace. ! - The C++ standard should not be violated - rather issues with the standard should be addressed through the standard committee. Unfortunately, the first two of these goals often come into conflict. Part of the problem is the lack of function partial specialization support, however, in cases of general extensions to a library it is difficult to come up with _any_ set of rules which would satisfy the first goal. Here we have tried to provide a reasonable balance which handles most cases. --- 64,70 ---- In specifying these guidelines the following goals were considered: ! - Any set of libraries, even those providing overlapping functionality, with different primary namespaces, should not conflict. ! - Any set of declarations with matching semantics should have matching names, including namespace. ! - The C++ standard should not be violated - rather issues with the standard should be addressed through the standard committee. Unfortunately, the first two of these goals often come into conflict. Part of the problem is the lack of function partial specialization support, however, in cases of general extensions to a library it is difficult to come up with _any_ set of rules which would satisfy the first goal. Here we have tried to provide a reasonable balance which handles most cases. Index: array_tutorial.dox =================================================================== RCS file: /cvsroot/adobe-source/sandbox/adobe-source/adobe/documentation/sources/tutorials/array_tutorial.dox,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** array_tutorial.dox 19 Mar 2005 00:16:42 -0000 1.1 --- array_tutorial.dox 3 Feb 2006 18:33:36 -0000 1.2 *************** *** 14,29 **** void foo(adobe::array_t param) // makes a copy of the array_t { ! std::cout << param[0].get<std::string>(); } int main(/*...*/) { ! adobe::array_t my_array; ! /* add elements of type adobe::value_t to my_array */ ! foo(my_array); ! return 0; } \endcode --- 14,29 ---- void foo(adobe::array_t param) // makes a copy of the array_t { ! std::cout << param[0].get<std::string>(); } int main(/*...*/) { ! adobe::array_t my_array; ! /* add elements of type adobe::value_t to my_array */ ! foo(my_array); ! return 0; } \endcode *************** *** 105,120 **** for (; first != last; ++first) { ! if (first->type() == typeid(std::string)) ! { ! std::cout << "Found a string: " << first->get<std::string>() << std::endl; ! } ! else if (first->type() == typeid(double)) ! { ! std::cout << "Found a number: " << first->get<double>() << std::endl; ! } ! else ! { ! std::cout << "I have no idea what we've found!" << std::endl; ! } } \endcode --- 105,120 ---- for (; first != last; ++first) { ! if (first->type() == typeid(std::string)) ! { ! std::cout << "Found a string: " << first->get<std::string>() << std::endl; ! } ! else if (first->type() == typeid(double)) ! { ! std::cout << "Found a number: " << first->get<double>() << std::endl; ! } ! else ! { ! std::cout << "I have no idea what we've found!" << std::endl; ! } } \endcode Index: eve_tutorial.dox =================================================================== RCS file: /cvsroot/adobe-source/sandbox/adobe-source/adobe/documentation/sources/tutorials/eve_tutorial.dox,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** eve_tutorial.dox 19 Mar 2005 00:16:42 -0000 1.1 --- eve_tutorial.dox 3 Feb 2006 18:33:36 -0000 1.2 *************** *** 8,21 **** \par The following list of items is a good recommendation of stuff you should know before you attempt to work through this document: ! - boost::function ! - boost::bind ! - adobe::dictionary_t ! - Cursory reading of the \ref eve_engine (Engine) and \ref eveparser documentation \par For advanced implementations, the following might be of help <i>but are not required</i>: ! - adobe/future/assemblage.hpp ! - adobe/test/visual/headers/optional_connect.hpp \par ! The sample code found in the Adobe Begin implementation (especially <code>client_assembler.cpp</code>) shows a possible implementation using these techniques. Note that Adobe Begin is an experimental work in progress, and should be used loosely as an example only! \section tutorials_eve_overview Overview --- 8,21 ---- \par The following list of items is a good recommendation of stuff you should know before you attempt to work through this document: ! - boost::function ! - boost::bind ! - adobe::dictionary_t ! - Cursory reading of the \ref eve_engine (Engine) and \ref eveparser documentation \par For advanced implementations, the following might be of help <i>but are not required</i>: ! - adobe/future/assemblage.hpp ! - adobe/test/visual/headers/optional_connect.hpp \par ! The sample code found in the Adobe Begin implementation (especially <code>client_assembler.cpp</code>) shows a possible implementation using these techniques. Note that Adobe Begin is an experimental work in progress, and should be used loosely as an example only! \section tutorials_eve_overview Overview *************** *** 28,42 **** \par The easiest way to see what is happening in a design that includes Eve is to enumerate the steps involved in solving a layout: ! -# The client code specifies an Eve file for parsed, solved, and displayed. ! -# The client code creates an <code>eve_t</code> object that is the Eve Engine instance that will manage the widgets at runtime. ! -# The client code calls the Eve Parser with (among other parameters) an input stream and an assemblage callback. ! -# The Eve Parser parses the input stream, notifying the assemblage callback any time a valid widget definition is found. ! -# The assemblage callback, when it receives a hit from the Eve Parser for a valid widget, constructs a signal suite and passes it (among other parameters) to the <code>eve_t</code> instance for layout of this new widget. ! -# The assemblage receives a new marker for the new widget just created in the Eve Engine hierarchy, and passes it back to the Eve Parser for later use. ! -# When the Eve Parser is finished, the client code calls the <code>evaluate</code> with the <code>eve_t</code> instance to solve for the layout. ! -# During the course of solving the layout, the Eve Engine calls back to the client assemblage code via the signal suites passed in for every individual widget created in the Eve Engine heirarchy. ! -# Once a view solution has been computed, the final signal (place) is fired for each widget to notify the client code of the positioning of every widget. ! -# The client code goes out to the OS to create the OS-specific widgets, hierarchy, event handlers, etc. ! -# The rest of the application takes it from there: Eve's work is done. \section tutorials_eve_parser Parser --- 28,42 ---- \par The easiest way to see what is happening in a design that includes Eve is to enumerate the steps involved in solving a layout: ! -# The client code specifies an Eve file for parsed, solved, and displayed. ! -# The client code creates an <code>eve_t</code> object that is the Eve Engine instance that will manage the widgets at runtime. ! -# The client code calls the Eve Parser with (among other parameters) an input stream and an assemblage callback. ! -# The Eve Parser parses the input stream, notifying the assemblage callback any time a valid widget definition is found. ! -# The assemblage callback, when it receives a hit from the Eve Parser for a valid widget, constructs a signal suite and passes it (among other parameters) to the <code>eve_t</code> instance for layout of this new widget. ! -# The assemblage receives a new marker for the new widget just created in the Eve Engine hierarchy, and passes it back to the Eve Parser for later use. ! -# When the Eve Parser is finished, the client code calls the <code>evaluate</code> with the <code>eve_t</code> instance to solve for the layout. ! -# During the course of solving the layout, the Eve Engine calls back to the client assemblage code via the signal suites passed in for every individual widget created in the Eve Engine heirarchy. ! -# Once a view solution has been computed, the final signal (place) is fired for each widget to notify the client code of the positioning of every widget. ! -# The client code goes out to the OS to create the OS-specific widgets, hierarchy, event handlers, etc. ! -# The rest of the application takes it from there: Eve's work is done. \section tutorials_eve_parser Parser *************** *** 47,57 **** void parse_my_eve_file(const std::string& path_to_file) { ! std::ifstream stream(path_to_file.c_str()); ! adobe::line_position_t result_line(adobe::eve::parse( ! stream, ! adobe::line_position_t(path_to_file.c_str()), ! adobe::eve::position_t(), ! boost::bind(&client_assemble, _1, _3, ! boost::bind(adobe::eve::evaluate_arguments(), _4)))); } \endcode --- 47,57 ---- void parse_my_eve_file(const std::string& path_to_file) { ! std::ifstream stream(path_to_file.c_str()); ! adobe::line_position_t result_line(adobe::eve::parse( ! stream, ! adobe::line_position_t(path_to_file.c_str()), ! adobe::eve::position_t(), ! boost::bind(&client_assemble, _1, _3, ! boost::bind(adobe::eve::evaluate_arguments(), _4)))); } \endcode *************** *** 72,93 **** \par \code ! adobe::position_t client_assemble( const adobe::eve_t::position_t& parent, ! adobe::name_t widget_name, ! const adobe::dictionary_t& parameters) { ! adobe::eve_t::signal_suite_t signals; ! signals.eve_container_defaults_proc_m = widget_container_defaults(widget_name); ! signals.eve_calculate_proc_m = widget_calculate_proc(widget_name); ! signals.eve_calculate_vertical_proc_m = widget_calculate_vertical_proc(widget_name); ! signals.eve_place_proc_m = widget_place_proc(widget_name); ! return eve_g.add_view_element(parent.empty() ? ! boost::any_cast<adobe::eve::position_t>(parent) : ! adobe::eve_t::iterator(), ! adobe::eve_t::insert_element_t( ! widget_is_a_container(widget_name), ! parameters, ! signals)); } \endcode --- 72,93 ---- \par \code ! adobe::position_t client_assemble( const adobe::eve_t::position_t& parent, ! adobe::name_t widget_name, ! const adobe::dictionary_t& parameters) { ! adobe::eve_t::signal_suite_t signals; ! signals.eve_container_defaults_proc_m = widget_container_defaults(widget_name); ! signals.eve_calculate_proc_m = widget_calculate_proc(widget_name); ! signals.eve_calculate_vertical_proc_m = widget_calculate_vertical_proc(widget_name); ! signals.eve_place_proc_m = widget_place_proc(widget_name); ! return eve_g.add_view_element(parent.empty() ? ! boost::any_cast<adobe::eve::position_t>(parent) : ! adobe::eve_t::iterator(), ! adobe::eve_t::insert_element_t( ! widget_is_a_container(widget_name), ! parameters, ! signals)); } \endcode *************** *** 130,135 **** void my_push_button_calc_proc(adobe::eve_t::calculate_data_t& geometry) { ! geometry.slice_m[horizontal].length_m = 80; ! geometry.slice_m[vertical].length_m = 20; } \endcode --- 130,135 ---- void my_push_button_calc_proc(adobe::eve_t::calculate_data_t& geometry) { ! geometry.slice_m[horizontal].length_m = 80; ! geometry.slice_m[vertical].length_m = 20; } \endcode *************** *** 140,147 **** void my_push_button_calc_proc(adobe::eve_t::calculate_data_t& geometry, const adobe::dictionary_t& parameters) { ! std::string button_name(parameters[adobe::static_name_t("name")].get<std::string>()); ! geometry.slice_m[horizontal].length_m = measure_string_width(button_name); ! geometry.slice_m[vertical].length_m = 20; } \endcode --- 140,147 ---- void my_push_button_calc_proc(adobe::eve_t::calculate_data_t& geometry, const adobe::dictionary_t& parameters) { ! std::string button_name(parameters[adobe::static_name_t("name")].get<std::string>()); ! geometry.slice_m[horizontal].length_m = measure_string_width(button_name); ! geometry.slice_m[vertical].length_m = 20; } \endcode *************** *** 180,187 **** \par <code>evaluate</code> sets the engine in motion, at which point callbacks will start getting signalled. There are several passes Eve takes when solving the layout, and there are corresponding callbacks that get signalled in each one. It is important to know the order in which the callbacks are signalled for a given widget: ! - eve_container_defaults_proc_m (if the widget was specified as being a container by client_assemble) ! - eve_calculate_proc_m ! - eve_calculate_vertical_proc_m ! - eve_place_proc_m \par Each of these callbacks will return state to the Eve Engine, and will affect the parameters of subsequent callbacks to the same widget. You are guaranteed that each callback, if they are called, will be called in the order listed above for a given widget. You are not guaranteed that a callback will be called. The case in which Eve will call a callback is if it needs to. I know this sounds obvious, but there are cases when Eve will not require calling some of the callbacks. One case is in the process of resizing a dialog: all the views have already had their calculate callbacks signalled in a previous pass when the dialog was first laid out. Thus the calculate_proc will not get signalled when a dialog is resized. Neither will the container_defaults_proc. When the remaining two callbacks are called, however, you can be sure they will be signalled in the order listed above. --- 180,187 ---- \par <code>evaluate</code> sets the engine in motion, at which point callbacks will start getting signalled. There are several passes Eve takes when solving the layout, and there are corresponding callbacks that get signalled in each one. It is important to know the order in which the callbacks are signalled for a given widget: ! - eve_container_defaults_proc_m (if the widget was specified as being a container by client_assemble) ! - eve_calculate_proc_m ! - eve_calculate_vertical_proc_m ! - eve_place_proc_m \par Each of these callbacks will return state to the Eve Engine, and will affect the parameters of subsequent callbacks to the same widget. You are guaranteed that each callback, if they are called, will be called in the order listed above for a given widget. You are not guaranteed that a callback will be called. The case in which Eve will call a callback is if it needs to. I know this sounds obvious, but there are cases when Eve will not require calling some of the callbacks. One case is in the process of resizing a dialog: all the views have already had their calculate callbacks signalled in a previous pass when the dialog was first laid out. Thus the calculate_proc will not get signalled when a dialog is resized. Neither will the container_defaults_proc. When the remaining two callbacks are called, however, you can be sure they will be signalled in the order listed above. Index: dictionary_tutorial.dox =================================================================== RCS file: /cvsroot/adobe-source/sandbox/adobe-source/adobe/documentation/sources/tutorials/dictionary_tutorial.dox,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** dictionary_tutorial.dox 6 Jan 2006 18:02:56 -0000 1.2 --- dictionary_tutorial.dox 3 Feb 2006 18:33:36 -0000 1.3 *************** *** 14,29 **** void foo(adobe::dictionary_t param) // makes a copy of the dictionary_t { ! std::cout << param[adobe::name_t("my_key")].get<std::string>(); } int main(/*...*/) { ! adobe::dictionary_t my_dictionary; ! /* add key/value pairs to my_dictionary */ ! foo(my_dictionary); ! return 0; } \endcode --- 14,29 ---- void foo(adobe::dictionary_t param) // makes a copy of the dictionary_t { ! std::cout << param[adobe::name_t("my_key")].get<std::string>(); } int main(/*...*/) { ! adobe::dictionary_t my_dictionary; ! /* add key/value pairs to my_dictionary */ ! foo(my_dictionary); ! return 0; } \endcode *************** *** 96,111 **** for (; first != last; ++first) { ! if (first->second.type() == typeid(std::string)) ! { ! std::cout << "Found a string: " << first->second.get<std::string>() << std::endl; ! } ! else if (first->second.type() == typeid(double)) ! { ! std::cout << "Found a number: " << first->second.get<double>() << std::endl; ! } ! else ! { ! std::cout << "I have no idea what we've found!" << std::endl; ! } } \endcode --- 96,111 ---- for (; first != last; ++first) { ! if (first->second.type() == typeid(std::string)) ! { ! std::cout << "Found a string: " << first->second.get<std::string>() << std::endl; ! } ! else if (first->second.type() == typeid(double)) ! { ! std::cout << "Found a number: " << first->second.get<double>() << std::endl; ! } ! else ! { ! std::cout << "I have no idea what we've found!" << std::endl; ! } } \endcode |