forked from boostorg/algorithm
Merge changes from [79588] to Release; fixes a unhex bug
[SVN r79604]
This commit is contained in:
@ -110,33 +110,25 @@ namespace detail {
|
||||
typedef T value_type;
|
||||
};
|
||||
|
||||
// Output Iterators have a value type of 'void'. Kinda sucks.
|
||||
// We special case some output iterators, but we can't enumerate them all.
|
||||
// If we can't figure it out, we assume that you want to output chars.
|
||||
// If you don't, pass in an iterator with a real value_type.
|
||||
template <typename T> struct value_type_or_char { typedef T value_type; };
|
||||
template <> struct value_type_or_char<void> { typedef char value_type; };
|
||||
|
||||
// All in one step
|
||||
template <typename Iterator>
|
||||
struct iterator_value_type {
|
||||
// typedef typename value_type_or_char<typename hex_iterator_traits<Iterator>::value_type>::value_type value_type;
|
||||
typedef typename hex_iterator_traits<Iterator>::value_type value_type;
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
bool iter_end ( Iterator current, Iterator last ) { return current == last; }
|
||||
|
||||
template <typename T>
|
||||
bool ptr_end ( const T* ptr, const T* /*end*/ ) { return *ptr == '\0'; }
|
||||
|
||||
// What can we assume here about the inputs?
|
||||
// is std::iterator_traits<InputIterator>::value_type always 'char' ?
|
||||
// Could it be wchar_t, say? Does it matter?
|
||||
// We are assuming ASCII for the values - but what about the storage?
|
||||
template <typename InputIterator, typename OutputIterator>
|
||||
typename boost::enable_if<boost::is_integral<typename iterator_value_type<OutputIterator>::value_type>, OutputIterator>::type
|
||||
decode_one ( InputIterator &first, InputIterator last, OutputIterator out ) {
|
||||
typedef typename iterator_value_type<OutputIterator>::value_type T;
|
||||
template <typename InputIterator, typename OutputIterator, typename EndPred>
|
||||
typename boost::enable_if<boost::is_integral<typename hex_iterator_traits<OutputIterator>::value_type>, OutputIterator>::type
|
||||
decode_one ( InputIterator &first, InputIterator last, OutputIterator out, EndPred pred ) {
|
||||
typedef typename hex_iterator_traits<OutputIterator>::value_type T;
|
||||
T res (0);
|
||||
|
||||
// Need to make sure that we get can read that many chars here.
|
||||
for ( std::size_t i = 0; i < 2 * sizeof ( T ); ++i, ++first ) {
|
||||
if ( first == last )
|
||||
if ( pred ( first, last ))
|
||||
BOOST_THROW_EXCEPTION (not_enough_input ());
|
||||
res = ( 16 * res ) + hex_char_to_int (static_cast<char> (*first));
|
||||
}
|
||||
@ -205,7 +197,7 @@ hex ( const Range &r, OutputIterator out ) {
|
||||
template <typename InputIterator, typename OutputIterator>
|
||||
OutputIterator unhex ( InputIterator first, InputIterator last, OutputIterator out ) {
|
||||
while ( first != last )
|
||||
out = detail::decode_one ( first, last, out );
|
||||
out = detail::decode_one ( first, last, out, detail::iter_end<InputIterator> );
|
||||
return out;
|
||||
}
|
||||
|
||||
@ -219,12 +211,12 @@ OutputIterator unhex ( InputIterator first, InputIterator last, OutputIterator o
|
||||
/// \note Based on the MySQL function of the same name
|
||||
template <typename T, typename OutputIterator>
|
||||
OutputIterator unhex ( const T *ptr, OutputIterator out ) {
|
||||
typedef typename detail::iterator_value_type<OutputIterator>::value_type OutputType;
|
||||
typedef typename detail::hex_iterator_traits<OutputIterator>::value_type OutputType;
|
||||
// If we run into the terminator while decoding, we will throw a
|
||||
// malformed input exception. It would be nicer to throw a 'Not enough input'
|
||||
// exception - but how much extra work would that require?
|
||||
while ( *ptr )
|
||||
out = detail::decode_one ( ptr, (const T *) NULL, out );
|
||||
out = detail::decode_one ( ptr, (const T *) NULL, out, detail::ptr_end<T> );
|
||||
return out;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user