Let the user give an error checking policy for invalid ranges.

This enables the user to use std::istream_iterator as the underlying iterator.
This commit is contained in:
King_DuckZ 2014-06-03 23:20:23 +02:00
parent a377c642ff
commit 73bd06b5d6

View file

@ -30,6 +30,7 @@ DEALINGS IN THE SOFTWARE.
#include "core.h"
#include <stdexcept>
#include <cassert>
namespace utf8
{
@ -263,8 +264,52 @@ namespace utf8
return result;
}
// Error policies for the iterator class
template <typename I>
class ErrorPolicyThrow {
public:
static void check_in_range(const I& it, const I& range_start, const I& range_end)
{
if (it < range_start || it > range_end)
throw std::out_of_range("Invalid utf-8 iterator position");
}
static void check_same_range(const I& range_start_a, const I& range_start_b, const I& range_end_a, const I& range_end_b)
{
if (range_start_a != range_start_b || range_end_a != range_end_b)
throw std::logic_error("Comparing utf-8 iterators defined with different ranges");
}
};
template <typename I>
class ErrorPolicyAssert {
public:
static void check_in_range(const I& it, const I& range_start, const I& range_end)
{
#if defined(NDEBUG)
(void)it;
(void)range_start;
(void)range_end;
#else
assert(it >= range_start && it <= range_end);
#endif
}
static void check_same_range(const I& range_start_a, const I& range_start_b, const I& range_end_a, const I& range_end_b)
{
#if defined(NDEBUG)
(void)range_start_a;
(void)range_start_b;
(void)range_end_a;
(void)range_end_b;
#else
assert(range_start_a == range_start_b && range_end_a == range_end_b);
#endif
}
};
// The iterator class
template <typename octet_iterator>
template <
typename octet_iterator,
typename error_policy=ErrorPolicyThrow<octet_iterator>
>
class iterator : public std::iterator <std::bidirectional_iterator_tag, uint32_t> {
octet_iterator it;
octet_iterator range_start;
@ -276,8 +321,7 @@ namespace utf8
const octet_iterator& range_end) :
it(octet_it), range_start(range_start), range_end(range_end)
{
if (it < range_start || it > range_end)
throw std::out_of_range("Invalid utf-8 iterator position");
error_policy::check_in_range(it, range_start, range_end);
}
// the default "big three" are OK
octet_iterator base () const { return it; }
@ -288,8 +332,7 @@ namespace utf8
}
bool operator == (const iterator& rhs) const
{
if (range_start != rhs.range_start || range_end != rhs.range_end)
throw std::logic_error("Comparing utf-8 iterators defined with different ranges");
error_policy::check_same_range(range_start, rhs.range_start, range_end, rhs.range_end);
return (it == rhs.it);
}
bool operator != (const iterator& rhs) const
@ -323,5 +366,3 @@ namespace utf8
} // namespace utf8
#endif //header guard