// Filesystem declarations -*- C++ -*-

// Copyright (C) 2014-2021 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

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

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/** @file include/bits/fs_fwd.h
 *  This is an internal header file, included by other library headers.
 *  Do not attempt to use it directly. @headername{filesystem}
 */

#ifndef _GLIBCXX_FS_FWD_H
#define _GLIBCXX_FS_FWD_H 1

#if __cplusplus >= 201703L

#include <system_error>
#include <cstdint>
#include <bits/chrono.h>

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

/// ISO C++ 2017 namespace for File System library
namespace filesystem
{
#if _GLIBCXX_USE_CXX11_ABI
/// @cond undocumented
inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
/// @endcond
#endif

/** @addtogroup filesystem
 *  @{
 */

  class file_status;
_GLIBCXX_BEGIN_NAMESPACE_CXX11
  class path;
  class filesystem_error;
  class directory_entry;
  class directory_iterator;
  class recursive_directory_iterator;
_GLIBCXX_END_NAMESPACE_CXX11

  /// Information about free space on a disk
  struct space_info
  {
    uintmax_t capacity;
    uintmax_t free;
    uintmax_t available;

#if __cpp_impl_three_way_comparison >= 201907L
    friend bool operator==(const space_info&, const space_info&) = default;
#endif
  };

  /// Enumerated type representing the type of a file
  enum class file_type : signed char {
      none = 0, not_found = -1, regular = 1, directory = 2, symlink = 3,
      block = 4, character = 5, fifo = 6, socket = 7, unknown = 8
  };

  /// Bitmask type controlling effects of `filesystem::copy`
  enum class copy_options : unsigned short {
      none = 0,
      skip_existing = 1, overwrite_existing = 2, update_existing = 4,
      recursive = 8,
      copy_symlinks = 16, skip_symlinks = 32,
      directories_only = 64, create_symlinks = 128, create_hard_links = 256
  };

  /// @{
  /// @relates copy_options
  constexpr copy_options
  operator&(copy_options __x, copy_options __y) noexcept
  {
    using __utype = typename std::underlying_type<copy_options>::type;
    return static_cast<copy_options>(
	static_cast<__utype>(__x) & static_cast<__utype>(__y));
  }

  constexpr copy_options
  operator|(copy_options __x, copy_options __y) noexcept
  {
    using __utype = typename std::underlying_type<copy_options>::type;
    return static_cast<copy_options>(
	static_cast<__utype>(__x) | static_cast<__utype>(__y));
  }

  constexpr copy_options
  operator^(copy_options __x, copy_options __y) noexcept
  {
    using __utype = typename std::underlying_type<copy_options>::type;
    return static_cast<copy_options>(
	static_cast<__utype>(__x) ^ static_cast<__utype>(__y));
  }

  constexpr copy_options
  operator~(copy_options __x) noexcept
  {
    using __utype = typename std::underlying_type<copy_options>::type;
    return static_cast<copy_options>(~static_cast<__utype>(__x));
  }

  inline copy_options&
  operator&=(copy_options& __x, copy_options __y) noexcept
  { return __x = __x & __y; }

  inline copy_options&
  operator|=(copy_options& __x, copy_options __y) noexcept
  { return __x = __x | __y; }

  inline copy_options&
  operator^=(copy_options& __x, copy_options __y) noexcept
  { return __x = __x ^ __y; }
  /// @}


  /// Bitmask type representing file access permissions
  enum class perms : unsigned {
      none		=  0,
      owner_read	=  0400,
      owner_write	=  0200,
      owner_exec	=  0100,
      owner_all		=  0700,
      group_read	=   040,
      group_write	=   020,
      group_exec	=   010,
      group_all		=   070,
      others_read	=    04,
      others_write	=    02,
      others_exec	=    01,
      others_all	=    07,
      all		=  0777,
      set_uid		= 04000,
      set_gid		= 02000,
      sticky_bit	= 01000,
      mask		= 07777,
      unknown		=  0xFFFF,
  };

  /// @{
  /// @relates perm_options
  constexpr perms
  operator&(perms __x, perms __y) noexcept
  {
    using __utype = typename std::underlying_type<perms>::type;
    return static_cast<perms>(
	static_cast<__utype>(__x) & static_cast<__utype>(__y));
  }

  constexpr perms
  operator|(perms __x, perms __y) noexcept
  {
    using __utype = typename std::underlying_type<perms>::type;
    return static_cast<perms>(
	static_cast<__utype>(__x) | static_cast<__utype>(__y));
  }

  constexpr perms
  operator^(perms __x, perms __y) noexcept
  {
    using __utype = typename std::underlying_type<perms>::type;
    return static_cast<perms>(
	static_cast<__utype>(__x) ^ static_cast<__utype>(__y));
  }

  constexpr perms
  operator~(perms __x) noexcept
  {
    using __utype = typename std::underlying_type<perms>::type;
    return static_cast<perms>(~static_cast<__utype>(__x));
  }

  inline perms&
  operator&=(perms& __x, perms __y) noexcept
  { return __x = __x & __y; }

  inline perms&
  operator|=(perms& __x, perms __y) noexcept
  { return __x = __x | __y; }

  inline perms&
  operator^=(perms& __x, perms __y) noexcept
  { return __x = __x ^ __y; }
  /// @}

  /// Bitmask type controlling changes to permissions
  enum class perm_options : unsigned {
      replace	= 0x1,
      add	= 0x2,
      remove	= 0x4,
      nofollow	= 0x8
  };

  /// @{
  /// @relates perm_options
  constexpr perm_options
  operator&(perm_options __x, perm_options __y) noexcept
  {
    using __utype = typename std::underlying_type<perm_options>::type;
    return static_cast<perm_options>(
	static_cast<__utype>(__x) & static_cast<__utype>(__y));
  }

  constexpr perm_options
  operator|(perm_options __x, perm_options __y) noexcept
  {
    using __utype = typename std::underlying_type<perm_options>::type;
    return static_cast<perm_options>(
	static_cast<__utype>(__x) | static_cast<__utype>(__y));
  }

  constexpr perm_options
  operator^(perm_options __x, perm_options __y) noexcept
  {
    using __utype = typename std::underlying_type<perm_options>::type;
    return static_cast<perm_options>(
	static_cast<__utype>(__x) ^ static_cast<__utype>(__y));
  }

  constexpr perm_options
  operator~(perm_options __x) noexcept
  {
    using __utype = typename std::underlying_type<perm_options>::type;
    return static_cast<perm_options>(~static_cast<__utype>(__x));
  }

  inline perm_options&
  operator&=(perm_options& __x, perm_options __y) noexcept
  { return __x = __x & __y; }

  inline perm_options&
  operator|=(perm_options& __x, perm_options __y) noexcept
  { return __x = __x | __y; }

  inline perm_options&
  operator^=(perm_options& __x, perm_options __y) noexcept
  { return __x = __x ^ __y; }
  /// @}

  /// Bitmask type controlling directory iteration
  enum class directory_options : unsigned char {
      none = 0, follow_directory_symlink = 1, skip_permission_denied = 2
  };

  /// @{
  /// @relates directory_options
  constexpr directory_options
  operator&(directory_options __x, directory_options __y) noexcept
  {
    using __utype = typename std::underlying_type<directory_options>::type;
    return static_cast<directory_options>(
	static_cast<__utype>(__x) & static_cast<__utype>(__y));
  }

  constexpr directory_options
  operator|(directory_options __x, directory_options __y) noexcept
  {
    using __utype = typename std::underlying_type<directory_options>::type;
    return static_cast<directory_options>(
	static_cast<__utype>(__x) | static_cast<__utype>(__y));
  }

  constexpr directory_options
  operator^(directory_options __x, directory_options __y) noexcept
  {
    using __utype = typename std::underlying_type<directory_options>::type;
    return static_cast<directory_options>(
	static_cast<__utype>(__x) ^ static_cast<__utype>(__y));
  }

  constexpr directory_options
  operator~(directory_options __x) noexcept
  {
    using __utype = typename std::underlying_type<directory_options>::type;
    return static_cast<directory_options>(~static_cast<__utype>(__x));
  }

  inline directory_options&
  operator&=(directory_options& __x, directory_options __y) noexcept
  { return __x = __x & __y; }

  inline directory_options&
  operator|=(directory_options& __x, directory_options __y) noexcept
  { return __x = __x | __y; }

  inline directory_options&
  operator^=(directory_options& __x, directory_options __y) noexcept
  { return __x = __x ^ __y; }
  /// @}

  /// The type used for file timestamps
  using file_time_type = __file_clock::time_point;

  // operational functions

  void copy(const path& __from, const path& __to, copy_options __options);
  void copy(const path& __from, const path& __to, copy_options __options,
	    error_code&);

  bool copy_file(const path& __from, const path& __to, copy_options __option);
  bool copy_file(const path& __from, const path& __to, copy_options __option,
		 error_code&);

  path current_path();

  bool exists(file_status) noexcept;

  bool is_other(file_status) noexcept;

  uintmax_t file_size(const path&);
  uintmax_t file_size(const path&, error_code&) noexcept;
  uintmax_t hard_link_count(const path&);
  uintmax_t hard_link_count(const path&, error_code&) noexcept;
  file_time_type last_write_time(const path&);
  file_time_type last_write_time(const path&, error_code&) noexcept;

  void permissions(const path&, perms, perm_options, error_code&) noexcept;

  path proximate(const path& __p, const path& __base, error_code& __ec);
  path proximate(const path& __p, const path& __base, error_code& __ec);

  path relative(const path& __p, const path& __base, error_code& __ec);

  file_status status(const path&);
  file_status status(const path&, error_code&) noexcept;

  bool status_known(file_status) noexcept;

  file_status symlink_status(const path&);
  file_status symlink_status(const path&, error_code&) noexcept;

  bool is_regular_file(file_status) noexcept;
  bool is_symlink(file_status) noexcept;

/// @}
} // namespace filesystem
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // C++17
#endif // _GLIBCXX_FS_FWD_H
