/*============================================================================= | |
Copyright (c) 2001-2011 Joel de Guzman | |
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) | |
==============================================================================*/ | |
#if !defined(BOOST_SPIRIT_NUMERIC_UTILS_APRIL_17_2006_0830AM) | |
#define BOOST_SPIRIT_NUMERIC_UTILS_APRIL_17_2006_0830AM | |
#if defined(_MSC_VER) | |
#pragma once | |
#endif | |
#include <boost/spirit/home/support/assert_msg.hpp> | |
#include <boost/spirit/home/qi/detail/assign_to.hpp> | |
#include <boost/spirit/home/qi/numeric/detail/numeric_utils.hpp> | |
#include <boost/assert.hpp> | |
#include <boost/mpl/assert.hpp> | |
namespace boost { namespace spirit { namespace qi | |
{ | |
/////////////////////////////////////////////////////////////////////////// | |
// Extract the prefix sign (- or +), return true if a '-' was found | |
/////////////////////////////////////////////////////////////////////////// | |
template <typename Iterator> | |
inline bool | |
extract_sign(Iterator& first, Iterator const& last) | |
{ | |
(void)last; // silence unused warnings | |
BOOST_ASSERT(first != last); // precondition | |
// Extract the sign | |
bool neg = *first == '-'; | |
if (neg || (*first == '+')) | |
{ | |
++first; | |
return neg; | |
} | |
return false; | |
} | |
/////////////////////////////////////////////////////////////////////////// | |
// Low level unsigned integer parser | |
/////////////////////////////////////////////////////////////////////////// | |
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits | |
, bool Accumulate = false> | |
struct extract_uint | |
{ | |
// check template parameter 'Radix' for validity | |
BOOST_SPIRIT_ASSERT_MSG( | |
Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16, | |
not_supported_radix, ()); | |
template <typename Iterator> | |
inline static bool call(Iterator& first, Iterator const& last, T& attr) | |
{ | |
if (first == last) | |
return false; | |
typedef detail::extract_int< | |
T | |
, Radix | |
, MinDigits | |
, MaxDigits | |
, detail::positive_accumulator<Radix> | |
, Accumulate> | |
extract_type; | |
Iterator save = first; | |
if (!extract_type::parse(first, last, | |
detail::cast_unsigned<T>::call(attr))) | |
{ | |
first = save; | |
return false; | |
} | |
return true; | |
} | |
template <typename Iterator, typename Attribute> | |
inline static bool call(Iterator& first, Iterator const& last, Attribute& attr_) | |
{ | |
// this case is called when Attribute is not T | |
T attr; | |
if (call(first, last, attr)) | |
{ | |
traits::assign_to(attr, attr_); | |
return true; | |
} | |
return false; | |
} | |
}; | |
/////////////////////////////////////////////////////////////////////////// | |
// Low level signed integer parser | |
/////////////////////////////////////////////////////////////////////////// | |
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits> | |
struct extract_int | |
{ | |
// check template parameter 'Radix' for validity | |
BOOST_SPIRIT_ASSERT_MSG( | |
Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16, | |
not_supported_radix, ()); | |
template <typename Iterator> | |
inline static bool call(Iterator& first, Iterator const& last, T& attr) | |
{ | |
if (first == last) | |
return false; | |
typedef detail::extract_int< | |
T, Radix, MinDigits, MaxDigits> | |
extract_pos_type; | |
typedef detail::extract_int< | |
T, Radix, MinDigits, MaxDigits, detail::negative_accumulator<Radix> > | |
extract_neg_type; | |
Iterator save = first; | |
bool hit = extract_sign(first, last); | |
if (hit) | |
hit = extract_neg_type::parse(first, last, attr); | |
else | |
hit = extract_pos_type::parse(first, last, attr); | |
if (!hit) | |
{ | |
first = save; | |
return false; | |
} | |
return true; | |
} | |
template <typename Iterator, typename Attribute> | |
inline static bool call(Iterator& first, Iterator const& last, Attribute& attr_) | |
{ | |
// this case is called when Attribute is not T | |
T attr; | |
if (call(first, last, attr)) | |
{ | |
traits::assign_to(attr, attr_); | |
return true; | |
} | |
return false; | |
} | |
}; | |
}}} | |
#endif |