// -*-c++-*-
// vim: set ft=cpp:

/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file LICENSE.rst or https://cmake.org/licensing for details.  */
#pragma once

#include "cmSTL.hxx" // IWYU pragma: keep

#if defined(CMake_HAVE_CXX_FILESYSTEM)

#  include <filesystem> // IWYU pragma: export

#else

#  include <cstddef>
#  include <cstdint>
#  include <iostream>
#  include <iterator>
#  include <memory>
#  include <string>
#  include <utility>

#  include <cm/iomanip>
#  include <cm/string_view>
#  include <cm/type_traits>
#  include <cmext/iterator>

#  if defined(_WIN32) && !defined(__CYGWIN__)
#    include <algorithm>
#  endif

#endif

namespace cm {
namespace filesystem {

#if defined(CMake_HAVE_CXX_FILESYSTEM)

using std::filesystem::path;
using std::filesystem::swap;
using std::filesystem::hash_value;

#else

#  if !defined(CM_FILESYSTEM_SOURCE_TRAITS_ITERATOR)
// Oracle DeveloperStudio C++ compiler on Solaris/Sparc fails to compile
// the source_traits for iterator check.  So disable it for now.
#    define CM_FILESYSTEM_SOURCE_TRAITS_ITERATOR 0
#  endif

namespace internals {

class path_parser;

class unicode_helper
{
protected:
  using utf8_state = unsigned char;
  static utf8_state const s_start = 0;
  static utf8_state const s_reject = 8;

  static inline bool in_range(std::uint32_t c, std::uint32_t lo,
                              std::uint32_t hi)
  {
    return (static_cast<std::uint32_t>(c - lo) < (hi - lo + 1));
  }

  static inline bool is_surrogate(std::uint32_t c)
  {
    return in_range(c, 0xd800, 0xdfff);
  }

  static inline bool is_high_surrogate(std::uint32_t c)
  {
    return (c & 0xfffffc00) == 0xd800;
  }

  static inline bool is_low_surrogate(std::uint32_t c)
  {
    return (c & 0xfffffc00) == 0xdc00;
  }

  static void append(std::string& str, std::uint32_t codepoint);

  static utf8_state decode(utf8_state const state, std::uint8_t const fragment,
                           std::uint32_t& codepoint);
};

template <typename Char, typename = void>
class unicode
{
};

template <typename Char>
class unicode<Char, typename std::enable_if<(sizeof(Char) == 4)>::type>
  : public unicode_helper
{
public:
  // UTF32 -> UTF8
  static std::string to_utf8(std::wstring const& str)
  {
    std::string result;
    for (auto c : str) {
      append(result, c);
    }
    return result;
  }
  static std::string to_utf8(Char c)
  {
    std::string result;
    append(result, c);
    return result;
  }

  // UTF8 -> UTF32
  static std::wstring from_utf8(std::string const& str)
  {
    std::wstring result;
    result.reserve(str.length());
    auto iter = str.begin();
    utf8_state state = s_start;
    std::uint32_t codepoint = 0;
    while (iter < str.end()) {
      if ((state = decode(state, static_cast<std::uint8_t>(*iter++),
                          codepoint)) == s_start) {
        result += static_cast<std::wstring::value_type>(codepoint);
        codepoint = 0;
      } else if (state == s_reject) {
        result += static_cast<std::wstring::value_type>(0xfffd);
        state = s_start;
        codepoint = 0;
      }
    }
    if (state) {
      result += static_cast<std::wstring::value_type>(0xfffd);
    }
    return result;
  }
  static std::wstring from_utf8(char c)
  {
    std::wstring result;
    utf8_state state = s_start;
    std::uint32_t codepoint = 0;
    if ((state = decode(state, static_cast<std::uint8_t>(c), codepoint)) ==
        s_start) {
      result += static_cast<std::wstring::value_type>(codepoint);
    } else {
      result += static_cast<std::wstring::value_type>(0xfffd);
    }

    return result;
  }
};

template <typename Char>
class unicode<Char, typename std::enable_if<(sizeof(Char) == 2)>::type>
  : public unicode_helper
{
public:
  // UTF16 -> UTF8
  static std::string to_utf8(std::wstring const& str)
  {
    std::string result;
    for (auto iter = str.begin(); iter != str.end(); ++iter) {
      std::uint32_t c = *iter;
      if (is_surrogate(c)) {
        ++iter;
        if (iter != str.end() && is_high_surrogate(c) &&
            is_low_surrogate(*iter)) {
          append(result, (std::uint32_t(c) << 10) + *iter - 0x35fdc00);
        } else {
          append(result, 0xfffd);
          if (iter == str.end()) {
            break;
          }
        }
      } else {
        append(result, c);
      }
    }
    return result;
  }
  static std::string to_utf8(Char c)
  {
    std::string result;
    if (is_surrogate(c)) {
      append(result, 0xfffd);
    } else {
      append(result, c);
    }
    return result;
  }

  // UTF8 -> UTF16
  static std::wstring from_utf8(std::string const& str)
  {
    std::wstring result;
    result.reserve(str.length());
    auto iter = str.begin();
    utf8_state state = s_start;
    std::uint32_t codepoint = 0;
    while (iter < str.end()) {
      if ((state = decode(state, static_cast<std::uint8_t>(*iter++),
                          codepoint)) == s_start) {
        if (codepoint <= 0xffff) {
          result += static_cast<std::wstring::value_type>(codepoint);
        } else {
          codepoint -= 0x10000;
          result +=
            static_cast<std::wstring::value_type>((codepoint >> 10) + 0xd800);
          result += static_cast<std::wstring::value_type>((codepoint & 0x3ff) +
                                                          0xdc00);
        }
        codepoint = 0;
      } else if (state == s_reject) {
        result += static_cast<std::wstring::value_type>(0xfffd);
        state = s_start;
        codepoint = 0;
      }
    }
    if (state) {
      result += static_cast<std::wstring::value_type>(0xfffd);
    }
    return result;
  }
  static std::wstring from_utf8(char c)
  {
    std::wstring result;
    utf8_state state = s_start;
    std::uint32_t codepoint = 0;
    if ((state = decode(state, static_cast<std::uint8_t>(c), codepoint)) ==
        s_start) {
      if (codepoint <= 0xffff) {
        result += static_cast<std::wstring::value_type>(codepoint);
      } else {
        codepoint -= 0x10000;
        result +=
          static_cast<std::wstring::value_type>((codepoint >> 10) + 0xd800);
        result +=
          static_cast<std::wstring::value_type>((codepoint & 0x3ff) + 0xdc00);
      }
    } else {
      result += static_cast<std::wstring::value_type>(0xfffd);
    }
    return result;
  }
};

template <typename In, typename Out>
class unicode_converter;

template <>
class unicode_converter<char, wchar_t>
{
public:
  std::wstring operator()(std::string const& in)
  {
    return unicode<wchar_t>::from_utf8(in);
  }
  std::wstring operator()(char const* in)
  {
    return unicode<wchar_t>::from_utf8(in);
  }
  std::wstring operator()(char in) { return unicode<wchar_t>::from_utf8(in); }
};
template <>
class unicode_converter<wchar_t, char>
{
public:
  std::string operator()(std::wstring const& in)
  {
    return unicode<wchar_t>::to_utf8(in);
  }
  std::string operator()(wchar_t const* in)
  {
    return unicode<wchar_t>::to_utf8(in);
  }
  std::string operator()(wchar_t in) { return unicode<wchar_t>::to_utf8(in); }
};
template <>
class unicode_converter<char, char>
{
public:
  std::string operator()(std::string const& in) { return in; }
  std::string operator()(char const* in) { return std::string(in); }
  std::string operator()(char in) { return std::string(1, in); }
};
template <>
class unicode_converter<wchar_t, wchar_t>
{
public:
  std::wstring operator()(std::wstring const& in) { return in; }
  std::wstring operator()(wchar_t const* in) { return std::wstring(in); }
  std::wstring operator()(wchar_t in) { return std::wstring(1, in); }
};

template <typename In>
struct string_converter
{
};

template <>
struct string_converter<char>
{
  // some compilers, like gcc 4.8 does not implement the following C++11
  // signature:
  // std::string::string(const string&, const Allocator&)
  // As workaround, use char* pointer.
  template <typename Char, typename Traits, typename Alloc>
  static std::basic_string<Char, Traits, Alloc> to(std::string const& in,
                                                   Alloc const& a)
  {
    return std::basic_string<Char, Traits, Alloc>(
      unicode_converter<char, Char>()(in).c_str(), a);
  }
  template <typename Char, typename Traits, typename Alloc>
  static std::basic_string<Char, Traits, Alloc> to(char const* in,
                                                   Alloc const& a)
  {
    return std::basic_string<Char, Traits, Alloc>(
      unicode_converter<char, Char>()(in).c_str(), a);
  }
  template <typename Char, typename Traits, typename Alloc>
  static std::basic_string<Char, Traits, Alloc> to(char in, Alloc const& a)
  {
    return std::basic_string<Char, Traits, Alloc>(
      unicode_converter<char, Char>()(in).c_str(), a);
  }

  template <typename Char>
  static std::basic_string<Char> to(std::string const& in)
  {
    return std::basic_string<Char>(unicode_converter<char, Char>()(in));
  }
  template <typename Char>
  static std::basic_string<Char> to(char const* in)
  {
    return std::basic_string<Char>(unicode_converter<char, Char>()(in));
  }
  template <typename Char>
  static std::basic_string<Char> to(char in)
  {
    return std::basic_string<Char>(unicode_converter<char, Char>()(in));
  }
};
template <>
struct string_converter<wchar_t>
{
  // some compilers, like gcc 4.8 does not implement the following C++11
  // signature:
  // std::string::string(const string&, const Allocator&)
  // As workaround, use char* pointer.
  template <typename Char, typename Traits, typename Alloc>
  static std::basic_string<Char, Traits, Alloc> to(std::wstring const& in,
                                                   Alloc const& a)
  {
    return std::basic_string<Char, Traits, Alloc>(
      unicode_converter<wchar_t, Char>()(in).c_str(), a);
  }
  template <typename Char, typename Traits, typename Alloc>
  static std::basic_string<Char, Traits, Alloc> to(wchar_t const* in,
                                                   Alloc const& a)
  {
    return std::basic_string<Char, Traits, Alloc>(
      unicode_converter<wchar_t, Char>()(in).c_str(), a);
  }
  template <typename Char, typename Traits, typename Alloc>
  static std::basic_string<Char, Traits, Alloc> to(wchar_t in, Alloc const& a)
  {
    return std::basic_string<Char, Traits, Alloc>(
      unicode_converter<wchar_t, Char>()(in).c_str(), a);
  }

  template <typename Char>
  static std::basic_string<Char> to(std::wstring const& in)
  {
    return std::basic_string<Char>(unicode_converter<wchar_t, Char>()(in));
  }
  template <typename Char>
  static std::basic_string<Char> to(wchar_t const* in)
  {
    return std::basic_string<Char>(unicode_converter<wchar_t, Char>()(in));
  }
  template <typename Char>
  static std::basic_string<Char> to(wchar_t in)
  {
    return std::basic_string<Char>(unicode_converter<wchar_t, Char>()(in));
  }
};

template <typename T, typename = void>
struct source_traits
{
};

template <typename T, std::size_t N>
struct source_traits<T[N]>
{
  using value_type = T;
};

template <typename Char, typename Traits, typename Alloc>
struct source_traits<std::basic_string<Char, Traits, Alloc>>
{
  using value_type =
    typename std::basic_string<Char, Traits, Alloc>::value_type;
};

template <>
struct source_traits<cm::string_view>
{
  using value_type = cm::string_view::value_type;
};

#  if CM_FILESYSTEM_SOURCE_TRAITS_ITERATOR
template <typename T>
struct source_traits<T, cm::enable_if_t<cm::is_iterator<T>::value, void>>
{
  using value_type =
    typename std::iterator_traits<typename std::decay<T>::type>::value_type;
};
#  endif

template <typename In, typename Out>
struct source_converter
{
};

template <>
struct source_converter<char, char>
{
  template <typename Iterator>
  static void append_range(std::string& p, Iterator b, Iterator e)
  {
    if (b == e) {
      return;
    }
    p.append(b, e);
  }
  template <typename Iterator>
  static void append_range(std::string& p, Iterator b)
  {
    char e = '\0';

    if (*b == e) {
      return;
    }
    for (; *b != e; ++b) {
      p.push_back(*b);
    }
  }

  static void append_source(std::string& p, cm::string_view const s)
  {
    append_range(p, s.begin(), s.end());
  }
  template <typename Traits, typename Alloc>
  static void append_source(std::string& p,
                            std::basic_string<char, Traits, Alloc> const& s)
  {
    append_range(p, s.begin(), s.end());
  }
  template <typename Source>
  static void append_source(std::string& p, Source const& s)
  {
    append_range(p, s);
  }

  static void set_source(std::string& p, std::string&& s) { p = std::move(s); }
};

template <>
struct source_converter<wchar_t, char>
{
  template <typename Iterator>
  static void append_range(std::string& p, Iterator b, Iterator e)
  {
    if (b == e) {
      return;
    }

    std::wstring tmp(b, e);
    std::string dest = string_converter<wchar_t>::to<char>(tmp);
    p.append(dest.begin(), dest.end());
  }
  template <typename Iterator>
  static void append_range(std::string& p, Iterator b)
  {
    wchar_t e = '\0';

    if (*b == e) {
      return;
    }
    std::wstring tmp;
    for (; *b != e; ++b) {
      tmp.push_back(*b);
    }

    std::string dest = string_converter<wchar_t>::to<char>(tmp);
    p.append(dest.begin(), dest.end());
  }

  template <typename Traits, typename Alloc>
  static void append_source(std::string& p,
                            std::basic_string<wchar_t, Traits, Alloc> const& s)
  {
    append_range(p, s.begin(), s.end());
  }
  template <typename Source>
  static void append_source(std::string& p, Source const& s)
  {
    append_range(p, s);
  }

  static void set_source(std::string& p, std::wstring&& s)
  {
    p = string_converter<wchar_t>::to<char>(s);
  }
};

template <typename T>
struct is_pathable_string : std::false_type
{
};
template <typename Traits, typename Alloc>
struct is_pathable_string<std::basic_string<char, Traits, Alloc>>
  : std::true_type
{
};
template <typename Traits, typename Alloc>
struct is_pathable_string<std::basic_string<wchar_t, Traits, Alloc>>
  : std::true_type
{
};
template <>
struct is_pathable_string<cm::string_view> : std::true_type
{
};

template <typename T, typename = void>
struct is_pathable_char_array : std::false_type
{
};
template <typename T>
struct is_pathable_char_array<
  T,
  cm::enable_if_t<
    std::is_same<char*, typename std::decay<T>::type>::value ||
      std::is_same<wchar_t*, typename std::decay<T>::type>::value,
    void>>
  : bool_constant<std::is_same<char*, typename std::decay<T>::type>::value ||
                  std::is_same<wchar_t*, typename std::decay<T>::type>::value>
{
};

template <typename T, typename = void>
struct is_pathable_iterator : std::false_type
{
};
template <typename T>
struct is_pathable_iterator<
  T,
  cm::enable_if_t<
    is_input_iterator<T>::value &&
      (std::is_same<char,
                    typename std::iterator_traits<
                      typename std::decay<T>::type>::value_type>::value ||
       std::is_same<wchar_t,
                    typename std::iterator_traits<
                      typename std::decay<T>::type>::value_type>::value),
    void>>
  : bool_constant<
      std::is_same<char,
                   typename std::iterator_traits<
                     typename std::decay<T>::type>::value_type>::value ||
      std::is_same<wchar_t,
                   typename std::iterator_traits<
                     typename std::decay<T>::type>::value_type>::value>
{
};

#  if defined(__SUNPRO_CC) && defined(__sparc)
// Oracle DeveloperStudio C++ compiler on Solaris/Sparc fails to compile
// the full 'is_pathable' check.  We use it only to improve error messages
// via 'enable_if' when calling methods with incorrect types.  Just
// pretend all types are allowed so we can at least compile valid code.
template <typename T>
struct is_pathable : std::true_type
{
};
#  else
template <typename T>
struct is_pathable
  : bool_constant<is_pathable_string<T>::value ||
                  is_pathable_char_array<T>::value ||
                  is_pathable_iterator<T>::value>
{
};
#  endif
}

class path
{
  using path_type = std::string;

  template <typename Source>
  using enable_if_pathable =
    enable_if_t<internals::is_pathable<Source>::value, path&>;

  enum class filename_fragment : unsigned char
  {
    stem,
    extension
  };

public:
#  if defined(_WIN32) && !defined(__CYGWIN__)
  using value_type = wchar_t;
#  else
  using value_type = char;
#  endif
  using string_type = std::basic_string<value_type>;

  class iterator;
  using const_iterator = iterator;

  enum format : unsigned char
  {
    auto_format,
    native_format,
    generic_format
  };

#  if defined(_WIN32) && !defined(__CYGWIN__)
  static constexpr value_type preferred_separator = L'\\';
#  else
  static constexpr value_type preferred_separator = '/';
#  endif

  // Constructors
  // ============
  path() noexcept {}
  path(path const& p)
    : path_(p.path_)
  {
  }
  path(path&& p) noexcept
    : path_(std::move(p.path_))
  {
  }
  path(string_type&& source, format fmt = auto_format)
  {
    (void)fmt;
    internals::source_converter<value_type, path_type::value_type>::set_source(
      this->path_, std::move(source));
  }
  template <typename Source, typename = enable_if_pathable<Source>>
  path(Source const& source, format fmt = auto_format)
  {
    (void)fmt;
    internals::source_converter<
      typename internals::source_traits<Source>::value_type,
      path_type::value_type>::append_source(this->path_, source);
  }
  template <typename Iterator, typename = enable_if_pathable<Iterator>>
  path(Iterator const first, Iterator last, format fmt = auto_format)
  {
    (void)fmt;
    internals::source_converter<
      typename std::iterator_traits<Iterator>::value_type,
      path_type::value_type>::append_range(this->path_, first, last);
  }

  ~path() = default;

  // Assignments
  // ===========
  path& operator=(path const& p)
  {
    if (this != &p) {
      this->path_ = p.path_;
    }
    return *this;
  }
  path& operator=(path&& p) noexcept
  {
    if (this != &p) {
      this->path_ = std::move(p.path_);
    }
    return *this;
  }
  path& operator=(string_type&& source) { return this->assign(source); }
  template <typename Source, typename = enable_if_pathable<Source>>
  path& operator=(Source const& source)
  {
    return this->assign(source);
  }

  path& assign(string_type&& source)
  {
    internals::source_converter<value_type, path_type::value_type>::set_source(
      this->path_, std::move(source));
    return *this;
  }
  template <typename Source, typename = enable_if_pathable<Source>>
  path& assign(Source const& source)
  {
    this->path_.clear();
    internals::source_converter<
      typename internals::source_traits<Source>::value_type,
      path_type::value_type>::append_source(this->path_, source);
    return *this;
  }
  template <typename Iterator, typename = enable_if_pathable<Iterator>>
  path& assign(Iterator first, Iterator last)
  {
    this->path_.clear();
    internals::source_converter<
      typename std::iterator_traits<Iterator>::value_type,
      path_type::value_type>::append_range(this->path_, first, last);
    return *this;
  }

  // Concatenation
  // =============
  path& operator/=(path const& p);

  template <typename Source, typename = enable_if_pathable<Source>>
  path& append(Source const& source)
  {
    return this->operator/=(path(source));
  }
  template <typename Source>
  path& operator/=(Source const& source)
  {
    return this->append(source);
  }

  template <typename Iterator, typename = enable_if_pathable<Iterator>>
  path& append(Iterator first, Iterator last)
  {
    return this->operator/=(path(first, last));
  }

  path& operator+=(path const& p)
  {
    this->path_ += p.path_;
    return *this;
  }
  path& operator+=(string_type const& str)
  {
    this->path_ +=
      internals::string_converter<value_type>::to<path_type::value_type>(str);
    return *this;
  }
  path& operator+=(cm::string_view str)
  {
    this->path_.append(str.begin(), str.end());
    return *this;
  }
  path& operator+=(value_type const* str)
  {
    this->path_ +=
      internals::string_converter<value_type>::to<path_type::value_type>(str);
    return *this;
  }
  path& operator+=(value_type const c)
  {
    this->path_ +=
      internals::string_converter<value_type>::to<path_type::value_type>(c);
    return *this;
  }
  template <typename Source, typename = enable_if_pathable<Source>>
  path& concat(Source const& source)
  {
    internals::source_converter<
      typename internals::source_traits<Source>::value_type,
      path_type::value_type>::append_source(this->path_, source);
    return *this;
  }
  template <typename Source>
  path& operator+=(Source const& source)
  {
    return this->concat(source);
  }
  template <typename Iterator, typename = enable_if_pathable<Iterator>>
  path& concat(Iterator first, Iterator last)
  {
    internals::source_converter<
      typename std::iterator_traits<Iterator>::value_type,
      path_type::value_type>::append_range(this->path_, first, last);
    return *this;
  }

  // Modifiers
  // =========
  void clear() noexcept { this->path_.clear(); }

  path& make_preferred()
  {
#  if defined(_WIN32) && !defined(__CYGWIN__)
    std::replace(
      this->path_.begin(), this->path_.end(), '/',
      static_cast<path_type::value_type>(this->preferred_separator));
#  endif
    return *this;
  }

  path& remove_filename()
  {
    auto fname = this->get_filename();
    if (!fname.empty()) {
      this->path_.erase(fname.data() -
                        // Avoid C++17 non-const .data() that may reallocate.
                        static_cast<path_type const&>(this->path_).data());
    }
    return *this;
  }

  path& replace_filename(path const& replacement)
  {
    this->remove_filename();
    this->operator/=(replacement);
    return *this;
  }

  path& replace_extension(path const& replacement = path())
  {
    auto ext = this->get_filename_fragment(filename_fragment::extension);
    if (!ext.empty()) {
      this->path_.erase(ext.data() -
                        // Avoid C++17 non-const .data() that may reallocate.
                        static_cast<path_type const&>(this->path_).data());
    }
    if (!replacement.path_.empty()) {
      if (replacement.path_[0] != '.') {
        this->path_ += '.';
      }
      this->path_.append(replacement.path_);
    }
    return *this;
  }

  void swap(path& other) noexcept { this->path_.swap(other.path_); }

  // Format observers
  // ================
  string_type const& native() const noexcept
  {
#  if defined(_WIN32) && !defined(__CYGWIN__)
    this->native_path_ = internals::string_converter<
      path_type::value_type>::to<string_type::value_type>(this->path_);
    return this->native_path_;
#  else
    return this->path_;
#  endif
  }
  value_type const* c_str() const noexcept { return this->native().c_str(); }
  operator string_type() const { return this->native(); }

  template <
    typename Char, typename Traits = std::char_traits<Char>,
    typename Alloc = std::allocator<Char>,
    cm::enable_if_t<(std::is_same<Char, char>::value &&
                     std::is_same<Traits, std::char_traits<char>>::value) ||
                      (std::is_same<Char, wchar_t>::value &&
                       std::is_same<Traits, std::char_traits<wchar_t>>::value),
                    int> = 1>
  std::basic_string<Char, Traits, Alloc> string(Alloc const& a = Alloc()) const
  {
    return internals::string_converter<path_type::value_type>::to<Char, Traits,
                                                                  Alloc>(
      this->path_, a);
  }
  std::string const string() const { return this->path_; }
  std::wstring wstring() const
  {
    std::string out = this->string();
    return internals::string_converter<path_type::value_type>::to<
      std::wstring::value_type>(out);
  }

  template <
    typename Char, typename Traits = std::char_traits<Char>,
    typename Alloc = std::allocator<Char>,
    cm::enable_if_t<(std::is_same<Char, char>::value &&
                     std::is_same<Traits, std::char_traits<char>>::value) ||
                      (std::is_same<Char, wchar_t>::value &&
                       std::is_same<Traits, std::char_traits<wchar_t>>::value),
                    int> = 1>
  std::basic_string<Char, Traits, Alloc> generic_string(
    Alloc const& a = Alloc()) const
  {
    return internals::string_converter<path_type::value_type>::to<Char, Traits,
                                                                  Alloc>(
      this->get_generic(), a);
  }
  std::string generic_string() const { return this->get_generic(); }
  std::wstring generic_wstring() const
  {
    auto dest = this->generic_string();
    return internals::string_converter<path_type::value_type>::to<
      std::wstring::value_type>(dest);
  }

  // Compare
  // =======
  int compare(path const& p) const noexcept
  {
    return this->compare_path(p.path_);
  }
  int compare(string_type const& str) const
  {
    return this->compare_path(
      internals::string_converter<value_type>::to<path_type::value_type>(str));
  }
  int compare(value_type const* str) const
  {
    return this->compare_path(
      internals::string_converter<value_type>::to<path_type::value_type>(str));
  }
  int compare(cm::string_view str) const { return this->compare_path(str); }

  // Generation
  // ==========
  path lexically_normal() const;

  path lexically_relative(path const& base) const;

  path lexically_proximate(path const& base) const
  {
    path result = this->lexically_relative(base);
    return result.empty() ? *this : result;
  }

  // Decomposition
  // =============
  path root_name() const { return get_root_name(); }

  path root_directory() const { return this->get_root_directory(); }

  path root_path() const
  {
    return this->root_name().append(this->get_root_directory());
  }

  path relative_path() const { return this->get_relative_path(); }

  path parent_path() const { return this->get_parent_path(); }

  path filename() const { return this->get_filename(); }

  path stem() const
  {
    return this->get_filename_fragment(filename_fragment::stem);
  }
  path extension() const
  {
    return this->get_filename_fragment(filename_fragment::extension);
  }

  // Queries
  // =======
  bool empty() const noexcept { return this->path_.empty(); }

  bool has_root_name() const { return !this->get_root_name().empty(); }

  bool has_root_directory() const
  {
    return !this->get_root_directory().empty();
  }

  bool has_root_path() const
  {
    return this->has_root_name() || this->has_root_directory();
  }

  bool has_relative_path() const { return !this->get_relative_path().empty(); }

  bool has_parent_path() const { return !this->get_parent_path().empty(); }

  bool has_filename() const { return !this->get_filename().empty(); }

  bool has_stem() const
  {
    return !this->get_filename_fragment(filename_fragment::stem).empty();
  }
  bool has_extension() const
  {
    return !this->get_filename_fragment(filename_fragment::extension).empty();
  }

  bool is_absolute() const
  {
#  if defined(_WIN32) && !defined(__CYGWIN__)
    return this->has_root_name() && this->has_root_directory();
#  else
    // For CYGWIN, root_name (i.e. //host or /cygdrive/x) is not considered.
    // Same as current GNU g++ implementation (9.3).
    return this->has_root_directory();
#  endif
  }

  bool is_relative() const { return !this->is_absolute(); }

  // Iterators
  // =========
  inline iterator begin() const;
  inline iterator end() const;

  // Non-members
  // ===========
  friend inline bool operator==(path const& lhs, path const& rhs) noexcept
  {
    return lhs.compare(rhs) == 0;
  }
  friend inline bool operator!=(path const& lhs, path const& rhs) noexcept
  {
    return lhs.compare(rhs) != 0;
  }
  friend inline bool operator<(path const& lhs, path const& rhs) noexcept
  {
    return lhs.compare(rhs) < 0;
  }
  friend inline bool operator<=(path const& lhs, path const& rhs) noexcept
  {
    return lhs.compare(rhs) <= 0;
  }
  friend inline bool operator>(path const& lhs, path const& rhs) noexcept
  {
    return lhs.compare(rhs) > 0;
  }
  friend inline bool operator>=(path const& lhs, path const& rhs) noexcept
  {
    return lhs.compare(rhs) >= 0;
  }

  friend inline path operator/(path const& lhs, path const& rhs)
  {
    path result(lhs);
    result /= rhs;

    return result;
  }

  template <typename Char, typename Traits>
  friend inline cm::enable_if_t<
    (std::is_same<Char, path::value_type>::value &&
     std::is_same<Traits, std::char_traits<path::value_type>>::value) ||
      (std::is_same<Char, path::path_type::value_type>::value &&
       std::is_same<Traits,
                    std::char_traits<path::path_type::value_type>>::value),
    std::basic_ostream<Char, Traits>&>
  operator<<(std::basic_ostream<Char, Traits>& os, path const& p)
  {
    os << cm::quoted(p.string<Char, Traits>());
    return os;
  }

  template <typename Char, typename Traits>
  friend inline cm::enable_if_t<
    (std::is_same<Char, path::value_type>::value &&
     std::is_same<Traits, std::char_traits<path::value_type>>::value) ||
      (std::is_same<Char, path::path_type::value_type>::value &&
       std::is_same<Traits,
                    std::char_traits<path::path_type::value_type>>::value),
    std::basic_istream<Char, Traits>&>
  operator>>(std::basic_istream<Char, Traits>& is, path& p)
  {
    std::basic_string<Char, Traits> tmp;
    is >> cm::quoted(tmp);
    p = tmp;
    return is;
  }

private:
  friend class iterator;
  friend std::size_t hash_value(path const& p) noexcept;

  path_type get_generic() const;

  cm::string_view get_root_name() const;
  cm::string_view get_root_directory() const;
  cm::string_view get_relative_path() const;
  cm::string_view get_parent_path() const;
  cm::string_view get_filename() const;
  cm::string_view get_filename_fragment(filename_fragment fragment) const;

  int compare_path(cm::string_view str) const;

  path_type path_;
#  if defined(_WIN32) && !defined(__CYGWIN__)
  mutable string_type native_path_;
#  endif
};

class path::iterator
{
public:
  using iterator_category = std::bidirectional_iterator_tag;

  using value_type = path;
  using difference_type = std::ptrdiff_t;
  using pointer = path const*;
  using reference = path const&;

  iterator();
  iterator(iterator const& other);

  ~iterator();

  iterator& operator=(iterator const& other);

  reference operator*() const { return this->path_element_; }

  pointer operator->() const { return &this->path_element_; }

  iterator& operator++();

  iterator operator++(int)
  {
    iterator it(*this);
    this->operator++();
    return it;
  }

  iterator& operator--();

  iterator operator--(int)
  {
    iterator it(*this);
    this->operator--();
    return it;
  }

private:
  friend class path;
  friend bool operator==(iterator const&, iterator const&);

  iterator(path const* p, bool at_end = false);

  path const* path_;
  std::unique_ptr<internals::path_parser> parser_;
  path path_element_;
};

inline path::iterator path::begin() const
{
  return iterator(this);
}
inline path::iterator path::end() const
{
  return iterator(this, true);
}

// Non-member functions
// ====================
bool operator==(path::iterator const& lhs, path::iterator const& rhs);

inline bool operator!=(path::iterator const& lhs, path::iterator const& rhs)
{
  return !(lhs == rhs);
}

inline void swap(path& lhs, path& rhs) noexcept
{
  lhs.swap(rhs);
}

std::size_t hash_value(path const& p) noexcept;

#endif

} // namespace filesystem
} // namespace cm
