Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. // Filesystem directory utilities -*- C++ -*-
  2.  
  3. // Copyright (C) 2014-2015 Free Software Foundation, Inc.
  4. //
  5. // This file is part of the GNU ISO C++ Library.  This library is free
  6. // software; you can redistribute it and/or modify it under the
  7. // terms of the GNU General Public License as published by the
  8. // Free Software Foundation; either version 3, or (at your option)
  9. // any later version.
  10.  
  11. // This library is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. // GNU General Public License for more details.
  15.  
  16. // Under Section 7 of GPL version 3, you are granted additional
  17. // permissions described in the GCC Runtime Library Exception, version
  18. // 3.1, as published by the Free Software Foundation.
  19.  
  20. // You should have received a copy of the GNU General Public License and
  21. // a copy of the GCC Runtime Library Exception along with this program;
  22. // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
  23. // <http://www.gnu.org/licenses/>.
  24.  
  25. /** @file experimental/fs_dir.h
  26.  *  This is an internal header file, included by other library headers.
  27.  *  Do not attempt to use it directly. @headername{experimental/filesystem}
  28.  */
  29.  
  30. #ifndef _GLIBCXX_EXPERIMENTAL_FS_DIR_H
  31. #define _GLIBCXX_EXPERIMENTAL_FS_DIR_H 1
  32.  
  33. #if __cplusplus < 201103L
  34. # include <bits/c++0x_warning.h>
  35. #else
  36. # include <typeinfo>
  37. # include <ext/concurrence.h>
  38. # include <bits/unique_ptr.h>
  39. # include <bits/shared_ptr.h>
  40.  
  41. namespace std _GLIBCXX_VISIBILITY(default)
  42. {
  43. namespace experimental
  44. {
  45. namespace filesystem
  46. {
  47. inline namespace v1
  48. {
  49. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  50.  
  51.   /**
  52.    * @ingroup filesystem
  53.    * @{
  54.    */
  55.  
  56.   class file_status
  57.   {
  58.   public:
  59.     // constructors
  60.     explicit
  61.     file_status(file_type __ft = file_type::none,
  62.                 perms __prms = perms::unknown) noexcept
  63.     : _M_type(__ft), _M_perms(__prms) { }
  64.  
  65.     file_status(const file_status&) noexcept = default;
  66.     file_status(file_status&&) noexcept = default;
  67.     ~file_status() = default;
  68.  
  69.     file_status& operator=(const file_status&) noexcept = default;
  70.     file_status& operator=(file_status&&) noexcept = default;
  71.  
  72.     // observers
  73.     file_type  type() const noexcept { return _M_type; }
  74.     perms      permissions() const noexcept { return _M_perms; }
  75.  
  76.     // modifiers
  77.     void       type(file_type __ft) noexcept { _M_type = __ft; }
  78.     void       permissions(perms __prms) noexcept { _M_perms = __prms; }
  79.  
  80.   private:
  81.     file_type   _M_type;
  82.     perms       _M_perms;
  83.   };
  84.  
  85. _GLIBCXX_BEGIN_NAMESPACE_CXX11
  86.  
  87.   class directory_entry
  88.   {
  89.   public:
  90.     // constructors and destructor
  91.     directory_entry() noexcept = default;
  92.     directory_entry(const directory_entry&) = default;
  93.     directory_entry(directory_entry&&) noexcept = default;
  94.     explicit directory_entry(const filesystem::path& __p) : _M_path(__p) { }
  95.     ~directory_entry() = default;
  96.  
  97.     // modifiers
  98.     directory_entry& operator=(const directory_entry&) = default;
  99.     directory_entry& operator=(directory_entry&&) noexcept = default;
  100.  
  101.     void assign(const filesystem::path& __p) { _M_path = __p; }
  102.  
  103.     void
  104.     replace_filename(const filesystem::path& __p)
  105.     { _M_path = _M_path.parent_path() / __p; }
  106.  
  107.     // observers
  108.     const filesystem::path&  path() const noexcept { return _M_path; }
  109.     operator const filesystem::path&() const noexcept { return _M_path; }
  110.  
  111.     file_status
  112.     status() const
  113.     { return filesystem::status(_M_path); }
  114.  
  115.     file_status
  116.     status(error_code& __ec) const noexcept
  117.     { return filesystem::status(_M_path, __ec); }
  118.  
  119.     file_status
  120.     symlink_status() const
  121.     { return filesystem::symlink_status(_M_path); }
  122.  
  123.     file_status
  124.     symlink_status(error_code& __ec) const noexcept
  125.     { return filesystem::symlink_status(_M_path, __ec); }
  126.  
  127.     bool
  128.     operator< (const directory_entry& __rhs) const noexcept
  129.     { return _M_path < __rhs._M_path; }
  130.  
  131.     bool
  132.     operator==(const directory_entry& __rhs) const noexcept
  133.     { return _M_path == __rhs._M_path; }
  134.  
  135.     bool
  136.     operator!=(const directory_entry& __rhs) const noexcept
  137.     { return _M_path != __rhs._M_path; }
  138.  
  139.     bool
  140.     operator<=(const directory_entry& __rhs) const noexcept
  141.     { return _M_path <= __rhs._M_path; }
  142.  
  143.     bool
  144.     operator> (const directory_entry& __rhs) const noexcept
  145.     { return _M_path > __rhs._M_path; }
  146.  
  147.     bool
  148.     operator>=(const directory_entry& __rhs) const noexcept
  149.     { return _M_path >= __rhs._M_path; }
  150.  
  151.   private:
  152.     filesystem::path    _M_path;
  153.   };
  154.  
  155.   struct _Dir;
  156.   class directory_iterator;
  157.   class recursive_directory_iterator;
  158.  
  159.   struct __directory_iterator_proxy
  160.   {
  161.     const directory_entry& operator*() const& noexcept { return _M_entry; }
  162.  
  163.     directory_entry operator*() && noexcept { return std::move(_M_entry); }
  164.  
  165.   private:
  166.     friend class directory_iterator;
  167.     friend class recursive_directory_iterator;
  168.  
  169.     explicit
  170.     __directory_iterator_proxy(const directory_entry& __e) : _M_entry(__e) { }
  171.  
  172.     directory_entry _M_entry;
  173.   };
  174.  
  175.   class directory_iterator
  176.   {
  177.   public:
  178.     typedef directory_entry        value_type;
  179.     typedef ptrdiff_t              difference_type;
  180.     typedef const directory_entry* pointer;
  181.     typedef const directory_entry& reference;
  182.     typedef input_iterator_tag     iterator_category;
  183.  
  184.     directory_iterator() noexcept = default;
  185.  
  186.     explicit
  187.     directory_iterator(const path& __p)
  188.     : directory_iterator(__p, directory_options::none, nullptr) { }
  189.  
  190.     directory_iterator(const path& __p, directory_options __options)
  191.     : directory_iterator(__p, __options, nullptr) { }
  192.  
  193.     directory_iterator(const path& __p, error_code& __ec) noexcept
  194.     : directory_iterator(__p, directory_options::none, __ec) { }
  195.  
  196.     directory_iterator(const path& __p,
  197.                        directory_options __options,
  198.                        error_code& __ec) noexcept
  199.     : directory_iterator(__p, __options, &__ec) { }
  200.  
  201.     directory_iterator(const directory_iterator& __rhs) = default;
  202.  
  203.     directory_iterator(directory_iterator&& __rhs) noexcept = default;
  204.  
  205.     ~directory_iterator() = default;
  206.  
  207.     directory_iterator&
  208.     operator=(const directory_iterator& __rhs) = default;
  209.  
  210.     directory_iterator&
  211.     operator=(directory_iterator&& __rhs) noexcept = default;
  212.  
  213.     const directory_entry& operator*() const;
  214.     const directory_entry* operator->() const { return &**this; }
  215.     directory_iterator&    operator++();
  216.     directory_iterator&    increment(error_code& __ec) noexcept;
  217.  
  218.     __directory_iterator_proxy operator++(int)
  219.     {
  220.       __directory_iterator_proxy __pr{**this};
  221.       ++*this;
  222.       return __pr;
  223.     }
  224.  
  225.   private:
  226.     directory_iterator(const path&, directory_options, error_code*);
  227.  
  228.     friend bool
  229.     operator==(const directory_iterator& __lhs,
  230.                const directory_iterator& __rhs);
  231.  
  232.     friend class recursive_directory_iterator;
  233.  
  234.     std::shared_ptr<_Dir> _M_dir;
  235.   };
  236.  
  237.   inline directory_iterator
  238.   begin(directory_iterator __iter) noexcept
  239.   { return __iter; }
  240.  
  241.   inline directory_iterator
  242.   end(directory_iterator) noexcept
  243.   { return directory_iterator(); }
  244.  
  245.   inline bool
  246.   operator==(const directory_iterator& __lhs, const directory_iterator& __rhs)
  247.   {
  248.     return !__rhs._M_dir.owner_before(__lhs._M_dir)
  249.       && !__lhs._M_dir.owner_before(__rhs._M_dir);
  250.   }
  251.  
  252.   inline bool
  253.   operator!=(const directory_iterator& __lhs, const directory_iterator& __rhs)
  254.   { return !(__lhs == __rhs); }
  255.  
  256.   class recursive_directory_iterator
  257.   {
  258.   public:
  259.     typedef directory_entry        value_type;
  260.     typedef ptrdiff_t              difference_type;
  261.     typedef const directory_entry* pointer;
  262.     typedef const directory_entry& reference;
  263.     typedef input_iterator_tag     iterator_category;
  264.  
  265.     recursive_directory_iterator() noexcept = default;
  266.  
  267.     explicit
  268.     recursive_directory_iterator(const path& __p)
  269.     : recursive_directory_iterator(__p, directory_options::none, nullptr) { }
  270.  
  271.     recursive_directory_iterator(const path& __p, directory_options __options)
  272.     : recursive_directory_iterator(__p, __options, nullptr) { }
  273.  
  274.     recursive_directory_iterator(const path& __p,
  275.                                  directory_options __options,
  276.                                  error_code& __ec) noexcept
  277.     : recursive_directory_iterator(__p, __options, &__ec) { }
  278.  
  279.     recursive_directory_iterator(const path& __p, error_code& __ec) noexcept
  280.     : recursive_directory_iterator(__p, directory_options::none, &__ec) { }
  281.  
  282.     recursive_directory_iterator(
  283.         const recursive_directory_iterator&) = default;
  284.  
  285.     recursive_directory_iterator(
  286.         recursive_directory_iterator&&) noexcept = default;
  287.  
  288.     ~recursive_directory_iterator();
  289.  
  290.     // observers
  291.     directory_options  options() const { return _M_options; }
  292.     int                depth() const;
  293.     bool               recursion_pending() const { return _M_pending; }
  294.  
  295.     const directory_entry& operator*() const;
  296.     const directory_entry* operator->() const { return &**this; }
  297.  
  298.     // modifiers
  299.     recursive_directory_iterator&
  300.     operator=(const recursive_directory_iterator& __rhs) noexcept;
  301.     recursive_directory_iterator&
  302.     operator=(recursive_directory_iterator&& __rhs) noexcept;
  303.  
  304.     recursive_directory_iterator& operator++();
  305.     recursive_directory_iterator& increment(error_code& __ec) noexcept;
  306.  
  307.     __directory_iterator_proxy operator++(int)
  308.     {
  309.       __directory_iterator_proxy __pr{**this};
  310.       ++*this;
  311.       return __pr;
  312.     }
  313.  
  314.     void pop();
  315.  
  316.     void disable_recursion_pending() { _M_pending = false; }
  317.  
  318.   private:
  319.     recursive_directory_iterator(const path&, directory_options, error_code*);
  320.  
  321.     friend bool
  322.     operator==(const recursive_directory_iterator& __lhs,
  323.                const recursive_directory_iterator& __rhs);
  324.  
  325.     struct _Dir_stack;
  326.     std::shared_ptr<_Dir_stack> _M_dirs;
  327.     directory_options _M_options = {};
  328.     bool _M_pending = false;
  329.   };
  330.  
  331.   inline recursive_directory_iterator
  332.   begin(recursive_directory_iterator __iter) noexcept
  333.   { return __iter; }
  334.  
  335.   inline recursive_directory_iterator
  336.   end(recursive_directory_iterator) noexcept
  337.   { return recursive_directory_iterator(); }
  338.  
  339.   inline bool
  340.   operator==(const recursive_directory_iterator& __lhs,
  341.              const recursive_directory_iterator& __rhs)
  342.   {
  343.     return !__rhs._M_dirs.owner_before(__lhs._M_dirs)
  344.       && !__lhs._M_dirs.owner_before(__rhs._M_dirs);
  345.   }
  346.  
  347.   inline bool
  348.   operator!=(const recursive_directory_iterator& __lhs,
  349.              const recursive_directory_iterator& __rhs)
  350.   { return !(__lhs == __rhs); }
  351.  
  352. _GLIBCXX_END_NAMESPACE_CXX11
  353.  
  354.   // @} group filesystem
  355. _GLIBCXX_END_NAMESPACE_VERSION
  356. } // namespace v1
  357. } // namespace filesystem
  358. } // namespace experimental
  359. } // namespace std
  360.  
  361. #endif // C++11
  362.  
  363. #endif // _GLIBCXX_EXPERIMENTAL_FS_DIR_H
  364.