.
, , .
stateful, , .
, ( ) → (, , , ). , :
struct LatLongRep {
bool _hemi; double _deg, _min, _sec;
LatLongRep(double val)
: _hemi(0 < val),
_min(60 * std::modf(std::abs(val), &_deg)),
_sec(60 * std::modf(_min, &_min))
{ }
};
:
karma::rule<iterator_type, LatLongRep()> latitude, longitude;
:
latitude =
right_align(3, '0') [ uint_ ]
<< right_align(2, '0') [ uint_ ]
<< right_align(5, '0') [ seconds ]
<< east_west;
Demo
, :
Live On Coliru
#include <boost/spirit/include/karma.hpp>
#include <boost/fusion/adapted/struct.hpp>
#include <cmath>
namespace karma = boost::spirit::karma;
typedef std::back_insert_iterator<std::string> iterator_type;
struct LatLongRep {
bool _hemi; double _deg, _min, _sec;
LatLongRep(double val)
: _hemi(0 < val),
_min(60 * std::modf(std::abs(val), &_deg)),
_sec(60 * std::modf(_min, &_min))
{ }
};
BOOST_FUSION_ADAPT_STRUCT(LatLongRep, _deg, _min, _sec, _hemi)
struct genLatLong : karma::grammar<iterator_type, double()> {
genLatLong() : genLatLong::base_type(start)
{
using namespace karma;
east_west.add (true, 'E')(false, 'W');
north_south.add(true, 'N')(false, 'S');
start = latitude;
latitude =
right_align(3, '0') [ uint_ ]
<< right_align(2, '0') [ uint_ ]
<< right_align(5, '0') [ seconds ]
<< east_west;
longitude =
right_align(3, '0') [ uint_ ]
<< right_align(2, '0') [ uint_ ]
<< right_align(5, '0') [ seconds ]
<< north_south;
}
private:
struct secfmt : karma::real_policies<double> {
unsigned precision(double) const { return 2; }
bool trailing_zeros(double) const { return true; }
};
karma::real_generator<double, secfmt> seconds;
karma::symbols<bool, char> east_west, north_south;
karma::rule<iterator_type, double()> start;
karma::rule<iterator_type, LatLongRep()> latitude, longitude;
};
int main()
{
genLatLong const gen;
for(auto & value : std::vector<double>{ 47.25346, 13.984364, -0.1233453, -44.3 })
{
std::string generated;
iterator_type outiter(generated);
auto rv = karma::generate(outiter, gen, value);
std::cout << "(" << std::boolalpha << rv << ") " << value << " ==> " << generated << std::endl;
}
}
(true) 47.2535 ==> 0471512.46E
(true) 13.9844 ==> 0135903.71E
(true) -0.123345 ==> 0000724.04W
(true) -44.3 ==> 0441760.00W
/:
real_policy secfmt ; .
, LatLongRep / Phoenix (. ). . Boost Spirit: " - ",
karma::symbols<> :
karma::symbols<bool, char> east_west, north_south;
east_west.add (true, 'E')(false, 'W');
north_south.add(true, 'N')(false, 'S');
,
, , ,