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:
parent
a377c642ff
commit
73bd06b5d6
1 changed files with 48 additions and 7 deletions
|
@ -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
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue