1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
|
/*=============================================================================
Copyright (c) 2001-2011 Hartmut Kaiser
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
//[customize_karma_counter_includes
#include <boost/spirit/include/karma.hpp>
#include <iostream>
#include <vector>
//]
///////////////////////////////////////////////////////////////////////////////
//[customize_karma_counter_data
namespace client
{
struct counter
{
// expose the current value of the counter as our iterator
typedef int iterator;
// expose 'int' as the type of each generated element
typedef int type;
counter(int max_count)
: counter_(0), max_count_(max_count)
{}
int counter_;
int max_count_;
};
}
//]
//[customize_karma_counter_traits
// All specializations of attribute customization points have to be placed into
// the namespace boost::spirit::traits.
//
// Note that all templates below are specialized using the 'const' type.
// This is necessary as all attributes in Karma are 'const'.
namespace boost { namespace spirit { namespace traits
{
// The specialization of the template 'is_container<>' will tell the
// library to treat the type 'client::counter' as a container providing
// the items to generate output from.
template <>
struct is_container<client::counter const>
: mpl::true_
{};
// The specialization of the template 'container_iterator<>' will be
// invoked by the library to evaluate the iterator type to be used
// for iterating the data elements in the container.
template <>
struct container_iterator<client::counter const>
{
typedef client::counter::iterator type;
};
// The specialization of the templates 'begin_container<>' and
// 'end_container<>' below will be used by the library to get the iterators
// pointing to the begin and the end of the data to generate output from.
// These specializations respectively return the initial and maximum
// counter values.
//
// The passed argument refers to the attribute instance passed to the list
// generator.
template <>
struct begin_container<client::counter const>
{
static client::counter::iterator
call(client::counter const& c)
{
return c.counter_;
}
};
template <>
struct end_container<client::counter const>
{
static client::counter::iterator
call(client::counter const& c)
{
return c.max_count_;
}
};
}}}
//]
//[customize_karma_counter_iterator_traits
// All specializations of attribute customization points have to be placed into
// the namespace boost::spirit::traits.
namespace boost { namespace spirit { namespace traits
{
// The specialization of the template 'deref_iterator<>' will be used to
// dereference the iterator associated with our counter data structure.
// Since we expose the current value as the iterator we just return the
// current iterator as the return value.
template <>
struct deref_iterator<client::counter::iterator>
{
typedef client::counter::type type;
static type call(client::counter::iterator const& it)
{
return it;
}
};
}}}
//]
///////////////////////////////////////////////////////////////////////////////
namespace karma = boost::spirit::karma;
int main()
{
//[customize_karma_counter
// use the instance of a 'client::counter' instead of a STL vector
client::counter count(4);
std::cout << karma::format(karma::int_ % ", ", count) << std::endl; // prints: '0, 1, 2, 3'
//]
return 0;
}
|