Skip to content

Commit

Permalink
馃Υ Add scaffolding for normalized_iterator
Browse files Browse the repository at this point in the history
  • Loading branch information
ThePhD committed Jul 1, 2022
1 parent 56fbd40 commit bf20f1c
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 7 deletions.
2 changes: 1 addition & 1 deletion include/ztd/text/basic_text_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ namespace ztd { namespace text {
using _CodePointView = decode_view<encoding_type, range_type, remove_cvref_t<_ViewErrorHandler>, state_type>;

template <typename _ViewErrorHandler = error_handler_type>
using _NormalizedView = normalized_view<_CodePointView<_ViewErrorHandler>>;
using _NormalizedView = normalized_view<_NormalizationForm, _CodePointView<_ViewErrorHandler>>;

range_type _M_storage;
encoding_type _M_encoding;
Expand Down
93 changes: 89 additions & 4 deletions include/ztd/text/normalized_iterator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include <ztd/ranges/default_sentinel.hpp>
#include <ztd/idk/ebco.hpp>
#include <ztd/idk/type_traits.hpp>
#include <ztd/static_containers/static_vector.hpp>

#include <array>

Expand All @@ -53,31 +54,53 @@ namespace ztd { namespace text {

using normalized_sentinel_t = ranges::default_sentinel_t;

//////
/// @brief An iterator that walks over the code points of a sequence as-if they were normalized.
///
/// @tparam _NormalizationForm The normalization form to apply to the sequence of code points.
/// @tparam _Range The sequence of code points to iterate over.
//////
template <typename _NormalizationForm, typename _Range>
class normalized_iterator : private ebco<_NormalizationForm, 0>, private ebco<_Range, 1> {
private:
using __base_normalization_form = ebco<_NormalizationForm, 0>;
using __base_range = ebco<_Range, 1>;
using _UNormalizationForm = remove_cvref_t<unwrap_t<_NormalizationForm>>;
using _URange = remove_cvref_t<unwrap_t<_Range>>;
using __code_point = ranges::range_value_type_t<_URange>;

public:
//////
/// @brief The code point type.
using value_type = __code_point;

//////
/// @brief Default constructor. Defaulted.
constexpr normalized_iterator() = default;

//////
/// @brief Constructs with the given `__normalization_form`.
///
/// @param[in] __normalization_form The normalization form object to use for this iterator.
//////
constexpr normalized_iterator(_NormalizationForm __normalization_form) noexcept(
::std::is_nothrow_move_constructible_v<_NormalizationForm> // cf-hack
&& ::std::is_nothrow_default_constructible_v<_Range>)
: __base_normalization_form(::std::move(__normalization_form)), __base_range() {
}

//////
/// @brief Constructs with the given `__normalization_form`.
///
/// @param[in] __normalization_form The normalization form object to use for this iterator.
/// @param[in] __range The range this normalization iterator will walk over.
//////
constexpr normalized_iterator(_NormalizationForm __normalization_form, _Range __range) noexcept(
::std::is_nothrow_move_constructible_v<_NormalizationForm> // cf-hack
&& ::std::is_nothrow_move_constructible_v<_Range>)
: __base_normalization_form(::std::move(__normalization_form)), __base_range(::std::move(__range)) {
}

//////
/// @brief Default constructor. Defaulted.
constexpr normalized_iterator() = default;

//////
/// @brief Copy constructor. Defaulted.
constexpr normalized_iterator(const normalized_iterator&) = default;
Expand All @@ -92,6 +115,68 @@ namespace ztd { namespace text {
//////
/// @brief Move assignment operator. Defaulted.
constexpr normalized_iterator& operator=(normalized_iterator&&) = default;

//////
/// @brief Retrieves the next code point in the normalized view of the underlying range.
constexpr normalized_iterator& operator++() noexcept {
if (this->_M_cursor == this->_M_normalized.size()) {
this->_M_get_more();
}
return *this;
}

//////
/// @brief The current code point in the normalized range.
constexpr value_type operator*() const noexcept {
return this->_M_normalized[static_cast<::std::size_t>(this->_M_cursor)];
}

//////
/// @brief Compares an iterator to its sentinel, which tests for whether the iteration is complete.
///
/// @param[in] __it The iterator to check against the sentinel.
//////
friend constexpr bool operator==(const normalized_iterator& __it, const normalized_sentinel_t&) noexcept {
const _URange& __range = __it.__base_range::get_value();
return ::ztd::ranges::ranges_adl::adl_empty(__range);
}

//////
/// @brief Compares an iterator to its sentinel, which tests for whether the iteration is complete.
///
/// @param[in] __it The iterator to check against the sentinel.
//////
friend constexpr bool operator==(const normalized_sentinel_t&, const normalized_iterator& __it) noexcept {
const _URange& __range = __it.__base_range::get_value();
return ::ztd::ranges::ranges_adl::adl_empty(__range);
}

//////
/// @brief Compares an iterator to its sentinel, which tests for whether the iteration is complete.
///
/// @param[in] __it The iterator to check against the sentinel.
//////
friend constexpr bool operator!=(const normalized_iterator& __it, const normalized_sentinel_t&) noexcept {
const _URange& __range = __it.__base_range::get_value();
return !::ztd::ranges::ranges_adl::adl_empty(__range);
}

//////
/// @brief Compares an iterator to its sentinel, which tests for whether the iteration is complete.
///
/// @param[in] __it The iterator to check against the sentinel.
//////
friend constexpr bool operator!=(const normalized_sentinel_t&, const normalized_iterator& __it) noexcept {
const _URange& __range = __it.__base_range::get_value();
return !::ztd::ranges::ranges_adl::adl_empty(__range);
}

private:
constexpr void _M_get_more() noexcept {
}

static_vector<__code_point, 8> _M_normalized;
unsigned char _M_cursor = 0;
};

//////
Expand Down
15 changes: 13 additions & 2 deletions include/ztd/text/normalized_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,20 +65,31 @@ namespace ztd { namespace text {
using range_type = _Range;
//////
/// @brief The encoding type used for transformations.
using normalization_form = _NormalizationFOrm;
using normalization_form = _NormalizationForm;

//////
/// @brief Constructs with the given `__normalization_form`.
///
/// @param[in] __normalization_form The normalization form object to use for this iterator.
//////
constexpr normalized_view(normalization_form __normalization_form) noexcept(
::std::is_nothrow_constructible_v<iterator, normalization_form>)
: _M_it(::std::move(__normalization_form)) {
}

//////
/// @brief Constructs with the given `__normalization_form`.
///
/// @param[in] __normalization_form The normalization form object to use for this iterator.
/// @param[in] __range The range this normalization iterator will walk over.
//////
constexpr normalized_view(normalization_form __normalization_form, range_type __range) noexcept(
::std::is_nothrow_constructible_v<iterator, normalization_form, range_type>)
: _M_it(::std::move(__normalization_form), ::std::move(__range)) {
}

//////
/// @brief Constructs an encoding_view from one of its iterators, reconstituting the range.
/// @brief Constructs from one of its iterators, reconstituting the range.
///
/// @param[in] __it A previously-made normalized_view iterator.
//////
Expand Down

0 comments on commit bf20f1c

Please sign in to comment.