<commit_before>﻿/* -*- coding: utf-8; mode: c++; tab-width: 3; indent-tabs-mode: nil -*-

Copyright 2014
<NAME>

This file is part of Abaclade.

Abaclade is free software: you can redistribute it and/or modify it under the terms of the GNU
General Public License as published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

Abaclade is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
Public License for more details.

You should have received a copy of the GNU General Public License along with Abaclade. If not, see
<http://www.gnu.org/licenses/>.
--------------------------------------------------------------------------------------------------*/

#ifndef _ABACLADE_HXX
   #error Please #include <abaclade.hxx> instead of this file
#endif



////////////////////////////////////////////////////////////////////////////////////////////////////
// abc::text::_codepoint_proxy


namespace abc {
namespace text {

/** TODO: comment.
*/
template <bool t_bConst>
class _codepoint_proxy;

// Const specialization.
template <>
class _codepoint_proxy<true> {
public:

   /** Constructor.

   pch
      Pointer to the character(s) that this proxy will present as char32_t.
   ps
      Pointer to the string that contains *pch.
   cpp
      Source code point proxy to copy.
   */
   _codepoint_proxy(char_t const * pch, str_base const * ps) :
      m_pch(pch),
      m_ps(ps) {
   }
   _codepoint_proxy(_codepoint_proxy const & cpp) :
      m_pch(cpp.m_pch),
      m_ps(cpp.m_ps) {
   }


   /** Implicit conversion to a code point.

   return
      Code point that the proxy is currently referencing.
   */
   operator char32_t() const {
      return host_char_traits::chars_to_codepoint(m_pch);
   }


private:

   _codepoint_proxy & operator=(_codepoint_proxy const & cpp);


protected:

   char_t const * m_pch;
   str_base const * m_ps;
};

// Non-const specialization.
template <>
class _codepoint_proxy<false> :
   public _codepoint_proxy<true> {
public:

   /** See _codepoint_proxy<true>::_codepoint_proxy().
   */
   _codepoint_proxy(char_t * pch, str_base * ps) :
      _codepoint_proxy<true>(pch, ps) {
   }
   _codepoint_proxy(_codepoint_proxy const & cpp) :
      _codepoint_proxy<true>(cpp) {
   }


   /** Assignment operator.

   ch
      Source character.
   cpp
      Source code point proxy to copy a code point from.
   return
      *this.
   */
   _codepoint_proxy & operator=(char_t ch);
#if ABC_HOST_UTF > 8
   _codepoint_proxy & operator=(char ch) {
      return operator=(host_char(ch));
   }
#endif
   _codepoint_proxy & operator=(char32_t ch);
   _codepoint_proxy & operator=(_codepoint_proxy const & cpp) {
      return operator=(cpp.operator char32_t());
   }
};

} //namespace text
} //namespace abc


// Relational operators. Provided so that comparisons between char32_t (from _codepoint_proxy) and
// char{,8,16}_t don’t raise warnings.
#define ABC_RELOP_IMPL(op) \
   template <bool t_bConst1, bool t_bConst2> \
   inline bool operator op( \
      abc::text::_codepoint_proxy<t_bConst1> const & cpp1, \
      abc::text::_codepoint_proxy<t_bConst2> const & cpp2 \
   ) { \
      return cpp1.operator char32_t() op cpp2.operator char32_t(); \
   } \
   template <bool t_bConst> \
   inline bool operator op(abc::text::_codepoint_proxy<t_bConst> const & cpp, abc::char_t ch) { \
      return cpp.operator char32_t() op abc::text::codepoint(ch); \
   } \
   template <bool t_bConst> \
   inline bool operator op(abc::char_t ch, abc::text::_codepoint_proxy<t_bConst> const & cpp) { \
      return abc::text::codepoint(ch) op cpp.operator char32_t(); \
   } \
   template <bool t_bConst> \
   inline bool operator op(abc::text::_codepoint_proxy<t_bConst> const & cpp, char32_t ch) { \
      return cpp.operator char32_t() op ch; \
   } \
   template <bool t_bConst> \
   inline bool operator op(char32_t ch, abc::text::_codepoint_proxy<t_bConst> const & cpp) { \
      return ch op cpp.operator char32_t(); \
   }
ABC_RELOP_IMPL(==)
ABC_RELOP_IMPL(!=)
ABC_RELOP_IMPL(>)
ABC_RELOP_IMPL(>=)
ABC_RELOP_IMPL(<)
ABC_RELOP_IMPL(<=)
#undef ABC_RELOP_IMPL

#if ABC_HOST_UTF > 8
   #define ABC_RELOP_IMPL(op) \
      template <bool t_bConst> \
      inline bool operator op(abc::text::_codepoint_proxy<t_bConst> const & cpp, char ch) { \
         return operator op(cpp, abc::text::host_char(ch)); \
      } \
      template <bool t_bConst> \
      inline bool operator op(char ch, abc::text::_codepoint_proxy<t_bConst> const & cpp) { \
         return operator op(abc::text::host_char(ch), cpp); \
      }
   ABC_RELOP_IMPL(==)
   ABC_RELOP_IMPL(!=)
   ABC_RELOP_IMPL(>)
   ABC_RELOP_IMPL(>=)
   ABC_RELOP_IMPL(<)
   ABC_RELOP_IMPL(<=)
   #undef ABC_RELOP_IMPL
#endif


////////////////////////////////////////////////////////////////////////////////////////////////////
// abc::text::_codepoint_iterator_impl


namespace abc {
namespace text {

/** Base class for codepoint_iterator. Its specializations include all the members that don’t return
an iterator or a reference to one, so that those are only defined once in the “real” template
codepoint_iterator instead of once for each specialization.
*/
template <bool t_bConst>
class _codepoint_iterator_impl;

// Const specialization.
template <>
class ABACLADE_SYM _codepoint_iterator_impl<true> {
public:

   /** Dereferencing operator.

   return
      Reference to the current character.
   */
   _codepoint_proxy<true> operator*() const {
      return _codepoint_proxy<true>(throw_if_end(m_pch), m_ps);
   }


   /** Element access operator.

   i
      Index relative to *this. If the resulting index is outside of the string’s [begin, end) range,
      an index_error exception will be thrown.
   return
      Reference to the specified item.
   */
   _codepoint_proxy<true> operator[](ptrdiff_t i) const {
      return _codepoint_proxy<true>(throw_if_end(advance(i, true)), m_ps);
   }


   /** Returns the underlying iterator type.

   return
      Pointer to the value pointed to by this iterator.
   */
   char_t const * base() const {
      return m_pch;
   }


   /** Returns the string that created this iterator.

   return
      Pointer to the value pointed to by this iterator.
   */
   str_base const * _str() const {
      return m_ps;
   }


protected:

   /** Constructor.

   pch
      Pointer to set the iterator to.
   ps
      Pointer to the string that is creating the iterator.
   */
   _codepoint_iterator_impl(char_t const * pch, str_base const * ps) :
      m_pch(pch),
      m_ps(ps) {
   }


   /** Invokes m_ps->_advance_char_ptr(). See abc::str_base::_advance_char_ptr().
   */
   char_t const * advance(ptrdiff_t i, bool bIndex) const;


   /** Computes the distance from another iterator/pointer.

   pch
      Pointer from which to calculate the distance.
   return
      Distance between *this and pch, in code points.
   */
   ptrdiff_t distance(char_t const * pch) const;


   /** Throws an iterator_error if the specified pointer is the end of the string.

   pch
      Pointer to validate.
   */
   char_t const * throw_if_end(char_t const * pch) const;


protected:

   char_t const * m_pch;
   str_base const * m_ps;
};

// Non-const specialization.
template <>
class _codepoint_iterator_impl<false> :
   public _codepoint_iterator_impl<true> {
public:

   /** See _codepoint_iterator_impl<true>::operator*().
   */
   _codepoint_proxy<false> operator*() {
      return _codepoint_proxy<false>(
         const_cast<char_t *>(throw_if_end(m_pch)), const_cast<str_base *>(m_ps)
      );
   }
   _codepoint_proxy<true> operator*() const {
      return _codepoint_iterator_impl<true>::operator*();
   }


   /** See _codepoint_iterator_impl<true>::operator[]().
   */
   _codepoint_proxy<false> operator[](ptrdiff_t i) {
      return _codepoint_proxy<false>(
         const_cast<char_t *>(throw_if_end(advance(i, true))), const_cast<str_base *>(m_ps)
      );
   }
   _codepoint_proxy<true> operator[](ptrdiff_t i) const {
      return _codepoint_iterator_impl<true>::operator[](i);
   }


   /** See _codepoint_iterator_impl<true>::base().
   */
   char_t * base() const {
      return const_cast<char_t *>(m_pch);<commit_msg>Use using directive to avoid code duplication<commit_after>﻿/* -*- coding: utf-8; mode: c++; tab-width: 3; indent-tabs-mode: nil -*-

Copyright 2014
<NAME>

This file is part of Abaclade.

Abaclade is free software: you can redistribute it and/or modify it under the terms of the GNU
General Public License as published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

Abaclade is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
Public License for more details.

You should have received a copy of the GNU General Public License along with Abaclade. If not, see
<http://www.gnu.org/licenses/>.
--------------------------------------------------------------------------------------------------*/

#ifndef _ABACLADE_HXX
   #error Please #include <abaclade.hxx> instead of this file
#endif



////////////////////////////////////////////////////////////////////////////////////////////////////
// abc::text::_codepoint_proxy


namespace abc {
namespace text {

/** TODO: comment.
*/
template <bool t_bConst>
class _codepoint_proxy;

// Const specialization.
template <>
class _codepoint_proxy<true> {
public:

   /** Constructor.

   pch
      Pointer to the character(s) that this proxy will present as char32_t.
   ps
      Pointer to the string that contains *pch.
   cpp
      Source code point proxy to copy.
   */
   _codepoint_proxy(char_t const * pch, str_base const * ps) :
      m_pch(pch),
      m_ps(ps) {
   }
   _codepoint_proxy(_codepoint_proxy const & cpp) :
      m_pch(cpp.m_pch),
      m_ps(cpp.m_ps) {
   }


   /** Implicit conversion to a code point.

   return
      Code point that the proxy is currently referencing.
   */
   operator char32_t() const {
      return host_char_traits::chars_to_codepoint(m_pch);
   }


private:

   _codepoint_proxy & operator=(_codepoint_proxy const & cpp);


protected:

   char_t const * m_pch;
   str_base const * m_ps;
};

// Non-const specialization.
template <>
class _codepoint_proxy<false> :
   public _codepoint_proxy<true> {
public:

   /** See _codepoint_proxy<true>::_codepoint_proxy().
   */
   _codepoint_proxy(char_t * pch, str_base * ps) :
      _codepoint_proxy<true>(pch, ps) {
   }
   _codepoint_proxy(_codepoint_proxy const & cpp) :
      _codepoint_proxy<true>(cpp) {
   }


   /** Assignment operator.

   ch
      Source character.
   cpp
      Source code point proxy to copy a code point from.
   return
      *this.
   */
   _codepoint_proxy & operator=(char_t ch);
#if ABC_HOST_UTF > 8
   _codepoint_proxy & operator=(char ch) {
      return operator=(host_char(ch));
   }
#endif
   _codepoint_proxy & operator=(char32_t ch);
   _codepoint_proxy & operator=(_codepoint_proxy const & cpp) {
      return operator=(cpp.operator char32_t());
   }
};

} //namespace text
} //namespace abc


// Relational operators. Provided so that comparisons between char32_t (from _codepoint_proxy) and
// char{,8,16}_t don’t raise warnings.
#define ABC_RELOP_IMPL(op) \
   template <bool t_bConst1, bool t_bConst2> \
   inline bool operator op( \
      abc::text::_codepoint_proxy<t_bConst1> const & cpp1, \
      abc::text::_codepoint_proxy<t_bConst2> const & cpp2 \
   ) { \
      return cpp1.operator char32_t() op cpp2.operator char32_t(); \
   } \
   template <bool t_bConst> \
   inline bool operator op(abc::text::_codepoint_proxy<t_bConst> const & cpp, abc::char_t ch) { \
      return cpp.operator char32_t() op abc::text::codepoint(ch); \
   } \
   template <bool t_bConst> \
   inline bool operator op(abc::char_t ch, abc::text::_codepoint_proxy<t_bConst> const & cpp) { \
      return abc::text::codepoint(ch) op cpp.operator char32_t(); \
   } \
   template <bool t_bConst> \
   inline bool operator op(abc::text::_codepoint_proxy<t_bConst> const & cpp, char32_t ch) { \
      return cpp.operator char32_t() op ch; \
   } \
   template <bool t_bConst> \
   inline bool operator op(char32_t ch, abc::text::_codepoint_proxy<t_bConst> const & cpp) { \
      return ch op cpp.operator char32_t(); \
   }
ABC_RELOP_IMPL(==)
ABC_RELOP_IMPL(!=)
ABC_RELOP_IMPL(>)
ABC_RELOP_IMPL(>=)
ABC_RELOP_IMPL(<)
ABC_RELOP_IMPL(<=)
#undef ABC_RELOP_IMPL

#if ABC_HOST_UTF > 8
   #define ABC_RELOP_IMPL(op) \
      template <bool t_bConst> \
      inline bool operator op(abc::text::_codepoint_proxy<t_bConst> const & cpp, char ch) { \
         return operator op(cpp, abc::text::host_char(ch)); \
      } \
      template <bool t_bConst> \
      inline bool operator op(char ch, abc::text::_codepoint_proxy<t_bConst> const & cpp) { \
         return operator op(abc::text::host_char(ch), cpp); \
      }
   ABC_RELOP_IMPL(==)
   ABC_RELOP_IMPL(!=)
   ABC_RELOP_IMPL(>)
   ABC_RELOP_IMPL(>=)
   ABC_RELOP_IMPL(<)
   ABC_RELOP_IMPL(<=)
   #undef ABC_RELOP_IMPL
#endif


////////////////////////////////////////////////////////////////////////////////////////////////////
// abc::text::_codepoint_iterator_impl


namespace abc {
namespace text {

/** Base class for codepoint_iterator. Its specializations include all the members that don’t return
an iterator or a reference to one, so that those are only defined once in the “real” template
codepoint_iterator instead of once for each specialization.
*/
template <bool t_bConst>
class _codepoint_iterator_impl;

// Const specialization.
template <>
class ABACLADE_SYM _codepoint_iterator_impl<true> {
public:

   /** Dereferencing operator.

   return
      Reference to the current character.
   */
   _codepoint_proxy<true> operator*() const {
      return _codepoint_proxy<true>(throw_if_end(m_pch), m_ps);
   }


   /** Element access operator.

   i
      Index relative to *this. If the resulting index is outside of the string’s [begin, end) range,
      an index_error exception will be thrown.
   return
      Reference to the specified item.
   */
   _codepoint_proxy<true> operator[](ptrdiff_t i) const {
      return _codepoint_proxy<true>(throw_if_end(advance(i, true)), m_ps);
   }


   /** Returns the underlying iterator type.

   return
      Pointer to the value pointed to by this iterator.
   */
   char_t const * base() const {
      return m_pch;
   }


   /** Returns the string that created this iterator.

   return
      Pointer to the value pointed to by this iterator.
   */
   str_base const * _str() const {
      return m_ps;
   }


protected:

   /** Constructor.

   pch
      Pointer to set the iterator to.
   ps
      Pointer to the string that is creating the iterator.
   */
   _codepoint_iterator_impl(char_t const * pch, str_base const * ps) :
      m_pch(pch),
      m_ps(ps) {
   }


   /** Invokes m_ps->_advance_char_ptr(). See abc::str_base::_advance_char_ptr().
   */
   char_t const * advance(ptrdiff_t i, bool bIndex) const;


   /** Computes the distance from another iterator/pointer.

   pch
      Pointer from which to calculate the distance.
   return
      Distance between *this and pch, in code points.
   */
   ptrdiff_t distance(char_t const * pch) const;


   /** Throws an iterator_error if the specified pointer is the end of the string.

   pch
      Pointer to validate.
   */
   char_t const * throw_if_end(char_t const * pch) const;


protected:

   char_t const * m_pch;
   str_base const * m_ps;
};

// Non-const specialization.
template <>
class _codepoint_iterator_impl<false> :
   public _codepoint_iterator_impl<true> {
public:

   /** See _codepoint_iterator_impl<true>::operator*().
   */
   using _codepoint_iterator_impl<true>::operator*;
   _codepoint_proxy<false> operator*() {
      return _codepoint_proxy<false>(
         const_cast<char_t *>(throw_if_end(m_pch)), const_cast<str_base *>(m_ps)
      );
   }


   /** See _codepoint_iterator_impl<true>::operator[]().
   */
   using _codepoint_iterator_impl<true>::operator[];
   _codepoint_proxy<false> operator[](ptrdiff_t i) {
      return _codepoint_proxy<false>(
         const_cast<char_t *>(throw_if_end(advance(i, true))), const_cast<str_base *>(m_ps)
      );
   }


   /** See _codepoint_iterator_impl<true>::base().
   */
   char_t * base() const {
      return const_cast<char_t *>(m_pch);
{'fraction_non_alphanumeric': 0.13909524672344023, 'fraction_numerical': 0.005556562179138733, 'mean_word_length': 2.856078248719143, 'pattern_counts': {'":': 0, '<': 115, '<?xml version=': 0, '>': 121, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1205359', 'n_tokens_mistral': 5519, 'n_tokens_neox': 5457, 'n_words': 1462}