1 /*============================================================================= 2 Copyright (c) 2001-2011 Hartmut Kaiser 3 http://spirit.sourceforge.net/ 4 5 Distributed under the Boost Software License, Version 1.0. (See accompanying 6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 =============================================================================*/ 8 #include <boost/config/warning_disable.hpp> 9 10 //[customize_karma_embedded_container_includes 11 #include <boost/spirit/include/karma.hpp> 12 #include <iostream> 13 #include <vector> 14 //] 15 16 /////////////////////////////////////////////////////////////////////////////// 17 //[customize_karma_embedded_container_data 18 namespace client 19 { 20 struct embedded_container 21 { 22 // expose the iterator of the embedded vector as our iterator 23 typedef std::vector<int>::const_iterator iterator; 24 25 // expose the type of the held data elements as our type 26 typedef std::vector<int>::value_type type; 27 28 // this is the vector holding the actual elements we need to generate 29 // output from 30 std::vector<int> data; 31 }; 32 } 33 //] 34 35 //[customize_karma_embedded_container_traits 36 // All specializations of attribute customization points have to be placed into 37 // the namespace boost::spirit::traits. 38 // 39 // Note that all templates below are specialized using the 'const' type. 40 // This is necessary as all attributes in Karma are 'const'. 41 namespace boost { namespace spirit { namespace traits 42 { 43 // The specialization of the template 'is_container<>' will tell the 44 // library to treat the type 'client::embedded_container' as a 45 // container holding the items to generate output from. 46 template <> 47 struct is_container<client::embedded_container const> 48 : mpl::true_ 49 {}; 50 51 // The specialization of the template 'container_iterator<>' will be 52 // invoked by the library to evaluate the iterator type to be used 53 // for iterating the data elements in the container. We simply return 54 // the type of the iterator exposed by the embedded 'std::vector<int>'. 55 template <> 56 struct container_iterator<client::embedded_container const> 57 { 58 typedef client::embedded_container::iterator type; 59 }; 60 61 // The specialization of the templates 'begin_container<>' and 62 // 'end_container<>' below will be used by the library to get the iterators 63 // pointing to the begin and the end of the data to generate output from. 64 // These specializations simply return the 'begin' and 'end' iterators as 65 // exposed by the embedded 'std::vector<int>'. 66 // 67 // The passed argument refers to the attribute instance passed to the list 68 // generator. 69 template <> 70 struct begin_container<client::embedded_container const> 71 { 72 static client::embedded_container::iterator callboost::spirit::traits::begin_container73 call(client::embedded_container const& d) 74 { 75 return d.data.begin(); 76 } 77 }; 78 79 template <> 80 struct end_container<client::embedded_container const> 81 { 82 static client::embedded_container::iterator callboost::spirit::traits::end_container83 call(client::embedded_container const& d) 84 { 85 return d.data.end(); 86 } 87 }; 88 }}} 89 //] 90 91 /////////////////////////////////////////////////////////////////////////////// 92 namespace karma = boost::spirit::karma; 93 main()94int main() 95 { 96 //[customize_karma_embedded_container 97 client::embedded_container d1; // create some test data 98 d1.data.push_back(1); 99 d1.data.push_back(2); 100 d1.data.push_back(3); 101 102 // use the instance of an 'client::embedded_container' instead of a 103 // STL vector 104 std::cout << karma::format(karma::int_ % ", ", d1) << std::endl; // prints: '1, 2, 3' 105 //] 106 return 0; 107 } 108 109