text:
// SPDX-License-Identifier: Apache-2.0
// Copyright Apache Software Foundation 2019
/** @file

   Class for handling "views" of text. Views presume the memory for the buffer is managed
   elsewhere and allow efficient access to segments of the buffer without copies. Views are read
   only as the view doesn't own the memory. Along with generic buffer methods are specialized
   methods to support better string parsing, particularly token based parsing.

   This class is based on @c std::string_view and is easily and cheaply converted to and from that
   class.
*/

#pragma once
#include <bitset>
#include <iosfwd>
#include <memory.h>
#include <string>
#include <string_view>
#include <limits>

#include "swoc/swoc_version.h"
#include "tscpp/util/string_view_util.h"

namespace swoc { inline namespace SWOC_VERSION_NS {

class TextView;

/** A read only view of a contiguous piece of memory.

    A @c TextView does not own the memory to which it refers, it is simply a view of part of some
    (presumably) larger memory object. The purpose is to allow working in a read only way a specific
    part of the memory. A classic example for ATS is working with HTTP header fields and values
    which need to be accessed independently but preferably without copying. A @c TextView supports
    this style.

    @note To simplify the interface there is no constructor taking only a character pointer.
    Constructors require either a literal string or an explicit length. This avoid ambiguities which
    are much more annoying that explicitly calling @c strlen on a character pointer.

    @internal For construction, assignment operator, and @c assign method, there are a lot of overloads
    because users would like to be able to use the same sort of arguments for all of these. This includes
    - self / parent type
    - @c std::string
    - literal string
    - C-string
    - pointer and count
    - begin/end style pointers.
 */
class TextView : public std::string_view {
  using self_type  = TextView;         ///< Self reference type.
  using super_type = std::string_view; ///< Parent type.

public:
  /// Default constructor (empty buffer).
  constexpr TextView() noexcept = default;

  /// Construct from a @c std::string_view or @c TextView
  /// @note This provides an user defined conversion from @c std::string_view to @c TextView. The
  /// reverse conversion is implicit in @c TextView being a subclass of @c std::string_view.
  constexpr TextView(super_type const &that) noexcept;

  /** Construct from pointer and size.
   *
   * @param ptr Pointer to first character.
   * @param n Number of characters.
   *
   * If @a n is @c npos then @c ptr is presumed to be a C string and checked for length. If @c ptr
   * is @c nullptr the length is 0. Otherwise @c strlen is used to calculate the length.
   */
  constexpr TextView(const char *ptr, size_t n) noexcept;

  /** Construct from a half open range [first, last).
   *
   * @param first Start of half open range.
   * @param last End of half open range.
   *
   * The character at @a first will be in the view, but the character at @a last will not.
   */
  constexpr TextView(char const *first, char const *last) noexcept;

  /** Construct from any character container following STL standards.
   *
   * @tparam C Container type.
   * @param c container
   *
   * The container type must have the methods @c data and @c size which must return values convertible
   * to @c char @c const @c * and @c size_t respectively.
   */
  template < typename C
    , typename = std::enable_if_t<
        std::is_convertible_v<decltype(std::declval<C>().data()), char const*> &&
        std::is_convertible_v<decltype(std::declval<C>().size()), size_t>
        , void
      >
  > constexpr TextView(C const& c);

  /** Construct from literal string or array.

      All elements of the array are included in the view unless the last element is nul, in which case it is elided.
      If this is inappropriate then a constructor with an explicit size should be used.

      @code
        TextView a("A literal string");
      @endcode
      The last character in @a a will be 'g'.
   */
  template <size_t N> constexpr TextView(const char (&s)[N]) noexcept;

  /** Construct from a C-string.
   *
   * @param src A pointer to a C-string.
   *
   * @internal This is a reference because it is otherwise ambiguous with the array constructor.
   */
  TextView(char *&src) : super_type(src) {}

  /** Construct from a const C-string.
   *
   * @param src Pointer to a const C-string.
   *
   * @internal This is a reference because it is otherwise ambiguous with the array constructor.
   */
  TextView(char const *&src) : super_type(src) {}

  /** Construct from nullptr.
      This implicitly makes the length 0.
  */
  constexpr TextView(std::nullptr_t) noexcept;

  /// Construct from @c std::string, referencing the entire string contents.
  /// @internal This can't be @c constexpr because this uses methods in @c std::string that may
  /// not be @c constexpr.
  TextView(std::string const &str) noexcept;

  /// Assign a super class instance, @c std::string_view  to @a this.
  self_type &operator=(super_type const &that);

  /// Assign a constant array to @a this.
  /// @note If the last character of @a s is a nul byte, it is not included in the view.
  template <size_t N> self_type &operator=(const char (&s)[N]);

  /// Assign from C-string @a s.
  self_type &operator=(char *&s);
  /// Assign from C-string @a s.
  self_type &operator=(char const *&s);

  /// Assign from a @c std::string.
  self_type &operator=(const std::string &s);

  /** Assign a view of the @a c_str
   *
   * @param c_str Pointer to C string.
   * @return @a this
   *
   * @note @c c_str must be a null terminated string. The null byte is not included in the view.
   */
  self_type &assign(char *&c_str);

  /** Assign a view of the @a c_str
   *
   * @param c_str Pointer to C string.
   * @return @a this
   *
   * @note @c c_str must be a null terminated string. The null byte is not included in the view.
   */
  self_type &assign(char const *&c_str);

  /// Explicitly set the start @a ptr and size @a n of the view.
  self_type &assign(char const *ptr, size_t n);

  /** Assign the half open view [ @a b , @a e ) to @a this
   *
   * @param b First character in the view.
   * @param e One character after the last character in the view.
   * @return @a this
   */
  self_type &assign(char const *b, char const *e);

  /// Explicitly set the view from a @c std::string
  self_type &assign(std::string const &s);

  /** Assign from any character container following STL standards.
   *
   * @tparam C Container type.
   * @param c container
   *
   * The container type must have the methods @c data and @c size which must return values convertible
   * to @c char @c const @c * and @c size_t respectively.
   */
  template < typename C
            , typename = std::enable_if_t<
                std::is_convertible_v<decltype(std::declval<C>().data()), char const*> &&
                std::is_convertible_v<decltype(std::declval<C>().size()), size_t>
                , void
              >
            > constexpr self_type & assign(C const& c) {
    return this->assign(c.data(), c.size());
  }

  /** Dereference operator.

      @note This allows the view to be used as if it were a character iterator to a null terminated
      string which is handy for several other STL interfaces.

      @return The first byte in the view, or a nul character if the view is empty.
  */
  /// @return The first byte in the view.
  constexpr char operator*() const;

  /** Discard the first byte of the view.
   *
   *  @return @a this.
   */
  self_type &operator++();

  /** Discard the first byte of the view.
   *
   * @return The view before discarding the byte.
   */
  self_type operator++(int);

  /** Discard the first @a n bytes of the view.
   *
   *  Equivalent to @c remove_prefix(n).
   *  @return @a this
   */
  self_type &operator+=(size_t n);

  /// Check for empty view.
  /// @return @c true if the view has a nullptr @b or zero size.
  constexpr bool operator!() const noexcept;

  /// Check for non-empty view.
  /// @return @c true if the view refers to a non-empty range of bytes.
  explicit constexpr operator bool() const noexcept;

  /// Clear the view (become an empty view).
  self_type &clear();

  /// Get the offset of the first character for which @a pred is @c true.
  template <typename F> size_t find_if(F const &pred) const;
  /// Get the offset of the last character for which @a pred is @c true.
  template <typename F> size_t rfind_if(F const &pred) const;

  /** Remove bytes that match @a c from the start of the view.
   *
   * @return @a this
   */
  self_type &ltrim(char c);

  /** Remove bytes from the start of the view that are in @a delimiters.
   *
   * @return @a this
   */
  self_type &ltrim(std::string_view const &delimiters);

  /** Remove bytes from the start of the view that are in @a delimiters.
   *
   * @internal This is needed to avoid collisions with the templated predicate style.
   *
   * @return @c *this
   */
  self_type &ltrim(const char *delimiters);

  /** Remove bytes from the start of the view for which @a pred is @c true.
      @a pred must be a functor taking a @c char argument and returning @c bool.
      @return @c *this
  */
  template <typename F> self_type &ltrim_if(F const &pred);

  /** Remove bytes that match @a c from the end of the view.
   *
   * @return @a this
   */
  self_type &rtrim(char c);

  /** Remove bytes from the end of the view that are in @a delimiters.
   * @return @a this
   */
  self_type &rtrim(std::string_view const &delimiters);

  /** Remove bytes from the end of the view for which @a pred is @c true.
   *
   * @a pred must be a functor taking a @c char argument and returning @c bool.
   *
   * @return @c *this
   */
  template <typename F> self_type &rtrim_if(F const &pred);

  /** Remove bytes that match @a c from the start and end of this view.
   *
   * @return @a this
   */
  self_type &trim(char c);

  /** Remove bytes from the start and end of the view that are in @a delimiters.
   * @return @a this
   */
  self_type &trim(std::string_view const &delimiters);

  /** Remove bytes from the start and end of the view that are in @a delimiters.
      @internal This is needed to avoid collisions with the templated predicate style.
      @return @c *this
  */
  self_type &trim(const char *delimiters);

  /** Remove bytes from the start and end of the view for which @a pred is @c true.
      @a pred must be a functor taking a @c char argument and returning @c bool.
      @return @c *this
  */
  template <typename F> self_type &trim_if(F const &pred);

  /** Get a view of the first @a n bytes.
   *
   * @param n Number of chars in the prefix.
   * @return A view of the first @a n characters in @a this, bounded by the size of @a this.
   */
  constexpr self_type prefix(size_t n) const noexcept;

  /** Get a view of a prefix bounded by @a c.
   *
   * @param c Delimiter character.
   * @return A view of the prefix bounded by @a c, or all of @a this if @a c is not found.
   * @note The character @a c is not included in the returned view.
   */
  self_type prefix_at(char c) const;

  /** Get a view of a prefix bounded by a character in @a delimiters.
   *
   * @param delimiters A set of characters.
   *
   * @return A view of the prefix bounded by any character in @a delimiters, or empty if none are
   * found.
   *
   * @note The delimiter character is not included in the returned view.
   */
  self_type prefix_at(std::string_view const &delimiters) const;

  /** Get a view of a prefix bounded by a character predicate @a pred.
   *
   * @a pred must be a functor which takes a @c char argument and returns @c bool. Each character in
   * @a this is tested by @a pred and the prefix is delimited by the first character for which @a
   * pred is @c true.
   *
   * @param pred A character predicate.
   *
   * @return A view of the prefix bounded by @a pred or empty if @a pred is not @c true for any
   * characer.
   *
   * @note The deliminting character is not included in the returned view.
   */
  template <typename F> self_type prefix_if(F const &pred) const;

  /** Remove bytes from the start of the view.
   *
   * @param n Number of bytes to remove.
   * @return @a this.
   */
  self_type &remove_prefix(size_t n);

  /** Remove bytes from the end of the view.
   *
   * @param n Number of bytes to remove.
   * @return @a this.
   */
  self_type &remove_suffix(size_t n);

  /** Remove the leading characters of @a this up to and including @a c.
   *
   * @param c Delimiter character.
   * @return @a this.
   * @note The first occurrence of character @a c is removed along with all preceding characters, or
   * the view is cleared if @a c is not found.
   */
  self_type &remove_prefix_at(char c);

  /** Remove the leading characters of @a this up to and including the first character matching @a delimiters.
   *
   * @param delimiters Characters to match.
   * @return @a this.
   * @note The first occurrence of any character in @a delimiters is removed along with all preceding
   * characters, or the view is cleared if none are found.
   */
  self_type &remove_prefix_at(std::string_view const &delimiters);

  /** Remove the leading characters up to and including the character selected by @a pred.
   *
   * @tparam F Predicate function type.
   * @param pred The predicate instance.
   * @return @a this.
   *
   * Characters are removed until @a pred returns @c true. The matching character is also removed.
   */
  template <typename F> self_type &remove_prefix_if(F const &pred);

  /** Remove and return a prefix of size @a n.
   *
   * @param n Size of the prefix.
   * @return The first @a n bytes of @a this if @a n is in @a this, otherwise an empty view.
   *
   * The prefix is removed and returned if the requested prefix is no larger than @a this,
   * otherwise @a this is not modified.
   *
   * @note The character at offset @a n is discarded if @a this is modified.
   *
   * @see @c take_prefix
   */
  self_type split_prefix(size_t n);

  /** Remove and return a prefix bounded by the first occurrence of @a c.
   *
   * @param c The character to match.
   * @return The prefix bounded by @a c if @a c is found, an empty view if not.
   *
   * The prefix is removed and returned if @a c is found, otherwise @a this is not modified.
   *
   * @note The delimiter character is discarded if @a this is modified.
   *
   * @see @c take_prefix
   */
  self_type split_prefix_at(char c);

  /** Remove and return a prefix bounded by the first occurrence of any of @a delimiters.
   *
   * @param delimiters The characters to match.
   * @return The prefix bounded by a delimiter if one is found, otherwise an empty view.
   *
   * The prefix is removed and returned if a @a delimiter is found, otherwise @a this is not modified.
   *
   * @note The matching character is discarded if @a this is modified.
   *
   * @see @c take_prefix_at
   */
  self_type split_prefix_at(std::string_view const &delimiters);

  /** Remove and return a prefix bounded by the first character that satisfies @a pred.
   *
   * @tparam F Predicate functor type.
   * @param pred A function taking @c char and returning @c bool.
   * @return The prefix bounded by the first character satisfying @a pred.
   *
   * The prefix is removed and returned if a character satisfying @a pred is found, otherwise
   * @a this is not modified.
   *
   * @note The matching character is discarded if @a this is modified.
   *
   * @see @c take_prefix_if
   */
  template <typename F> self_type split_prefix_if(F const &pred);

  /** Remove and return the first @a n characters.
   *
   * @param n Size of the return prefix.
   * @return The first @a n bytes of @a this if @a n is in @a this, otherwise all of @a this.
   *
   * The prefix is removed and returned if the requested prefix is no larger than @a this,
   * otherwise all of @a this is removed and returned.
   *
   * @note The character at offset @a n is discarded if @a n is within the bounds of @a this.
   *
   * @see @c split_prefix
   */
  self_type take_prefix(size_t n);

  /** Remove and return a prefix bounded by the first occurrence of @a c.
   *
   * @param c The character to match.
   * @return The prefix bounded by @a c if @a c is found, all of @a this if not.
   *
   * The prefix is removed and returned if @a c is found, otherwise all of @a this is removed and
   * returned.
   *
   * @note The character at offset @a n is discarded if found.
   *
   * @see @c split_prefix_at
   */
  self_type take_prefix_at(char c);

  /** Remove and return a prefix bounded by the first occurrence of any of @a delimiters.
   *
   * @param delimiters The characters to match.
   * @return The prefix bounded by a delimiter if one is found, otherwise all of @a this.
   *
   * The prefix is removed and returned if a @a delimiter is found, otherwise all of @a this is
   * removed and returned.
   *
   * @note The matching character is discarded if found.
   *
   * @see @c split_prefix_at
   */
  self_type take_prefix_at(std::string_view const &delimiters);

  /** Remove and return a prefix bounded by the first character that satisfies @a pred.
   *
   * @tparam F Predicate functor type.
   * @param pred A function taking @c char and returning @c bool.
   * @return The prefix bounded by the first character satisfying @a pred, or all of @a this if none
   * is found.
   *
   * The prefix is removed and returned if a a character satisfying @a pred is found, otherwise
   * all of @a this is removed and returned.
   *
   * @note The matching character is discarded if found.
   *
   * @see @c split_prefix_if
   */
  template <typename F> self_type take_prefix_if(F const &pred);

  /** Remove and return a prefix of characters satisfying @a pred
   *
   * @tparam F Predicate functor type.
   * @param pred A function taking @c char and returning @c bool.
   * @return The prefix of characters that satisfy @a pred.
   *
   * The returned prefix is removed from @a this. That prefix may be empty if the first character
   * does not satisfy @a pred.
   */
  template <typename F> self_type clip_prefix_of(F const &pred);

  /** Get a view of the last @a n bytes.
   *
   * @param n Number of chars in the prefix.
   * @return A view of the last @a n characters in @a this, bounded by the size of @a this.
   */
  constexpr self_type suffix(size_t n) const noexcept;

  /** Get a view of a suffix bounded by @a c.
   *
   * @param c Delimiter character.
   * @return A view of the suffix bounded by @a c, or all of @a this if @a c is not found.
   * @note The character @a c is not included in the returned view.
   */
  self_type suffix_at(char c) const;

  /** Get a view of a suffix bounded by a character in @a delimiters.
   *
   * @param delimiters A set of characters.
   *
   * @return A view of the suffix bounded by any character in @a delimiters, or mepty if none are
   * found.
   *
   * @note The delimiter character is not included in the returned view.
   */
  self_type suffix_at(std::string_view const &delimiters) const;

  /** Get a view of a suffix bounded by a character predicate @a pred.
   *
   * @a pred must be a functor which takes a @c char argument and returns @c bool. Each character in
   * @a this is tested by @a pred and the suffix is delimited by the last character for which @a
   * pred is @c true.
   *
   * @param pred A character predicate.
   *
   * @return A view of the suffix bounded by @a pred or empty if @a pred is not @c true for any
   * character.
   *
   * @note The delimiting character is not included in the returned view.
   */
  template <typename F> self_type suffix_if(F const &pred) const;

  /** Remove the trailing characters of @a this up to and including @a c.
   *
   * @param c Delimiter character.
   * @return @a this.
   *
   * @note The last occurrence of character @a c is removed along with all succeeding characters, or
   * the view is cleared if @a c is not found.
   */
  self_type &remove_suffix_at(char c);

  /** Remove the trailing characters of @a this up to and including the last character matching @a delimiters.
   *
   * @param delimiters Characters to match.
   * @return @a this.
   * @note The first occurrence of any character in @a delimiters is removed along with all preceding
   * characters, or the view is cleared if none are found.
   */
  self_type &remove_suffix_at(std::string_view const &delimiters);

  /** Remove the trailing characters up to and including the character selected by @a pred.
   *
   * @tparam F Predicate function type.
   * @param pred The predicate instance.
   * @return @a this.
   */
  template <typename F> self_type &remove_suffix_if(F const &pred);

  /** Remove and return a suffix of size @a n.
   *
   * @param n Size of the suffix.
   * @return The first @a n bytes of @a this if @a n is in @a this, otherwise an empty view.
   *
   * The prefix is removed and returned if the requested suffix is no larger than @a this,
   * otherwise @a this is not modified.
   *
   * @note The character at offset @a n is discarded if @a this is modified.
   *
   * @see @c take_suffix
   */
  self_type split_suffix(size_t n);

  /** Remove and return a suffix bounded by the last occurrence of @a c.
   *
   * @param c The character to match.
   * @return The suffix bounded by @a c if @a c is found, an empty view if not.
   *
   * The suffix is removed and returned if @a c is found, otherwise @a this is not modified.
   *
   * @note The character at offset @a n is discarded if @a this is modified.
   *
   * @see @c take_suffix_at
   */
  self_type split_suffix_at(char c);

  /** Remove and return a suffix bounded by the last occurrence of any of @a delimiters.
   *
   * @param delimiters The characters to match.
   * @return The suffix bounded by a delimiter if found, an empty view if none found.
   *
   * The suffix is removed and returned if delimiter is found, otherwise @a this is not modified.
   *
   * @note The delimiter character is discarded if @a this is modified.
   *
   * @see @c take_suffix_at
   */
  self_type split_suffix_at(std::string_view const &delimiters);

  /** Remove and return a suffix bounded by the last character that satisfies @a pred.
   *
   * @tparam F Predicate functor type.
   * @param pred A function taking @c char and returning @c bool.
   * @return The suffix bounded by the first character satisfying @a pred if found, otherwise @a this
   * is not modified.
   *
   * The prefix is removed and returned if a character satisfying @a pred if found, otherwise
   * @a this is not modified.
   *
   * @note The matching character is discarded if @a this is modified.
   *
   * @see @c take_suffix_if
   */
  template <typename F> self_type split_suffix_if(F const &pred);

  /** Remove and return a suffix of size @a n.
   *
   * @param n Size of the suffix.
   * @return The first @a n bytes of @a this if @a n is in @a this, otherwise all of @a this.
   *
   * The returned suffix is removed from @a this, along with the character at offset @a n if present.
   *
   * @see @c split_suffix
   */
  self_type take_suffix(size_t n);

  /** Remove and return a suffix bounded by the last occurrence of @a c.
   *
   * @param c The character to match.
   * @return The suffix bounded by @a c if @a c is found, all of @a this if not.
   *
   * The returned suffix is removed from @a this, along with the delimiter character if found.
   *
   * @see @c split_suffix_at
   */
  self_type take_suffix_at(char c);

  /** Remove and return a suffix bounded by the last occurrence of any of @a delimiters.
   *
   * @param delimiters The characters to match.
   * @return The suffix bounded by a delimiter if @a c is found, all of @a this if not.
   *
   * The returned suffix is removed from @a this, along with the delimiter character if found.
   *
   * @see @c split_suffix_at
   */
  self_type take_suffix_at(std::string_view const &delimiters);

  /** Remove and return a suffix bounded by the last character that satisfies @a pred.
   *
   * @tparam F Predicate functor type.
   * @param pred A function taking @c char and returning @c bool.
   * @return The suffix bounded by the first character satisfying @a pred if found, otherwise all of @a this.
   *
   * @note The matching character is discarded if found.
   *
   * @see @c split_suffix_if
   */
  template <typename F> self_type take_suffix_if(F const &pred);

  /** Remove and return a suffix of characters satisfying @a pred
   *
   * @tparam F Predicate functor type.
   * @param pred A function taking @c char and returning @c bool.
   * @return The suffix of characters that satisfy @a pred.
   *
   * The returned suffix is removed from @a this. That suffix may be empty if the last character
   * does not satisfy @a pred.
   */
  template <typename F> self_type clip_suffix_of(F const &pred);

  /** Get a view of part of this view.
   *
   * @param pos Offset of first byte in the new view.
   * @param count Number of bytes in the view.
   * @return The view starting at @a pos for @a count bytes.
   *
   * The returned view is clipped by @a this. @a count is reduced such that it covers only data
   * in @a this.
   *
   * @note This is provided primarily for co-variance, i.e. the returned view is a @c TextView
   * instead of a @c std::string_view.
   */
  constexpr self_type substr(size_type pos = 0, size_type count = npos) const noexcept;

  /** Check if the view begins with a specific @a prefix.
   *
   * @param prefix String to check against @a this.
   * @return @c true if <tt>this->prefix(prefix.size()) == prefix</tt>, @c false otherwise.
   * @internal C++20 preview.
   */
  bool starts_with(std::string_view const &prefix) const noexcept;

  /** Check if the view begins with a specific @a prefix.
   *
   * @param prefix String to check against @a this.
   * @return @c true if <tt>this->prefix(prefix.size()) == prefix</tt>, @c false otherwise.
   * @internal C++20 preview.
   */
  bool starts_with(char const *prefix) const;

  /** Check if the view begins with the character @c c.
   *
   * @param c Character to check.
   * @return @c true if the string is non-empty and the first character is @c c.
   * @internal C++20 preview.
   */
  bool starts_with(char c) const noexcept;

  /** Check if the view begins with a specific @a prefix, ignoring case.
   *
   * @param prefix String to check against @a this.
   * @return @c true if <tt>this->prefix(prefix.size()) == prefix</tt> without regard to case, @c false otherwise.
   * @internal C++20 preview.
   */
  bool starts_with_nocase(std::string_view const &prefix) const noexcept;

  /** Check if the view begins with a specific @a prefix.
   *
   * @param prefix String to check against @a this.
   * @return @c true if <tt>this->prefix(prefix.size()) == prefix</tt>, @c false otherwise.
   * @internal C++20 preview.
   */
  bool starts_with_nocase(char const *prefix) const;

  /** Check if the view begins with the character @c c, ignoring case.
   *
   * @param c Character to check.
   * @return @c true if the string is non-empty and the first character is @c c.
   * @internal C++20 preview.
   */
  bool starts_with_nocase(char c) const noexcept;

  /** Check if the view ends with a specific @a suffix.
   *
   * @param suffix String to check against @a this.
   * @return @c true if <tt>this->suffix(suffix.size()) == suffix</tt>, @c false otherwise.
   * @internal C++20 preview.
   */
  bool ends_with(std::string_view const &suffix) const noexcept;

  /** Check if the view ends with a specific @a suffix.
   *
   * @param suffix String to check against @a this.
   * @return @c true if <tt>this->suffix(suffix.size()) == suffix</tt>, @c false otherwise.
   * @internal C++20 preview.
   */
  bool ends_with(char const *suffix) const;

  /** Check the view ends with the character @c c.
   *
   * @param c Character to check.
   * @return @c true if the string is non-empty and the last character is @c c.
   * @internal C++20 preview.
   */
  bool ends_with(char c) const noexcept;

  /** Check if the view starts with a specific @a suffix, ignoring case.
   *
   * @param suffix String to check against @a this.
   * @return @c true if <tt>this->suffix(suffix.size()) == suffix</tt> without regard to case, @c false otherwise.
   * @internal C++20 preview.
   */
  bool ends_with_nocase(std::string_view const &suffix) const noexcept;

  /** Check if the view starts with a specific @a suffix, ignoring case.
   *
   * @param suffix String to check against @a this.
   * @return @c true if <tt>this->suffix(suffix.size()) == suffix</tt> without regard to case, @c false otherwise.
   * @internal C++20 preview.
   */
  bool ends_with_nocase(char const *suffix) const;

  /** Check the view ends with the character @c c, ignoring case.
   *
   * @param c Character to check.
   * @return @c true if the string is non-empty and the last character is @c c.
   * @internal C++20 preview.
   */
  bool ends_with_nocase(char c) const noexcept;

  // Functors for using this class in STL containers.
  /// Ordering functor, lexicographic comparison.
  struct LessThan {
    /// @return Case sensitive ordering.
    bool
    operator()(self_type const &lhs, self_type const &rhs) const noexcept {
      return -1 == strcmp(lhs, rhs);
    }
  };

  /// Ordering functor, case ignoring lexicographic comparison.
  struct LessThanNoCase {
    /// @return Case insensitive ordering.
    bool
    operator()(self_type const &lhs, self_type const &rhs) const noexcept {
      return -1 == strcasecmp(lhs, rhs);
    }
  };

  /** Get a pointer to past the last byte.
   *
   * @return The first byte past the end of the view.
   *
   * This is effectively @c std::string_view::end() except it explicit returns a pointer and not
   * (potentially) an iterator class, to match up with @c data().
   */
  constexpr char const *data_end() const noexcept;

  /// Specialized stream operator implementation.
  /// @note Use the standard stream operator unless there is a specific need for this, which is unlikely.
  /// @return The stream @a os.
  /// @internal Needed because @c std::ostream::write must be used and
  /// so alignment / fill have to be explicitly handled.
  template <typename Stream> Stream &stream_write(Stream &os, const TextView &b) const;

  /// @cond OVERLOAD
  // These methods are all overloads of other methods, defined in order to make the API more
  // convenient to use. Mostly these overload @c int for @c size_t so naked numbers work as expected.
  constexpr self_type prefix(int n) const noexcept;
  self_type take_suffix(int n);
  self_type split_prefix(int n);
  constexpr self_type suffix(int n) const noexcept;
  self_type split_suffix(int n);
  /// @endcond

protected:
  /// Initialize a bit mask to mark which characters are in this view.
  static void init_delimiter_set(std::string_view const &delimiters, std::bitset<256> &set);
};

/// Internal table of digit values for characters.
/// This is -1 for characters that are not valid digits.
extern const int8_t svtoi_convert[256];

/** Convert the text in @c TextView @a src to a signed numeric value.

    If @a parsed is non-null then the part of the string actually parsed is placed there.
    @a base sets the conversion base. If not set base 10 is used with two special cases:

    - If the number starts with a literal '0' then it is treated as base 8.
    - If the number starts with the literal characters '0x' or '0X' then it is treated as base 16.

    If @a base is explicitly set then any leading radix indicator is not supported.
*/
intmax_t svtoi(TextView src, TextView *parsed = nullptr, int base = 0);

/** Convert the text in @c TextView @a src to an unsigned numeric value.

    If @a parsed is non-null then the part of the string actually parsed is placed there.
    @a base sets the conversion base. If not set base 10 is used with two special cases:

    - If the number starts with a literal '0' then it is treated as base 8.
    - If the number starts with the literal characters '0x' or '0X' then it is treated as base 16.

    If @a base is explicitly set then any leading radix indicator is not supported.
*/
uintmax_t svtou(TextView src, TextView *parsed = nullptr, int base = 0);

/** Convert the text in @c src to an unsigned numeric value.
 *
 * @tparam N The radix (must be  1..36)
 * @param src The source text. Updated during parsing.
 * @return The converted numeric value.
 *
 * This is a specialized function useful only where conversion performance is critical. It is used
 * inside @c svtoi for the common cases of 8, 10, and 16, therefore normally this isn't much more
 * performant in those cases than just @c svtoi. Because of this only positive values are parsed.
 * If determining the radix from the text or signed value parsing is needed, used @c svtoi.
 *
 * @a src is updated in place to indicate what characters were parsed. Parsing stops on the first
 * invalid digit, so any leading non-digit characters (e.g. whitespace) must already be removed.
 * @a src is updated in place by removing parsed characters. Parsing stops on the first invalid
 * digit, so any leading non-digit characters (e.g. whitespace) must already be removed. Overflow
 * is detected and the first digit that would overflow is not parsed, and the maximum value is
 * returned.
 */
template <int N>
uintmax_t
svto_radix(swoc::TextView &src) {
  static_assert(0 < N && N <= 36, "Radix must be in the range 1..36");
  uintmax_t zret{0};
  int8_t v;
  while (src.size() && (0 <= (v = swoc::svtoi_convert[uint8_t(*src)])) && v < N) {
    auto n = zret * N + v;
    if (n < zret) { // overflow / wrap
      return std::numeric_limits<uintmax_t>::max();
    }
    zret = n;
    ++src;
  }
  return zret;
}

/// Convenience overload.
/// @see svto_radix(swoc::TextView &src)
template <int N>
uintmax_t
svto_radix(swoc::TextView &&src) {
  return svto_radix<N>(src);
}

/** Parse @a text as a floating point number.
 *
 * @param text The input text.
 * @param parsed Parsed text [out]
 * @return The floating point value, or 0.0 if invalid input.
 *
 * If @a parsed is not @a nullptr then the span of characters parsed is put there. This can be
 * used to check if the parse was scuccesful - on a failed parse, it will be empty.
 *
 * @note This should be within 1 epsilon of correct, although it doesn't guarantee picking
 * the closest epsilon. It's more than sufficient for use in configurations, but possibly
 * not for high precision work.
 */
double svtod(swoc::TextView text, swoc::TextView *parsed = nullptr);
// ----------------------------------------------------------
// Inline implementations.
// Note: Why, you may ask, do I use @c TextView::self_type for return type instead of the
// simpler plain @c TextView ? Because otherwise Doxygen can't match up the declaration and
// definition and the reference documentation is messed up. Sigh.

// === TextView Implementation ===
inline constexpr TextView::TextView(const char *ptr, size_t n) noexcept
  : super_type(ptr, n == npos ? (ptr ? ::strlen(ptr) : 0) : n) {}
inline constexpr TextView::TextView(char const *first, char const *last) noexcept : super_type(first, last - first) {}
inline constexpr TextView::TextView(std::nullptr_t) noexcept : super_type(nullptr, 0) {}
inline TextView::TextView(std::string const &str) noexcept : super_type(str) {}
inline constexpr TextView::TextView(super_type const &that) noexcept : super_type(that) {}
template <size_t N> constexpr TextView::TextView(const char (&s)[N]) noexcept : super_type(s, s[N - 1] ? N : N - 1) {}
template <typename C, typename> constexpr TextView::TextView(C const &c) : super_type(c.data(), c.size()) {}

inline void
TextView::init_delimiter_set(std::string_view const &delimiters, std::bitset<256> &set) {
  set.reset();
  for (char c : delimiters)
    set[static_cast<uint8_t>(c)] = true;
}

inline TextView &
TextView::clear() {
  new (this) self_type();
  return *this;
}

inline constexpr char
TextView::operator*() const {
  return this->empty() ? char(0) : *(this->data());
}

inline constexpr bool
TextView::operator!() const noexcept {
  return this->empty();
}

inline constexpr TextView::operator bool() const noexcept {
  return !this->empty();
}

inline TextView &
TextView::operator++() {
  this->remove_prefix(1);
  return *this;
}

inline TextView
TextView::operator++(int) {
  self_type zret{*this};
  this->remove_prefix(1);
  return zret;
}

inline TextView &
TextView::operator+=(size_t n) {
  this->remove_prefix(n);
  return *this;
}

template <size_t N>
inline TextView::self_type &
TextView::operator=(const char (&s)[N]) {
  return *this = self_type{s, s[N - 1] ? N : N - 1};
}

inline TextView &
TextView::operator=(super_type const &that) {
  this->super_type::operator=(that);
  return *this;
}

inline TextView &
TextView::operator=(char *&s) {
  this->super_type::operator=(s);
  return *this;
}

inline TextView &
TextView::operator=(char const *&s) {
  this->super_type::operator=(s);
  return *this;
}

inline TextView &
TextView::operator=(const std::string &s) {
  this->super_type::operator=(s);
  return *this;
}

inline TextView &
TextView::assign(char *&c_str) {
  return this->assign(c_str, strlen(c_str));
}

inline TextView &
TextView::assign(char const *&c_str) {
  return this->assign(c_str, strlen(c_str));
}

inline TextView &
TextView::assign(const std::string &s) {
  *this = super_type(s);
  return *this;
}

inline TextView &
TextView::assign(char const *ptr, size_t n) {
  *this = super_type(ptr, n);
  return *this;
}

inline TextView &
TextView::assign(char const *b, char const *e) {
  *this = super_type(b, e - b);
  return *this;
}

inline constexpr TextView
TextView::prefix(size_t n) const noexcept {
  return {this->data(), std::min(n, this->size())};
}

inline constexpr TextView
TextView::prefix(int n) const noexcept {
  return {this->data(), std::min<size_t>(n, this->size())};
}

inline TextView
TextView::prefix_at(char c) const {
  self_type zret; // default to empty return.
  if (auto n = this->find(c); n != npos) {
    zret.assign(this->data(), n);
  }
  return zret;
}

inline TextView
TextView::prefix_at(std::string_view const &delimiters) const {
  self_type zret; // default to empty return.
  if (auto n = this->find_first_of(delimiters); n != npos) {
    zret.assign(this->data(), n);
  }
  return zret;
}

template <typename F>
TextView::self_type
TextView::prefix_if(F const &pred) const {
  self_type zret; // default to empty return.
  if (auto n = this->find_if(pred); n != npos) {
    zret.assign(this->data(), n);
  }
  return zret;
}

inline auto
TextView::remove_prefix(size_t n) -> self_type & {
  this->super_type::remove_prefix(std::min(n, this->size()));
  return *this;
}

inline TextView &
TextView::remove_prefix_at(char c) {
  if (auto n = this->find(c); n != npos) {
    this->super_type::remove_prefix(n + 1);
  }
  return *this;
}

inline TextView &
TextView::remove_prefix_at(std::string_view const &delimiters) {
  if (auto n = this->find_first_of(delimiters); n != npos) {
    this->super_type::remove_prefix(n + 1);
  }
  return *this;
}

template <typename F>
TextView::self_type &
TextView::remove_prefix_if(F const &pred) {
  if (auto n = this->find_if(pred); n != npos) {
    this->super_type::remove_prefix(n + 1);
  }
  return *this;
}

inline TextView
TextView::split_prefix(size_t n) {
  self_type zret; // default to empty return.
  if (n < this->size()) {
    zret = this->prefix(n);
    this->remove_prefix(std::min(n + 1, this->size()));
  }
  return zret;
}

inline TextView
TextView::split_prefix(int n) {
  return this->split_prefix(size_t(n));
}

inline TextView
TextView::split_prefix_at(char c) {
  return this->split_prefix(this->find(c));
}

inline TextView
TextView::split_prefix_at(std::string_view const &delimiters) {
  return this->split_prefix(this->find_first_of(delimiters));
}

template <typename F>
TextView::self_type
TextView::split_prefix_if(F const &pred) {
  return this->split_prefix(this->find_if(pred));
}

inline TextView
TextView::take_prefix(size_t n) {
  n              = std::min(n, this->size());
  self_type zret = this->prefix(n);
  this->remove_prefix(std::min(n + 1, this->size()));
  return zret;
}

inline TextView
TextView::take_prefix_at(char c) {
  return this->take_prefix(this->find(c));
}

inline TextView
TextView::take_prefix_at(std::string_view const &delimiters) {
  return this->take_prefix(this->find_first_of(delimiters));
}

template <typename F>
TextView::self_type
TextView::take_prefix_if(F const &pred) {
  return this->take_prefix(this->find_if(pred));
}

inline constexpr TextView
TextView::suffix(size_t n) const noexcept {
  n = std::min(n, this->size());
  return {this->data_end() - n, n};
}

inline constexpr TextView
TextView::suffix(int n) const noexcept {
  return this->suffix(size_t(n));
}

inline TextView
TextView::suffix_at(char c) const {
  self_type zret;
  if (auto n = this->rfind(c); n != npos) {
    ++n;
    zret.assign(this->data() + n, this->size() - n);
  }
  return zret;
}

inline TextView
TextView::suffix_at(std::string_view const &delimiters) const {
  self_type zret;
  if (auto n = this->find_last_of(delimiters); n != npos) {
    ++n;
    zret.assign(this->data() + n, this->size() - n);
  }
  return zret;
}

template <typename F>
TextView::self_type
TextView::suffix_if(F const &pred) const {
  self_type zret;
  if (auto n = this->rfind_if(pred); n != npos) {
    ++n;
    zret.assign(this->data() + n, this->size() - n);
  }
  return zret;
}

inline auto
TextView::remove_suffix(size_t n) -> self_type & {
  this->super_type::remove_suffix(std::min(n, this->size()));
  return *this;
}

inline TextView &
TextView::remove_suffix_at(char c) {
  if (auto n = this->rfind(c); n != npos) {
    this->remove_suffix(this->size() - n);
  }
  return *this;
}

inline TextView &
TextView::remove_suffix_at(std::string_view const &delimiters) {
  if (auto n = this->find_last_of(delimiters); n != npos) {
    this->remove_suffix(this->size() - n);
  }
  return *this;
}

template <typename F>
TextView::self_type &
TextView::remove_suffix_if(F const &pred) {
  if (auto n = this->rfind_if(pred); n != npos) {
    this->remove_suffix(this->size() - n);
  }
  return *this;
}

inline TextView
TextView::split_suffix(size_t n) {
  self_type zret;
  n    = std::min(n, this->size());
  zret = this->suffix(n);
  this->remove_suffix(n + 1);
  return zret;
}

inline auto
TextView::split_suffix(int n) -> self_type {
  return this->split_suffix(size_t(n));
}

inline TextView
TextView::split_suffix_at(char c) {
  auto idx = this->rfind(c);
  return npos == idx ? self_type{} : this->split_suffix(this->size() - (idx + 1));
}

inline auto
TextView::split_suffix_at(std::string_view const &delimiters) -> self_type {
  auto idx = this->find_last_of(delimiters);
  return npos == idx ? self_type{} : this->split_suffix(this->size() - (idx + 1));
}

template <typename F>
TextView::self_type
TextView::split_suffix_if(F const &pred) {
  return this->split_suffix(this->rfind_if(pred));
}

inline TextView
TextView::take_suffix(size_t n) {
  self_type zret{*this};
  *this = zret.split_prefix(n);
  return zret;
}

inline TextView
TextView::take_suffix(int n) {
  return this->take_suffix(size_t(n));
}

inline TextView
TextView::take_suffix_at(char c) {
  return this->take_suffix(this->rfind(c));
}

inline TextView
TextView::take_suffix_at(std::string_view const &delimiters) {
  return this->take_suffix(this->find_last_of(delimiters));
}

template <typename F>
TextView::self_type
TextView::take_suffix_if(F const &pred) {
  return this->take_suffix_at(this->rfind_if(pred));
}

template <typename F>
inline size_t
TextView::find_if(F const &pred) const {
  for (const char *spot = this->data(), *limit = this->data_end(); spot < limit; ++spot)
    if (pred(*spot))
      return spot - this->data();
  return npos;
}

template <typename F>
inline size_t
TextView::rfind_if(F const &pred) const {
  for (const char *spot = this->data_end(), *limit = this->data(); spot > limit;)
    if (pred(*--spot))
      return spot - this->data();
  return npos;
}

inline TextView &
TextView::ltrim(char c) {
  this->remove_prefix(this->find_first_not_of(c));
  return *this;
}

inline TextView &
TextView::rtrim(char c) {
  auto n = this->find_last_not_of(c);
  this->remove_suffix(this->size() - (n == npos ? 0 : n + 1));
  return *this;
}

inline TextView &
TextView::trim(char c) {
  return this->ltrim(c).rtrim(c);
}

inline TextView &
TextView::ltrim(std::string_view const &delimiters) {
  std::bitset<256> valid;
  this->init_delimiter_set(delimiters, valid);
  const char *spot;
  const char *limit;

  for (spot = this->data(), limit = this->data_end(); spot < limit && valid[static_cast<uint8_t>(*spot)]; ++spot)
    ;
  this->remove_prefix(spot - this->data());

  return *this;
}

inline TextView &
TextView::ltrim(const char *delimiters) {
  return this->ltrim(std::string_view(delimiters));
}

inline TextView &
TextView::rtrim(std::string_view const &delimiters) {
  std::bitset<256> valid;
  this->init_delimiter_set(delimiters, valid);
  const char *spot  = this->data_end();
  const char *limit = this->data();

  while (limit < spot-- && valid[static_cast<uint8_t>(*spot)])
    ;

  this->remove_suffix(this->data_end() - (spot + 1));
  return *this;
}

inline TextView &
TextView::trim(std::string_view const &delimiters) {
  std::bitset<256> valid;
  this->init_delimiter_set(delimiters, valid);
  const char *spot;
  const char *limit;

  // Do this explicitly, so we don't have to initialize the character set twice.
  for (spot = this->data(), limit = this->data_end(); spot < limit && valid[static_cast<uint8_t>(*spot)]; ++spot)
    ;
  this->remove_prefix(spot - this->data());

  spot  = this->data_end();
  limit = this->data();
  while (limit < spot-- && valid[static_cast<uint8_t>(*spot)])
    ;
  this->remove_suffix(this->data_end() - (spot + 1));

  return *this;
}

inline TextView &
TextView::trim(const char *delimiters) {
  return this->trim(std::string_view(delimiters));
}

template <typename F>
TextView::self_type &
TextView::ltrim_if(F const &pred) {
  const char *spot;
  const char *limit;
  for (spot = this->data(), limit = this->data_end(); spot < limit && pred(*spot); ++spot)
    ;
  this->remove_prefix(spot - this->data());
  return *this;
}

template <typename F>
TextView::self_type &
TextView::rtrim_if(F const &pred) {
  const char *spot  = this->data_end();
  const char *limit = this->data();
  while (limit < spot-- && pred(*spot))
    ;
  this->remove_suffix(this->data_end() - (spot + 1));
  return *this;
}

template <typename F>
TextView::self_type &
TextView::trim_if(F const &pred) {
  return this->ltrim_if(pred).rtrim_if(pred);
}

constexpr inline char const *
TextView::data_end() const noexcept {
  return this->data() + this->size();
}

inline constexpr TextView
TextView::substr(size_type pos, size_type count) const noexcept {
  if (pos >= this->size()) {
    return {};
  }
  count = std::min(this->size() - pos, count);
  return {this->data() + pos, count};
}

inline bool
TextView::starts_with(std::string_view const &prefix) const noexcept {
  return this->size() >= prefix.size() && 0 == ::memcmp(this->data(), prefix.data(), prefix.size());
}

inline bool
TextView::starts_with(char const *prefix) const {
  return this->starts_with(super_type(prefix));
}
inline bool
TextView::starts_with_nocase(char const *prefix) const {
  return this->starts_with_nocase(super_type{prefix});
}

inline bool
TextView::starts_with(char c) const noexcept {
  return !this->empty() && c == this->front();
}
inline bool
TextView::starts_with_nocase(char c) const noexcept {
  return !this->empty() && tolower(c) == tolower(this->front());
}

inline bool
TextView::starts_with_nocase(std::string_view const &prefix) const noexcept {
  return this->size() >= prefix.size() && 0 == ::strncasecmp(this->data(), prefix.data(), prefix.size());
}

inline bool
TextView::ends_with(std::string_view const &suffix) const noexcept {
  return this->size() >= suffix.size() && 0 == ::memcmp(this->data_end() - suffix.size(), suffix.data(), suffix.size());
}

inline bool
TextView::ends_with_nocase(std::string_view const &suffix) const noexcept {
  return this->size() >= suffix.size() && 0 == ::strncasecmp(this->data_end() - suffix.size(), suffix.data(), suffix.size());
}

inline bool
TextView::ends_with(char const *suffix) const {
  return this->ends_with(super_type(suffix));
}

inline bool
TextView::ends_with_nocase(char const *suffix) const {
  return this->ends_with_nocase(super_type(suffix));
}

inline bool
TextView::ends_with(char c) const noexcept {
  return !this->empty() && c == this->back();
}
inline bool
TextView::ends_with_nocase(char c) const noexcept {
  return !this->empty() && tolower(c) == tolower(this->back());
}

template <typename Stream>
Stream &
TextView::stream_write(Stream &os, const TextView &b) const {
  // Local function, avoids extra template work.
  static const auto stream_fill = [](Stream &os, size_t n) -> Stream & {
    static constexpr size_t pad_size = 8;
    typename Stream::char_type padding[pad_size];

    std::fill_n(padding, pad_size, os.fill());
    for (; n >= pad_size && os.good(); n -= pad_size)
      os.write(padding, pad_size);
    if (n > 0 && os.good())
      os.write(padding, n);
    return os;
  };

  const std::size_t w = os.width();
  if (w <= b.size()) {
    os.write(b.data(), b.size());
  } else {
    const std::size_t pad_size = w - b.size();
    const bool align_left      = (os.flags() & Stream::adjustfield) == Stream::left;
    if (!align_left && os.good())
      stream_fill(os, pad_size);
    if (os.good())
      os.write(b.data(), b.size());
    if (align_left && os.good())
      stream_fill(os, pad_size);
  }
  return os;
}

template <typename F>
TextView::self_type
TextView::clip_prefix_of(F const &pred) {
  size_t idx = 0;
  for (auto spot = this->data(), limit = spot + this->size(); spot < limit && pred(*spot); ++spot, ++idx)
    ; // empty
  TextView token = this->prefix(idx);
  this->remove_prefix(idx);
  return token;
}

template <typename F>
TextView::self_type
TextView::clip_suffix_of(F const &pred) {
  size_t idx = this->size() - 1;
  for (auto spot = this->data() + idx, limit = this->data(); spot >= limit && pred(*spot); --spot, --idx)
    ; // empty
  TextView token = this->suffix(idx);
  this->remove_suffix(idx);
  return token;
}

// Provide an instantiation for @c std::ostream as it's likely this is the only one ever used.
extern template std::ostream &TextView::stream_write(std::ostream &, const TextView &) const;

/** A transform view.
 *
 * @tparam X Transform functor type.
 * @tparam V Source view type.
 *
 * A transform view acts like a view on the original source view @a V with each element transformed by
 * @a X.
 *
 * This is used most commonly with @c std::string_view. For example, if the goal is to handle a
 * piece of text as if it were lower case without changing the actual text, the following would
 * make that possible.
 * @code
 * std:::string_view source; // original text.
 * TransformView<int (*)(int) noexcept, std::string_view> xv(&tolower, source);
 * @endcode
 *
 * To avoid having to figure out the exact signature of the transform, the convenience function
 * @c transform_view_of is provide.
 * @code
 * std::string_view source; // original text.
 * auto xv = transform_view_of(&tolower, source);
 * @endcode
 *
 * This class supports iterators but those should be avoided as use of them makes extra copies of the instance which
 * may be expensive if the functor is expensive. In cases where the functor is a function pointer or a lambda this isn't
 * an issue.
 */
template <typename X, typename V> class TransformView {
  using self_type = TransformView; ///< Self reference type.
  using source_iterator = decltype(V{}.begin());

public:
  using transform_type    = X; ///< Export transform functor type.
  using source_view_type  = V; ///< Export source view type.
  using source_value_type = std::remove_reference_t<decltype(*source_iterator{})>;
  /// Result type of calling the transform on an element of the source view.
  using value_type = std::invoke_result_t<transform_type, source_value_type>;
  /// This class serves as its own iterator.
  using iterator = self_type;

  /** Construct a transform view using transform @a xf on source view @a v.
   *
   * @param xf Transform instance.
   * @param v Source view.
   */
  TransformView(transform_type &&xf, source_view_type const &v);

  /** Construct a transform view using transform @a xf on source view @a v.
   *
   * @param xf Transform instance.
   * @param v Source view.
   */
  TransformView(transform_type const &xf, source_view_type const &v);

  /// Copy constructor.
  TransformView(self_type const &that) = default;
  /// Move constructor.
  TransformView(self_type &&that) = default;

  /// Copy assignment.
  self_type &operator=(self_type const &that) = default;
  /// Move assignment.
  self_type &operator=(self_type &&that) = default;

  /// Equality.
  bool operator==(self_type const &that) const;
  /// Inequality.
  bool operator!=(self_type const &that) const;

  /// Get the current element.
  value_type operator*() const;
  /// Move to next element.
  self_type &operator++();
  /// Move to next element.
  self_type operator++(int);

  /// Check if view is empty.
  bool empty() const;
  /// Check if bool is not empty.
  explicit operator bool() const;

  /// Iterator to first transformed character.
  iterator begin() const { return *this; }
  /// Iterator past last transformed character.
  iterator end() const { return self_type{_xf, _limit}; }

protected:
  transform_type _xf;     ///< Per character transform functor.
  source_iterator _spot;  ///< Current location in the source view.
  source_iterator _limit; ///< End of source view.

  /// Special constructor for making an empty instance to serve as the @c end iterator.
  TransformView(transform_type && xf, source_iterator && limit) : _xf(xf), _spot(limit), _limit(limit) {}
};

template <typename X, typename V>
TransformView<X, V>::TransformView(transform_type &&xf, source_view_type const &v) : _xf(xf), _spot(v.begin()), _limit(v.end()) {}

template <typename X, typename V>
TransformView<X, V>::TransformView(transform_type const &xf, source_view_type const &v)
  : _xf(xf), _spot(v.begin()), _limit(v.end()) {}

template <typename X, typename V>
auto
TransformView<X, V>::operator*() const -> value_type {
  return _xf(*_spot);
}

template <typename X, typename V>
auto
TransformView<X, V>::operator++() -> self_type & {
  ++_spot;
  return *this;
}

template <typename X, typename V>
auto
TransformView<X, V>::operator++(int) -> self_type {
  self_type zret{*this};
  ++_spot;
  return zret;
}

template <typename X, typename V>
bool
TransformView<X, V>::empty() const {
  return _spot == _limit;
}

template <typename X, typename V> TransformView<X, V>::operator bool() const {
  return _spot != _limit;
}

template <typename X, typename V>
bool
TransformView<X, V>::operator==(self_type const &that) const {
  return _spot == that._spot && _limit == that._limit;
}

template <typename X, typename V>
bool
TransformView<X, V>::operator!=(self_type const &that) const {
  return _spot != that._spot || _limit != that._limit;
}

/** Create a transformed view of a source.
 *
 * @tparam X The transform functor type.
 * @tparam V The source type.
 * @param xf The transform.
 * @param src The view source.
 * @return A @c TransformView that applies @a xf to @a src.
 */
template <typename X, typename V>
TransformView<X, V>
transform_view_of(X const &xf, V const &src) {
  return TransformView<X, V>(xf, src);
}

/** Identity transform view.
 *
 * @tparam V The source type.
 *
 * This is a transform that returns the input unmodified. This is convenient when a transform is
 * required in general but not in in all cases.
 */
template <typename V> class TransformView<void, V> {
  using self_type = TransformView; ///< Self reference type.
  /// Iterator over source, for internal use.
  using source_iterator = decltype(V{}.begin());

public:
  using source_view_type  = V; ///< Export source view type.
  using source_value_type = std::remove_reference_t<decltype(*source_iterator{})>;
  /// Result type of calling the transform on an element of the source view.
  using value_type = source_value_type;
  /// This class serves as its own iterator.
  using iterator = self_type;

  /** Construct identity transform view from @a v.
   *
   * @param v Source view.
   */
  TransformView(source_view_type const &v) : _spot(v.begin()), _limit(v.end()) {}

  /// Copy constructor.
  TransformView(self_type const &that) = default;
  /// Move constructor.
  TransformView(self_type &&that) = default;

  /// Copy assignment.
  self_type &operator=(self_type const &that) = default;
  /// Move assignment.
  self_type &operator=(self_type &&that) = default;

  /// Equality.
  bool operator==(self_type const &that) const;
  /// Inequality.
  bool operator!=(self_type const &that) const;

  /// Get the current element.
  value_type operator*() const;

  /// Move to next element.
  self_type & operator++();

  /// Move to next element.
  self_type operator++(int);

  /// Check if view is empty.
  bool empty() const;

  /// Check if bool is not empty.
  explicit operator bool() const;

  /// Iterator to first transformed character.
  iterator begin() const;
  /// Iterator past last transformed character.
  iterator end() const;

protected:
  source_iterator _spot;  ///< Current location.
  source_iterator _limit; ///< End marker.

  /// Special constructor for making an empty instance to serve as the @c end iterator.
  explicit TransformView(source_iterator && limit) : _spot(limit), _limit(limit) {}
};

template <typename V>
auto
TransformView<void, V>::operator*() const -> value_type {
  return *_spot;
}

template <typename V>
auto
TransformView<void, V>::operator++() -> self_type & {
  ++_spot;
  return *this;
}

template <typename V>
auto
TransformView<void, V>::operator++(int) -> self_type {
  auto zret{*this};
  ++*this;
  return zret;
}

template <typename V>
bool
TransformView<void, V>::operator==(const self_type &that) const {
  return _spot == that._spot && _limit == that._limit;
}

template <typename V>
bool
TransformView<void, V>::operator!=(const self_type &that) const {
  return _spot != that._spot || _limit != that._limit;
}

template <typename V>
bool
TransformView<void, V>::empty() const {
  return _spot == _limit;
}

template <typename V>
TransformView<void, V>::operator bool() const {
  return _spot != _limit;
}

template <typename V>
auto TransformView<void, V>::begin() const -> self_type { return *this; }

template <typename V>
auto TransformView<void, V>::end() const -> self_type { return self_type{_limit}; }

/// @cond INTERNAL_DETAIL
// Capture @c void transforms and make them identity transforms.
template <typename V>
TransformView<void, V>
transform_view_of(V const &v) {
  return TransformView<void, V>(v);
}

/// @endcond

/** User literals for TextView.
 *
 * - _tv : TextView
 * - _sv : std::string_view
 */
namespace literals {
/** Literal constructor for @c std::string_view.
 *
 * @param s The source string.
 * @param n Size of the source string.
 * @return A @c string_view
 *
 * @internal This is provided because the STL one does not support @c constexpr which seems
 * rather bizarre to me, but there it is. Update: this depends on the version of the compiler,
 * so hopefully someday this can be removed.
 */
constexpr std::string_view operator"" _sv(const char *s, size_t n) {
  return {s, n};
}

/** Literal constructor for @c swoc::TextView.
 *
 * @param s The source string.
 * @param n Size of the source string.
 * @return A @c string_view
 *
 * @internal This is provided because the STL one does not support @c constexpr which seems
 * rather bizarre to me, but there it is. Update: this depends on the version of the compiler,
 * so hopefully someday this can be removed.
 */
constexpr swoc::TextView operator"" _tv(const char *s, size_t n) {
  return {s, n};
}
} // namespace literals

}} // namespace swoc::SWOC_VERSION_NS

namespace std {
/// Write the contents of @a view to the stream @a os.
ostream &operator<<(ostream &os, const swoc::TextView &view);

/// @cond INTERNAL_DETAIL
/* For interaction with specific STL interfaces, primarily std::filesystem. Along with the
 * dereference operator, this enables a @c TextView to act as a character iterator to a C string
 * even if the internal view is not nul terminated.
 * @note Putting these directly in the class doesn't seem to work.
 */
template <> struct iterator_traits<swoc::TextView> {
  using value_type        = char;
  using pointer_type      = const char *;
  using reference_type    = const char &;
  using difference_type   = ssize_t;
  using iterator_category = forward_iterator_tag;
};

template <typename X, typename V> struct iterator_traits<swoc::TransformView<X, V>> {
  using value_type        = typename swoc::TransformView<X, V>::value_type;
  using pointer_type      = const value_type *;
  using reference_type    = const value_type &;
  using difference_type   = ssize_t;
  using iterator_category = forward_iterator_tag;
};
/// @endcond

} // namespace std


text:
package org.greenrobot.greendao.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Specifies that the target should be kept during next run of greenDAO generation.
 *

 * Using this annotation on an Entity class itself silently disables any class modification.
 * The user is responsible to write and support any code which is required for greenDAO.
 *

 *

 * Don't use this annotation on a class member if you are not completely sure what you are doing, because in
 * case of model changes greenDAO will not be able to make corresponding changes into the code of the target.
 *

 *
 * @see Generated
 */
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.TYPE})
public @interface Keep {
}

redpajama_set_name: RedPajamaGithub


text:
class Condition < ApplicationRecord
  include UuidMixin
  before_validation :default_name_to_guid, :on => :create

  validates :name, :description, :expression, :towhat, :presence => true
  validates :name, :description, :uniqueness_when_changed => true

  acts_as_miq_taggable
  acts_as_miq_set_member

  belongs_to :miq_policy
  has_and_belongs_to_many :miq_policies

  serialize :expression
  serialize :applies_to_exp

  attr_accessor :reserved

  TOWHAT_APPLIES_TO_CLASSES = {
    "ContainerGroup"      => ui_lookup(:model => "ContainerGroup"),
    "ContainerImage"      => ui_lookup(:model => "ContainerImage"),
    "ContainerNode"       => ui_lookup(:model => "ContainerNode"),
    "ContainerProject"    => ui_lookup(:model => "ContainerProject"),
    "ContainerReplicator" => ui_lookup(:model => "ContainerReplicator"),
    "ExtManagementSystem" => ui_lookup(:model => "ExtManagementSystem"),
    "Host"                => ui_lookup(:model => "Host"),
    "PhysicalServer"      => ui_lookup(:model => "PhysicalServer"),
    "Vm"                  => ui_lookup(:model => "Vm")
  }.freeze

  def applies_to?(rec, inputs = {})
    rec_model = rec.class.base_model.name
    rec_model = "Vm" if rec_model.downcase.match("template")

    return false if towhat && rec_model != towhat
    return true  if applies_to_exp.nil?

    Condition.evaluate(self, rec, inputs, :applies_to_exp)
  end

  def self.conditions
    pluck(:expression)
  end

  def self.evaluate(cond, rec, _inputs = {}, attr = :expression)
    expression = cond.send(attr)
    name = cond.try(:description) || cond.try(:name)
    mode = expression.kind_of?(MiqExpression) ? "object" : expression["mode"]

    case mode
    when "tag"
      unless %w(any all none).include?(expression["include"])
        raise _("condition '%{name}', include value \"%{value}\", is invalid. Should be one of \"any, all or none\"") %
                {:name => name, :value => expression["include"]}
      end

      result = expression["include"] != "any"
      expression["tag"].split.each do |tag|
        if rec.is_tagged_with?(tag, :ns => expression["ns"])
          result = true if expression["include"] == "any"
          result = false if expression["include"] == "none"
        else
          result = false if expression["include"] == "all"
        end
      end
    when "tag_expr", "tag_expr_v2", "object"
      expr = case mode
             when "tag_expr"
               expression["expr"]
             when "tag_expr_v2"
               MiqExpression.new(expression["expr"]).to_ruby
             when "object"
               expression.to_ruby
             end

      MiqPolicy.logger.debug("MIQ(condition-eval): Name: #{name}, Expression before substitution: [#{expr.gsub(/\n/, " ")}]")

      subst(expr, rec)

      MiqPolicy.logger.debug("MIQ(condition-eval): Name: #{name}, Expression after substitution: [#{expr.gsub(/\n/, " ")}]")
      result = do_eval(expr)
      MiqPolicy.logger.info("MIQ(condition-eval): Name: #{name}, Expression evaluation result: [#{result}]")
    end
    result
  end

  # similar to MiqExpression#evaluate
  # @return [Boolean] true if the expression matches the record
  def self.subst_matches?(expr, rec)
    do_eval(subst(expr, rec))
  end

  def self.do_eval(expr)
    !!eval(expr)
  end

  def self.subst(expr, rec)
    findexp = /<find>(.+?)<\/find>/im
    if expr =~ findexp
      expr = expr.gsub!(findexp) { |_s| _subst_find(rec, $1.strip) }
      MiqPolicy.logger.debug("MIQ(condition-_subst_find): Find Expression after substitution: [#{expr}]")
    end

    # <mode>/virtual/operating_system/product_name</mode>
    # <mode WE/JWSref=host>/managed/environment/prod</mode>
    expr.gsub!(/<(value|exist|count|registry)([^>]*)>([^<]+)<\/(value|exist|count|registry)>/im) { |_s| _subst(rec, $2.strip, $3.strip, $1.strip) }

    # <mode /virtual/operating_system/product_name />
    expr.gsub!(/<(value|exist|count|registry)([^>]+)\/>/im) { |_s| _subst(rec, nil, $2.strip, $1.strip) }

    expr
  end

  def self._subst(rec, opts, tag, mode)
    ohash, ref, _object = options2hash(opts, rec)

    case mode.downcase
    when "exist"
      ref.nil? ? value = false : value = ref.is_tagged_with?(tag, :ns => "*")
    when "value"
      if ref.kind_of?(Hash)
        value = ref.fetch(tag, "")
      else
        value = ref.nil? ? "" : Tag.list(ref, :ns => tag)
      end
      value = MiqExpression.quote(value, ohash[:type] || "string")
    when "count"
      ref.nil? ? value = 0 : value = ref.tag_list(:ns => tag).length
    when "registry"
      ref.nil? ? value = "" : value = registry_data(ref, tag, ohash)
      value = MiqExpression.quote(value, ohash[:type] || "string")
    end
    value
  end

  def self.collect_children(ref, methods)
    method = methods.shift

    list = ref.send(method)
    return [] if list.nil?

    result = methods.empty? ? Array(list) : []
    Array(list).each do |obj|
      result.concat(collect_children(obj, methods)) unless methods.empty?
    end
    result
  end

  def self._subst_find(rec, expr)
    MiqPolicy.logger.debug("MIQ(condition-_subst_find): Find Expression before substitution: [#{expr}]")
    searchexp = /<search>(.+)<\/search>/im
    expr =~ searchexp
    search = $1
    MiqPolicy.logger.debug("MIQ(condition-_subst_find): Search Expression before substitution: [#{search}]")

    listexp = /<value([^>]*)>(.+)<\/value>/im
    search =~ listexp
    opts, _ref, _object = options2hash($1, rec)
    methods = $2.split("/")
    methods.shift
    methods.shift
    attr = methods.pop
    l = collect_children(rec, methods)

    return false if l.empty?

    list = l.collect do |obj|
      value = MiqExpression.quote(obj.send(attr), opts[:type])
      value = value.gsub(/\\/, '\&\&') if value.kind_of?(String)
      e = search.gsub(/<value[^>]*>.+<\/value>/im, value.to_s)
      obj if do_eval(e)
    end.compact

    MiqPolicy.logger.debug("MIQ(condition-_subst_find): Search Expression returned: [#{list.length}] records")

    checkexp = /<check([^>]*)>(.+)<\/check>/im

    expr =~ checkexp
    checkopts = $1.strip
    check = $2
    checkmode = checkopts.split("=").last.strip.downcase

    MiqPolicy.logger.debug("MIQ(condition-_subst_find): Check Expression before substitution: [#{check}], options: [#{checkopts}]")

    if checkmode == "count"
      e = check.gsub(/<count>/i, list.length.to_s)
      left, operator, right = e.split
      raise _("Illegal operator, '%{operator}'") % {:operator => operator} unless %w(== != < > <= >=).include?(operator)

      MiqPolicy.logger.debug("MIQ(condition-_subst_find): Check Expression after substitution: [#{e}]")
      result = !!left.to_f.send(operator, right.to_f)
      MiqPolicy.logger.debug("MIQ(condition-_subst_find): Check Expression result: [#{result}]")
      return result
    end

    return false if list.empty?

    check =~ /<value([^>]*)>(.+)<\/value>/im
    raw_opts = $1
    tag = $2
    checkattr = tag.split("/").last.strip

    result = true
    list.each do |obj|
      opts, _ref, _object = options2hash(raw_opts, obj)
      value = MiqExpression.quote(obj.send(checkattr), opts[:type])
      value = value.gsub(/\\/, '\&\&') if value.kind_of?(String)
      e = check.gsub(/<value[^>]*>.+<\/value>/im, value.to_s)
      MiqPolicy.logger.debug("MIQ(condition-_subst_find): Check Expression after substitution: [#{e}]")

      result = do_eval(e)

      return true if result && checkmode == "any"
      return false if !result && checkmode == "all"
    end
    MiqPolicy.logger.debug("MIQ(condition-_subst_find): Check Expression result: [#{result}]")
    result
  end

  def self.options2hash(opts, rec)
    ref = rec
    ohash = {}
    unless opts.blank?
      val = nil
      opts.split(",").each do |o|
        attr, val = o.split("=")
        ohash[attr.strip.downcase.to_sym] = val.strip.downcase
      end
      if ohash[:ref] != rec.class.to_s.downcase && !exclude_from_object_ref_substitution(ohash[:ref], rec)
        ref = rec.send(val) if val && rec.respond_to?(val)
      end

      if ohash[:object]
        object = val.to_sym
        ref = inputs[object]
      end
    end
    return ohash, ref, object
  end

  def self.exclude_from_object_ref_substitution(reference, rec)
    case reference
    when "service"
      rec.kind_of?(Service)
    end
  end

  def self.registry_data(ref, name, ohash)
    # <registry>HKLM\Software\Microsoft\Windows\CurrentVersion\explorer\Shell Folders\Common AppData</registry> == 'C:\Documents and Settings\All Users\Application Data'
    # <registry>HKLM\Software\Microsoft\Windows\CurrentVersion\explorer\Shell Folders : Common AppData</registry> == 'C:\Documents and Settings\All Users\Application Data'
    return nil unless ref.respond_to?("registry_items")

    registry_items = ref.registry_items
    if ohash[:key_exists]
      registry_items.where("name LIKE ? ESCAPE ''", name + "%").exists?
    elsif ohash[:value_exists]
      registry_items.where(:name => name).exists?
    else
      registry_items.find_by(:name => name)&.data
    end
  end

  def export_to_array
    h = attributes
    ["id", "created_on", "updated_on"].each { |k| h.delete(k) }
    [self.class.to_s => h]
  end

  def self.import_from_hash(condition, options = {})
    # To delete condition modifier in policy from versions 5.8 and older
    condition["expression"].exp = {"not" => condition["expression"].exp} if condition["modifier"] == 'deny'
    condition.delete("modifier")

    status = {:class => name, :description => condition["description"]}
    c = Condition.find_by(:guid => condition["guid"]) || Condition.find_by(:name => condition["name"]) ||
        Condition.find_by(:description => condition["description"])
    msg_pfx = "Importing Condition: guid=[#{condition["guid"]}] description=[#{condition["description"]}]"

    if c.nil?
      c = Condition.new(condition)
      status[:status] = :add
    else
      status[:old_description] = c.description
      c.attributes = condition
      status[:status] = :update
    end

    unless c.valid?
      status[:status]   = :conflict
      status[:messages] = c.errors.full_messages
    end

    msg = "#{msg_pfx}, Status: #{status[:status]}"
    msg += ", Messages: #{status[:messages].join(",")}" if status[:messages]
    if options[:preview] == true
      MiqPolicy.logger.info("[PREVIEW] #{msg}")
    else
      MiqPolicy.logger.info(msg)
      c.save!
    end

    return c, status
  end

end # class Condition


text:
mkdir -p /etc/google-fluentd/files
if [ -z "$FILES_TO_COLLECT" ]; then
  exit 0
fi

for filepath in $FILES_TO_COLLECT
do
  filename=$(basename $filepath)
  cat > "/etc/google-fluentd/files/${filename}" << EndOfMessage
<source>
  type tail
  format none
  time_key time
  path ${filepath}
  pos_file /etc/google-fluentd/fluentd-gcp-${filename}.pos
  time_format %Y-%m-%dT%H:%M:%S
  tag file.${filename}
  read_from_head true
</source>
EndOfMessage
done


text:
import PaddedView from '@ui/PaddedView';
import styled from '@ui/styled';

const Content = styled(({ theme }) => ({
  paddingVertical: theme.sizing.baseUnit * 0.75,
}), 'Card.Content')(PaddedView);

export default Content;


text:
namespace BankTest
{
    using System;

    public class StartPoint
    {
        static void Main()
        {
            Account[] bankSystem =
            {
                new DepositAccount("Pesho", 333.33m, 0.1m, 20),
                new LoanAccount("Gosho", 2000.33m, 0.1m, AccountType.Company, 14),
                new MortageAccount("Stamat", 4003m, 0.1m, AccountType.Company, 3),
                new DepositAccount("Mariq", 3333.33m, 0.1m, 2),
                new LoanAccount("Lili", 6666.33m, 0.1m, AccountType.Individual, 4),
                new MortageAccount("Irena", 444.33m, 0.1m, AccountType.Individual, 12),
                new DepositAccount("Poli", 1000000.33m, 0.2m, 23)
            };

            foreach (var item in bankSystem)
            {
                Console.WriteLine(item.CalculateInterestRate());
            }
        }
    }
}


text:
<?xml version="1.0" encoding="UTF-8"?>
<XMLRequest>
<ClientType>iPhone</ClientType>
<ClientVersion>4.1</ClientVersion>
<ServiceVersion>2.1</ServiceVersion>
<Locale>{locale}</Locale>
<ServiceName>FinancialService</ServiceName>
<Operation>Statement</Operation>
<ClientSecurityToken>{security_token}</ClientSecurityToken>
<StatementRequestData>
<BillingPeriod>99</BillingPeriod>
<CardIndex>{card_index}</CardIndex>
<StartRecord>0</StartRecord>
<RecordsPerPage>9999</RecordsPerPage>
<PaymentsAndCredits>TRUE</PaymentsAndCredits>
</StatementRequestData>
</XMLRequest>


text:
@protocol ContentSuggestionsCollectionControlling;
@protocol ContentSuggestionsHeaderControlling;

// Synchronizer for all the interactions between the HeaderController and the
// CollectionView. It handles the interactions both ways.
@interface ContentSuggestionsHeaderSynchronizer
    : NSObject<ContentSuggestionsCollectionSynchronizing,
               ContentSuggestionsHeaderSynchronizing>

// Initializes the CommandHandler with the `suggestionsViewController` and the
// `headerController`.
- (nullable instancetype)
initWithCollectionController:
    (nullable id<ContentSuggestionsCollectionControlling>)collectionController
            headerController:(nullable id<ContentSuggestionsHeaderControlling>)
                                 headerController NS_DESIGNATED_INITIALIZER;

- (nullable instancetype)init NS_UNAVAILABLE;

// When the omnibox is focused, this value represents the shift distance of the
// collection needed to pin the omnibox to the top. It is 0 if the omnibox has
// not been moved when focused (i.e. the collection was already scrolled to
// top).
@property(nonatomic, assign) CGFloat collectionShiftingOffset;

@end

#endif  // IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_HEADER_SYNCHRONIZER_H_


text:
<?php

namespace Matthias\SimpleBus\SymfonyBundle\DependencyInjection;

use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;

class DoctrineOrmEventBusBridgeExtension extends Extension
{
    public function getAlias()
    {
        return 'doctrine_orm_event_bus_bridge';
    }

    public function load(array $config, ContainerBuilder $container)
    {
        $loader = new YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));

        $loader->load('doctrine_orm.yml');
    }
}


text:
from __future__ import unicode_literals
import frappe
from frappe.model.document import Document

class DataMigrationMapping(Document):
	def get_filters(self):
		if self.condition:
			return frappe.safe_eval(self.condition, dict(frappe=frappe))

	def get_fields(self):
		fields = []
		for f in self.fields:
			if not (f.local_fieldname[0] in ('"', "'") or f.local_fieldname.startswith('eval:')):
				fields.append(f.local_fieldname)

		if frappe.db.has_column(self.local_doctype, self.migration_id_field):
			fields.append(self.migration_id_field)

		if 'name' not in fields:
			fields.append('name')

		return fields

	def get_mapped_record(self, doc):
		mapped = frappe._dict()

		key_fieldname = 'remote_fieldname'
		value_fieldname = 'local_fieldname'

		if self.mapping_type == 'Pull':
			key_fieldname, value_fieldname = value_fieldname, key_fieldname

		for field_map in self.fields:
			if not field_map.is_child_table:
				value = get_value_from_fieldname(field_map, value_fieldname, doc)
				mapped[field_map.get(key_fieldname)] = value
			else:
				mapping_name = field_map.child_table_mapping
				value = get_mapped_child_records(mapping_name, doc.get(field_map.get(value_fieldname)))
				mapped[field_map.get(key_fieldname)] = value
		return mapped

def get_mapped_child_records(mapping_name, child_docs):
	mapped_child_docs = []
	mapping = frappe.get_doc('Data Migration Mapping', mapping_name)
	for child_doc in child_docs:
		mapped_child_docs.append(mapping.get_mapped_record(child_doc))

	return mapped_child_docs

def get_value_from_fieldname(field_map, fieldname_field, doc):
	field_name = field_map.get(fieldname_field)

	if field_name.startswith('eval:'):
		value = frappe.safe_eval(field_name[5:], dict(frappe=frappe))
	elif field_name[0] in ('"', "'"):
		value = field_name[1:-1]
	else:
		value = doc.get(field_name)
	return value


text:
package org.androidtransfuse.gen;

import com.sun.codemodel.JBlock;
import com.sun.codemodel.JClassAlreadyExistsException;
import com.sun.codemodel.JDefinedClass;
import com.sun.codemodel.JExpression;
import org.androidtransfuse.analysis.astAnalyzer.VirtualProxyAspect;
import org.androidtransfuse.gen.proxy.VirtualProxyGenerator;
import org.androidtransfuse.model.InjectionNode;
import org.androidtransfuse.model.TypedExpression;

import javax.inject.Inject;
import java.util.HashMap;
import java.util.Map;

/**
 * @author John Ericksen
 */
public class InjectionFragmentGenerator {

    private final InjectionBuilderContextFactory injectionBuilderContextFactory;
    private final InjectionExpressionBuilder injectionExpressionBuilder;
    private final VirtualProxyGenerator virtualProxyGenerator;

    @Inject
    public InjectionFragmentGenerator(InjectionBuilderContextFactory injectionBuilderContextFactory,
                                      InjectionExpressionBuilder injectionExpressionBuilder,
                                      VirtualProxyGenerator virtualProxyGenerator) {
        this.injectionBuilderContextFactory = injectionBuilderContextFactory;
        this.injectionExpressionBuilder = injectionExpressionBuilder;
        this.virtualProxyGenerator = virtualProxyGenerator;
    }

    public Map<InjectionNode, TypedExpression> buildFragment(JBlock block, InstantiationStrategy instantiateOnceStrategy, JDefinedClass definedClass, InjectionNode injectionNode, JExpression scopeVar) throws JClassAlreadyExistsException {
        return buildFragment(block, instantiateOnceStrategy, definedClass, injectionNode, scopeVar, new HashMap<InjectionNode, TypedExpression>());
    }

    public Map<InjectionNode, TypedExpression> buildFragment(JBlock block, InstantiationStrategy instantiateOnceStrategy, JDefinedClass definedClass, InjectionNode injectionNode, JExpression scopeVar, Map<InjectionNode, TypedExpression> expressionMap) throws JClassAlreadyExistsException {

        InjectionBuilderContext injectionBuilderContext = injectionBuilderContextFactory.buildContext(block, instantiateOnceStrategy, definedClass, scopeVar, expressionMap);

        injectionExpressionBuilder.buildVariable(injectionBuilderContext, injectionNode);

        //loop over remaining injection chains, building cyclic graph
        while(!injectionBuilderContext.getProxyLoad().isEmpty()){
            Map<InjectionNode, TypedExpression> proxied = new HashMap<InjectionNode, TypedExpression>(injectionBuilderContext.getProxyLoad());

            injectionBuilderContext.getProxyLoad().clear();
            for (Map.Entry<InjectionNode, TypedExpression> node : proxied.entrySet()) {
                injectionExpressionBuilder.setupInjectionRequirements(injectionBuilderContext, node.getKey());

                VirtualProxyAspect aspect = node.getKey().getAspect(VirtualProxyAspect.class);
                aspect.setProxyDefined(true);

                injectionBuilderContext.getVariableMap().remove(node.getKey());
                TypedExpression delegateVariable = injectionExpressionBuilder.buildVariable(injectionBuilderContext, node.getKey());

                //init proxy
                virtualProxyGenerator.initializeProxy(injectionBuilderContext, node.getValue(), delegateVariable);
            }
        }

        return injectionBuilderContext.getVariableMap();
    }
}


text:
<resources>
    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="demo2_activity_horizontal_margin">16dp</dimen>
    <dimen name="demo2_activity_vertical_margin">16dp</dimen>
</resources>


text:
package integrationTests.homepage;

import org.junit.*;

import mockit.*;

public final class JMockitVerificationsExampleTest
{
   @Test // notice the "mock parameter", whose argument value will be created automatically
   public void testDoAnotherOperation(final AnotherDependency anotherMock)
   {
      new NonStrictExpectations() {
         DependencyXyz mock; // mock instance created and assigned automatically

         {
            mock.doSomething("test"); result = 123;
         }
      };

      // In ServiceAbc#doAnotherOperationAbc(String s): "new DependencyXyz().doSomething(s);"
      // and "new AnotherDependency().complexOperation(1, obj);".
      new ServiceAbc().doAnotherOperation("test");

      new Verifications() {{
         anotherMock.complexOperation(anyInt, null);
      }};
   }
}


text:
//**************************************************************************/
// Copyright (c) 1998-2006 Autodesk, Inc.
// All rights reserved.
//
// These coded instructions, statements, and computer programs contain
// unpublished proprietary information written by Autodesk, Inc., and are
// protected by Federal copyright law. They may not be disclosed to third
// parties or copied or duplicated in any form, in whole or in part, without
// the prior written consent of Autodesk, Inc.
//**************************************************************************/
// FILE:        linshape.h
// DESCRIPTION: Defines a Linear Shape Object Class
// AUTHOR:      Tom Hudson
// HISTORY:     created 31 October 1995
//**************************************************************************/

#pragma once

#include "object.h"

extern CoreExport Class_ID  linearShapeClassID;

#pragma warning(push)
#pragma warning(disable:4239)

/*! \sa  Class ShapeObject, Class PolyShape, Working with Shapes and Splines.\n\n
\par Description:
This class represents a linear shape object. This class is similar to a
SplineShape except this class uses a PolyShape as its data while
a SplineShape uses a BezierShape as its data. Therefore this is a
shape made up of entirely linear segments. All methods of this class are
implemented by the system.
\par Data Members:
PolyShape shape;\n\n
The PolyShape that holds the linear shape.  */
class LinearShape : public ShapeObject {
	private:
		Interval geomValid;
		Interval topoValid;
		Interval selectValid;
		ChannelMask validBits; // for the remaining constant channels
		void CopyValidity(LinearShape *fromOb, ChannelMask channels);

	protected:
		//  inherited virtual methods for Reference-management
		RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message );

	public:
		PolyShape		shape;

		/*! \remarks Constructor. */
		CoreExport LinearShape();
		/*! \remarks Destructor. */
		CoreExport ~LinearShape();

		CoreExport LinearShape &operator=(LinearShape &from);

		//  inherited virtual methods:

		// From BaseObject
		CoreExport int HitTest(TimeValue t, INode* inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt);
		CoreExport void Snap(TimeValue t, INode* inode, SnapInfo *snap, IPoint2 *p, ViewExp *vpt);
		CoreExport int Display(TimeValue t, INode* inode, ViewExp *vpt, int flags);
		CoreExport CreateMouseCallBack* GetCreateMouseCallBack();
		CoreExport RefTargetHandle Clone(RemapDir& remap);
		// From Object
		CoreExport ObjectState Eval(TimeValue time);
		CoreExport Interval ObjectValidity(TimeValue t);

		// The validity interval of channels necessary to do a convert to type
		CoreExport Interval ConvertValidity(TimeValue t);

		// get and set the validity interval for the nth channel
	   	CoreExport Interval ChannelValidity(TimeValue t, int nchan);
		CoreExport void SetChannelValidity(int i, Interval v);
		CoreExport void InvalidateChannels(ChannelMask channels);

		// Deformable object procs
		int IsDeformable() { return 1; }
		CoreExport int NumPoints();
		CoreExport Point3 GetPoint(int i);
		CoreExport void SetPoint(int i, const Point3& p);
		CoreExport BOOL IsPointSelected (int i);

		CoreExport void PointsWereChanged();
		CoreExport void GetDeformBBox(TimeValue t, Box3& box, Matrix3 *tm=NULL,BOOL useSel=FALSE );
		CoreExport void Deform(Deformer *defProc, int useSel);

		CoreExport int CanConvertToType(Class_ID obtype);
		CoreExport Object* ConvertToType(TimeValue t, Class_ID obtype);
		CoreExport void FreeChannels(ChannelMask chan);
		CoreExport Object *MakeShallowCopy(ChannelMask channels);
		CoreExport void ShallowCopy(Object* fromOb, ChannelMask channels);
		CoreExport void NewAndCopyChannels(ChannelMask channels);

		CoreExport DWORD GetSubselState();

		// From ShapeObject
		CoreExport ObjectHandle CreateTriObjRep(TimeValue t);  // for rendering, also for deformation
		CoreExport void GetWorldBoundBox(TimeValue t, INode *inode, ViewExp* vpt, Box3& box );
		CoreExport void GetLocalBoundBox(TimeValue t, INode *inode, ViewExp* vpt, Box3& box );
		CoreExport int NumberOfVertices(TimeValue t, int curve);
		CoreExport int NumberOfCurves();
		CoreExport BOOL CurveClosed(TimeValue t, int curve);
		CoreExport Point3 InterpCurve3D(TimeValue t, int curve, float param, int ptype=PARAM_SIMPLE);
		CoreExport Point3 TangentCurve3D(TimeValue t, int curve, float param, int ptype=PARAM_SIMPLE);
		CoreExport float LengthOfCurve(TimeValue t, int curve);
		CoreExport int NumberOfPieces(TimeValue t, int curve);
		CoreExport Point3 InterpPiece3D(TimeValue t, int curve, int piece, float param, int ptype=PARAM_SIMPLE);
		CoreExport Point3 TangentPiece3D(TimeValue t, int curve, int piece, float param, int ptype=PARAM_SIMPLE);
		/*! \remarks This method is available in release 3.0 and later
		only.\n\n
		This method provides access to the material IDs of the shape. It
		returns the material ID of the specified segment of the specified curve
		of this shape at the time passed. There is a default implementation so
		there is no need to implement this method if the shape does not support
		material IDs.\n\n
		Note: typedef unsigned short MtlID;
		\par Parameters:
		TimeValue t\n\n
		The time to evaluate the sub-curve.\n\n
		int curve\n\n
		The zero based index of the curve to evaluate.\n\n
		int piece\n\n
		The sub-curve (segment) to evaluate. */
		CoreExport MtlID GetMatID(TimeValue t, int curve, int piece);
		BOOL CanMakeBezier() { return TRUE; }
		CoreExport void MakeBezier(TimeValue t, BezierShape &shape);
		CoreExport ShapeHierarchy &OrganizeCurves(TimeValue t, ShapeHierarchy *hier = NULL);
		CoreExport void MakePolyShape(TimeValue t, PolyShape &shape, int steps = PSHAPE_BUILTIN_STEPS, BOOL optimize = FALSE);
		CoreExport int MakeCap(TimeValue t, MeshCapInfo &capInfo, int capType);
		CoreExport int MakeCap(TimeValue t, PatchCapInfo &capInfo);

		/*! \remarks Returns the shape data member. */
		PolyShape& GetShape() { return shape; }

		// This does the job of setting all points in the PolyShape to "POLYPT_KNOT"
		// types, and removing the "POLYPT_INTERPOLATED" flag.  This is because the
		// LinearShape knows nothing about its origin
		/*! \remarks This method does the job of setting all points in the
		PolyShape to POLYPT_KNOT types, and removing the
		POLYPT_INTERPOLATED flag. This is because the LinearShape knows
		nothing about its origin. */
		CoreExport void SetPointFlags();

		// Animatable methods

		CoreExport void DeleteThis();
		void FreeCaches() { shape.InvalidateGeomCache(FALSE); }
		Class_ID ClassID() { return linearShapeClassID; }
		CoreExport void GetClassName(MSTR& s);
		void NotifyMe(Animatable* subAnim, int message) { UNUSED_PARAM(subAnim); UNUSED_PARAM(message);}
		int IsKeyable() { return 0;}
		int Update(TimeValue t) { UNUSED_PARAM(t); return 0; }
		BOOL BypassTreeView() { return TRUE; }
		// This is the name that will appear in the history browser.
		CoreExport const MCHAR *GetObjectName();

		// IO
		CoreExport IOResult Save(ISave *isave);
		CoreExport IOResult Load(ILoad *iload);

		// RefMaker methods
		CoreExport void RescaleWorldUnits(float f);

		// Flush all caches
		CoreExport void InvalidateGeomCache();
	};

#pragma warning(pop)

CoreExport ClassDesc* GetLinearShapeDescriptor();


text:
VBSharper
=========

VBSharper is a set of ReSharper extensions for those of us who want/need to work in VB.Net for one reason or another.

Bulk Quick Fixes
----------------

Use IsNot Operator - Replace "Not x Is y" with "x IsNot y"

Remove ByVal Keyword - Explicit use of ByVal keyword is unnecessary

Use Short-circuit Operators - Replace And with AndAlso & Or with OrElse

Use Implicit Line Continuation - Remove unnecessary explicit line continuation characters

Refactorings
------------

Convert Shared Method to Extension Method - Available via "Refactor This" Menu (Ctrl+Shift+R) when your cursor is on a shared method.


text:
/*
 * Copyright 1999-2004 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * $Id: DTMAxisTraverser.java,v 1.2.4.1 2005/09/15 08:14:52 suresh_emailid Exp $
 */
package com.sun.org.apache.xml.internal.dtm;

/**
 * A class that implements traverses DTMAxisTraverser interface can traverse
 * a set of nodes, usually as defined by an XPath axis.  It is different from
 * an iterator, because it does not need to hold state, and, in fact, must not
 * hold any iteration-based state.  It is meant to be implemented as an inner
 * class of a DTM, and returned by the getAxisTraverser(final int axis)
 * function.
 *
 *
A DTMAxisTraverser can probably not traverse a reverse axis in
 * document order.

 *
 *
Typical usage:

 *

 * for(int nodeHandle=myTraverser.first(myContext);
 *     nodeHandle!=DTM.NULL;
 *     nodeHandle=myTraverser.next(myContext,nodeHandle))
 * { ... processing for node indicated by nodeHandle goes here ... }
 *

 *
 * @author Scott Boag
 */
public abstract class DTMAxisTraverser
{

  /**
   * By the nature of the stateless traversal, the context node can not be
   * returned or the iteration will go into an infinate loop.  So to traverse
   * an axis, the first function must be used to get the first node.
   *
   *
This method needs to be overloaded only by those axis that process
   * the self node. <\p>
   *
   * @param context The context node of this traversal. This is the point
   * that the traversal starts from.
   * @return the first node in the traversal.
   */
  public int first(int context)
  {
    return next(context, context);
  }

  /**
   * By the nature of the stateless traversal, the context node can not be
   * returned or the iteration will go into an infinate loop.  So to traverse
   * an axis, the first function must be used to get the first node.
   *
   *
This method needs to be overloaded only by those axis that process
   * the self node. <\p>
   *
   * @param context The context node of this traversal. This is the point
   * of origin for the traversal -- its "root node" or starting point.
   * @param extendedTypeID The extended type ID that must match.
   *
   * @return the first node in the traversal.
   */
  public int first(int context, int extendedTypeID)
  {
    return next(context, context, extendedTypeID);
  }

  /**
   * Traverse to the next node after the current node.
   *
   * @param context The context node of this traversal. This is the point
   * of origin for the traversal -- its "root node" or starting point.
   * @param current The current node of the traversal. This is the last known
   * location in the traversal, typically the node-handle returned by the
   * previous traversal step. For the first traversal step, context
   * should be set equal to current. Note that in order to test whether
   * context is in the set, you must use the first() method instead.
   *
   * @return the next node in the iteration, or DTM.NULL.
   * @see #first(int)
   */
  public abstract int next(int context, int current);

  /**
   * Traverse to the next node after the current node that is matched
   * by the extended type ID.
   *
   * @param context The context node of this traversal. This is the point
   * of origin for the traversal -- its "root node" or starting point.
   * @param current The current node of the traversal. This is the last known
   * location in the traversal, typically the node-handle returned by the
   * previous traversal step. For the first traversal step, context
   * should be set equal to current. Note that in order to test whether
   * context is in the set, you must use the first() method instead.
   * @param extendedTypeID The extended type ID that must match.
   *
   * @return the next node in the iteration, or DTM.NULL.
   * @see #first(int,int)
   */
  public abstract int next(int context, int current, int extendedTypeID);
}


text:
/**
 */

/*
*/

package org.apache.harmony.test.func.api.java.lang.ClassLoader.getPackages.getPackages10.getPackages1010;

import java.lang.reflect.Constructor;

import java.net.URL;
import java.io.*;
import java.util.*;

import org.apache.harmony.share.Test;
import org.apache.harmony.test.func.share.MyLog;

public class getPackages1010 extends Test {

    boolean  results[] = new boolean[100];
    String  logArray[] = new String[100];
    int     logIndex   = 0;

    void addLog(String s) {
        if ( logIndex < logArray.length )
            logArray[logIndex] = s;
        logIndex++;
    }

    void getPackages1010() {

        MygetPackages1010 mygetPackages1010 = new MygetPackages1010();

        String packageName    = "org.apache.harmony.test.func.api.java.lang.ClassLoader.getPackages.getPackages10.getPackages1010" ;
        mygetPackages1010.getPackage(packageName);

        Package[] pkgs = mygetPackages1010.getPackages();
//-1
        results[1] = pkgs != null ;
//-1)
//-2
        results[2] = pkgs.length >= 1 ;
//-2)
        return ;
    }
class MygetPackages1010 extends ClassLoader {
    MygetPackages1010() {super();}

    public Package getPackage(String s) {
        return super.getPackage(s);
   }
    public Package[] getPackages() {
        return super.getPackages();
   }
}

    public int test() {

        logIndex = 0;

        String texts[] = { "Testcase FAILURE, results[#] = " ,
                           "Test P A S S E D"                ,
                           "Test F A I L E D"                ,
                           "#### U N E X P E C T E D : "     };

        int    failed   = 105;
        int    passed   = 104;
        int  unexpected = 106;

        int    toReturn = 0;
        String toPrint  = null;

        for ( int i = 0; i < results.length; i++ )
            results[i] = true;

        try {

            addLog("*********  Test getPackages1010 begins ");
getPackages1010();
            addLog("*********  Test getPackages1010 results: ");

            boolean result = true;
            for ( int i = 1 ; i < results.length ; i++ ) {
                result &= results[i];
                if ( ! results[i] )
                    addLog(texts[0] + i);
            }
            if ( ! result ) {
                toPrint  = texts[2];
                toReturn = failed;
            }
            if ( result ) {
                toPrint  = texts[1];
                toReturn = passed;
            }
        } catch (Exception e) {
            toPrint  = texts[3] + e;
            toReturn = unexpected;
        }
        if ( toReturn != passed )
            for ( int i = 0; i < logIndex; i++ )
                MyLog.toMyLog(logArray[i]);

        MyLog.toMyLog(toPrint);
        return toReturn;
    }

    public static void main(String args[]) {
        System.exit(new getPackages1010().test());
    }
}


text:
<!--
  ~ Copyright 2019 Louis Cognault Ayeva Derman. Use of this source code is governed by the Apache 2.0 license.
  -->

<resources>
    <!-- Example customization of dimensions originally defined in res/values/dimens.xml
         (such as screen margins) for screens with more than 820dp of available width. This
         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
    <dimen name="activity_horizontal_margin">64dp</dimen>
</resources>