Browse Source

* Refactored directory classes

master
bergmann 4 years ago
parent
commit
e6075832c8
20 changed files with 536 additions and 239 deletions
  1. +4
    -1
      cmake/asyncpp-options.cmake
  2. +2
    -1
      cmake/config.h.in
  3. +5
    -1
      include/asyncpp.h
  4. +1
    -1
      include/asyncpp/core/future.h
  5. +1
    -1
      include/asyncpp/core/future/future.h
  6. +1
    -1
      include/asyncpp/core/stream.h
  7. +1
    -1
      include/asyncpp/core/stream/stream.h
  8. +0
    -2
      include/asyncpp/fs.h
  9. +9
    -40
      include/asyncpp/fs/directory.h
  10. +0
    -167
      include/asyncpp/fs/directory.inl
  11. +49
    -0
      include/asyncpp/fs/directory/create.inl
  12. +49
    -0
      include/asyncpp/fs/directory/create_all.inl
  13. +100
    -0
      include/asyncpp/fs/directory/directory.h
  14. +14
    -0
      include/asyncpp/fs/directory/directory.inl
  15. +80
    -0
      include/asyncpp/fs/directory/read.inl
  16. +111
    -0
      include/asyncpp/fs/directory/read_all.inl
  17. +49
    -0
      include/asyncpp/fs/directory/remove.inl
  18. +49
    -0
      include/asyncpp/fs/directory/remove_all.inl
  19. +1
    -1
      include/asyncpp/timing.h
  20. +10
    -22
      test/asyncpp/fs/directory_tests.cpp

+ 4
- 1
cmake/asyncpp-options.cmake View File

@@ -9,6 +9,9 @@ Option ( ASYNCPP_INSTALL_PACKAGE
Option ( ASYNCPP_USE_GIT_VERSION
"Read the git tags to get the version of asyncpp"
ON )
Option ( ASYNCPP_FEATURE_TIMING_ENABLED
Option ( ASYNCPP_ENABLE_FEATURE_FS
"Enable the file system features of asyncpp"
ON )
Option ( ASYNCPP_ENABLE_FEATURE_TIMING
"Enable the timing features of asyncpp"
ON )

+ 2
- 1
cmake/config.h.in View File

@@ -1,3 +1,4 @@
#pragma once

#cmakedefine ASYNCPP_FEATURE_TIMING_ENABLED
#cmakedefine ASYNCPP_ENABLE_FEATURE_FS
#cmakedefine ASYNCPP_ENABLE_FEATURE_TIMING

+ 5
- 1
include/asyncpp.h View File

@@ -4,6 +4,10 @@

#include <asyncpp/core.h>

#ifdef ASYNCPP_FEATURE_TIMING_ENABLED
#ifdef ASYNCPP_ENABLE_FEATURE_FS
#include <asyncpp/fs.h>
#endif

#ifdef ASYNCPP_ENABLE_FEATURE_TIMING
#include <asyncpp/timing.h>
#endif

+ 1
- 1
include/asyncpp/core/future.h View File

@@ -6,6 +6,6 @@
#include "future/lazy.inl"
#include "future/and_then.inl"

#ifdef ASYNCPP_FEATURE_TIMING_ENABLED
#ifdef ASYNCPP_ENABLE_FEATURE_TIMING
#include "future/timeout.inl"
#endif

+ 1
- 1
include/asyncpp/core/future/future.h View File

@@ -57,7 +57,7 @@ namespace asyncpp
typename X_lambda>
inline auto and_then(X_lambda&& p_lambda) &&;

#ifdef ASYNCPP_FEATURE_TIMING_ENABLED
#ifdef ASYNCPP_ENABLE_FEATURE_TIMING
public:
/**
* @brief Throw an execption if the timeout has passed.


+ 1
- 1
include/asyncpp/core/stream.h View File

@@ -6,6 +6,6 @@
#include "stream/flatten.inl"
#include "stream/for_each.inl"

#ifdef ASYNCPP_FEATURE_TIMING_ENABLED
#ifdef ASYNCPP_ENABLE_FEATURE_TIMING
#include "stream/timeout.inl"
#endif

+ 1
- 1
include/asyncpp/core/stream/stream.h View File

@@ -75,7 +75,7 @@ namespace asyncpp
chaining_mode X_mode = move>
inline auto flatten() &&;

#ifdef ASYNCPP_FEATURE_TIMING_ENABLED
#ifdef ASYNCPP_ENABLE_FEATURE_TIMING
public:
/**
* @brief Throw an execption if the timeout has passed.


+ 0
- 2
include/asyncpp/fs.h View File

@@ -1,5 +1,3 @@
#pragma once

#include "fs/directory.h"

#include "fs/directory.inl"

+ 9
- 40
include/asyncpp/fs/directory.h View File

@@ -1,42 +1,11 @@
#pragma once

#include <string>

#include <cppfs/path.h>

#include <asyncpp/core/stream/stream.pre.h>

namespace asyncpp {
namespace fs {

/**
* @brief Create future to read the content of a directory.
*/
inline auto read_dir(const cppfs::path& p_path);

/**
* @brief Create future to read the content of a directory including the subdirectories.
*/
inline auto read_dir_all(const cppfs::path& p_path);

/**
* @brief Create a new future to create a directory.
*/
inline auto create_dir(const cppfs::path& p_path);

/**
* @brief Create a new future to create a directory and all it's parent directories.
*/
inline auto create_dir_all(const cppfs::path& p_path);

/**
* @brief Create a new future to remove an empty directory.
*/
inline auto remove_dir(const cppfs::path& p_path);

/**
* @brief Create a new future to remove a directory and all it's content.
*/
inline auto remove_dir_all(const cppfs::path& p_path);

} }
#include "directory/directory.h"

#include "directory/directory.inl"
#include "directory/create.inl"
#include "directory/create_all.inl"
#include "directory/read.inl"
#include "directory/read_all.inl"
#include "directory/remove.inl"
#include "directory/remove_all.inl"

+ 0
- 167
include/asyncpp/fs/directory.inl View File

@@ -1,167 +0,0 @@
#pragma once

#include <vector>

#include <cppfs/directory.h>

#include "directory.h"

namespace asyncpp {
namespace fs {

namespace __impl
{

struct read_dir_impl
: public base_stream<
cppfs::directory::entry,
read_dir_impl>
{
public:
using value_type = cppfs::directory::entry;
using this_type = read_dir_impl;
using base_future_type = base_stream<value_type, this_type>;
using result_type = typename base_future_type::result_type;

private:
cppfs::directory::iterator _it;
cppfs::directory::iterator _end;

public:
inline read_dir_impl(
const cppfs::path& p_path)
{
cppfs::directory d(p_path);
if (d.exists())
{
_it = d.begin();
_end = d.end();
}
}

public:
inline result_type poll()
{
if (_it == _end)
return result_type::done();

auto ret = result_type::ready(*_it);
++_it;
return ret;
}
};

struct read_dir_all_impl
: public base_stream<
cppfs::directory::entry,
read_dir_all_impl>
{
public:
using value_type = cppfs::directory::entry;
using this_type = read_dir_impl;
using base_future_type = base_stream<value_type, this_type>;
using result_type = typename base_future_type::result_type;

private:
struct entry
{
cppfs::directory::iterator it;
cppfs::directory::iterator end;
};

using entry_stack = std::vector<entry>;

entry_stack _stack;

public:
inline read_dir_all_impl(
const cppfs::path& p_path)
{
cppfs::directory d(p_path);
if (d.exists())
{
_stack.emplace_back(entry {
d.begin(),
d.end()
});
}
}

public:
inline result_type poll()
{
while (true)
{
if (_stack.empty())
return result_type::done();

auto& e = _stack.back();
if (e.it == e.end)
{
_stack.pop_back();
continue;
}

auto ret = result_type::ready(std::move(*e.it));
cppfs::directory d(e.it->path);

++e.it;

if (d.exists())
{
_stack.emplace_back(entry {
d.begin(),
d.end(),
});
}

return ret;
}
}
};

}

auto read_dir(const cppfs::path& p_path)
{
return __impl::read_dir_impl(p_path);
}

auto read_dir_all(const cppfs::path& p_path)
{
return __impl::read_dir_all_impl(p_path);
}

auto create_dir(const cppfs::path& p_path)
{
return lazy([d = cppfs::directory(p_path)]{
if (!d.exists())
d.create(false);
});
}

auto create_dir_all(const cppfs::path& p_path)
{
return lazy([d = cppfs::directory(p_path)]{
if (!d.exists())
d.create(true);
});
}

auto remove_dir(const cppfs::path& p_path)
{
return lazy([d = cppfs::directory(p_path)]{
if (d.exists())
d.remove(false);
});
}

auto remove_dir_all(const cppfs::path& p_path)
{
return lazy([d = cppfs::directory(p_path)]{
if (d.exists())
d.remove(true);
});
}

} }

+ 49
- 0
include/asyncpp/fs/directory/create.inl View File

@@ -0,0 +1,49 @@
#pragma once

#include <asyncpp/core/future/future.h>

#include "directory.h"

namespace asyncpp {
namespace fs {
namespace __directory {

template<
chaining_mode X_mode,
typename X_self>
inline auto create_impl(X_self&& p_self)
{
return lazy([self = std::forward<X_self>(p_self)] {
if (!self.handle.exists())
self.handle.create(false);

return self; // TODO: use std::forward
});
}

} } }

namespace asyncpp {
namespace fs {

/* directory::create */

template<chaining_mode X_mode>
auto directory
::create() &
{
return __directory::create_impl<X_mode>(*this);
}

template<chaining_mode X_mode>
auto directory
::create() &&
{
static_assert(
X_mode != ref,
"Can not store rvalue reference as lvalue reference!");

return __directory::create_impl<X_mode>(std::move(*this));
}

} }

+ 49
- 0
include/asyncpp/fs/directory/create_all.inl View File

@@ -0,0 +1,49 @@
#pragma once

#include <asyncpp/core/future/future.h>

#include "directory.h"

namespace asyncpp {
namespace fs {
namespace __directory {

template<
chaining_mode X_mode,
typename X_self>
inline auto create_all_impl(X_self&& p_self)
{
return lazy([self = std::forward<X_self>(p_self)] {
if (!self.handle.exists())
self.handle.create(true);

return self; // TODO: use std::forward
});
}

} } }

namespace asyncpp {
namespace fs {

/* directory::create */

template<chaining_mode X_mode>
auto directory
::create_all() &
{
return __directory::create_all_impl<X_mode>(*this);
}

template<chaining_mode X_mode>
auto directory
::create_all() &&
{
static_assert(
X_mode != ref,
"Can not store rvalue reference as lvalue reference!");

return __directory::create_all_impl<X_mode>(std::move(*this));
}

} }

+ 100
- 0
include/asyncpp/fs/directory/directory.h View File

@@ -0,0 +1,100 @@
#pragma once

#include <cppfs/directory.h>

#include <asyncpp/core/misc/chaining.h>

namespace asyncpp {
namespace fs {

struct directory
{
public:
cppfs::directory handle;

public:
/**
* @brief Constructor.
*/
inline directory(const cppfs::path& p_path);

public:
/**
* @brief Create a new future to create a directory.
*/
template<chaining_mode X_mode = copy>
inline auto create() &;

/**
* @brief Create a new future to create a directory.
*/
template<chaining_mode X_mode = move>
inline auto create() &&;

public:
/**
* @brief Create a new future to create a directory and all it's parent directories.
*/
template<chaining_mode X_mode = copy>
inline auto create_all() &;

/**
* @brief Create a new future to create a directory and all it's parent directories.
*/
template<chaining_mode X_mode = move>
inline auto create_all() &&;

public:
/**
* @brief Create future to read the content of a directory.
*/
template<chaining_mode X_mode = copy>
inline auto read() &;

/**
* @brief Create future to read the content of a directory.
*/
template<chaining_mode X_mode = move>
inline auto read() &&;

public:
/**
* @brief Create future to read the content of a directory including the subdirectories.
*/
template<chaining_mode X_mode = copy>
inline auto read_all() &;

/**
* @brief Create future to read the content of a directory including the subdirectories.
*/
template<chaining_mode X_mode = move>
inline auto read_all() &&;

public:
/**
* @brief Create a new future to remove an empty directory.
*/
template<chaining_mode X_mode = copy>
inline auto remove() &;

/**
* @brief Create a new future to remove an empty directory.
*/
template<chaining_mode X_mode = move>
inline auto remove() &&;

public:
/**
* @brief Create a new future to remove a directory and all it's content.
*/
template<chaining_mode X_mode = copy>
inline auto remove_all() &;

/**
* @brief Create a new future to remove a directory and all it's content.
*/
template<chaining_mode X_mode = move>
inline auto remove_all() &&;
};

} }

+ 14
- 0
include/asyncpp/fs/directory/directory.inl View File

@@ -0,0 +1,14 @@
#pragma once

#include "directory.h"

namespace asyncpp {
namespace fs {

/* directory */

inline directory::directory(const cppfs::path& p_path)
: handle(p_path)
{ }

} }

+ 80
- 0
include/asyncpp/fs/directory/read.inl View File

@@ -0,0 +1,80 @@
#pragma once

#include <cppfs/directory.h>

#include "directory.h"

namespace asyncpp {
namespace fs {
namespace __directory {

struct read_stream
: public base_stream<
cppfs::directory::entry,
read_stream>
{
public:
using value_type = cppfs::directory::entry;
using this_type = read_stream;
using base_future_type = base_stream<value_type, this_type>;
using result_type = typename base_future_type::result_type;

private:
cppfs::directory::iterator _it;
cppfs::directory::iterator _end;

public:
inline read_stream(
const fs::directory& p_directory)
{
auto& d = p_directory.handle;
if (d.exists())
{
_it = d.begin();
_end = d.end();
}
}

public:
inline result_type poll()
{
if (_it == _end)
return result_type::done();

auto ret = result_type::ready(*_it);
++_it;

return ret;
}
};

template<
chaining_mode X_mode,
typename X_self>
inline auto read_impl(X_self&& p_self)
{ return read_stream(std::forward<X_self>(p_self)); }

} } }

namespace asyncpp {
namespace fs {

template<chaining_mode X_mode>
auto directory
::read() &
{
return __directory::read_impl<X_mode>(*this);
}

template<chaining_mode X_mode>
auto directory
::read() &&
{
static_assert(
X_mode != ref,
"Can not store rvalue reference as lvalue reference!");

return __directory::read_impl<X_mode>(std::move(*this));
}

} }

+ 111
- 0
include/asyncpp/fs/directory/read_all.inl View File

@@ -0,0 +1,111 @@
#pragma once

#include <vector>

#include <cppfs/directory.h>

#include "directory.h"

namespace asyncpp {
namespace fs {
namespace __directory {

struct read_all_stream
: public base_stream<
cppfs::directory::entry,
read_all_stream>
{
public:
using value_type = cppfs::directory::entry;
using this_type = read_all_stream;
using base_future_type = base_stream<value_type, this_type>;
using result_type = typename base_future_type::result_type;

private:
struct entry
{
cppfs::directory::iterator it;
cppfs::directory::iterator end;
};

using entry_stack = std::vector<entry>;

entry_stack _stack;

public:
inline read_all_stream(
const fs::directory& p_directory)
{
auto& d = p_directory.handle;
if (d.exists())
{
_stack.emplace_back(entry {
d.begin(),
d.end()
});
}
}

public:
inline result_type poll()
{
while (true)
{
if (_stack.empty())
return result_type::done();

auto& e = _stack.back();
if (e.it == e.end)
{
_stack.pop_back();
continue;
}

auto ret = result_type::ready(std::move(*e.it));
cppfs::directory d(e.it->path);

++e.it;

if (d.exists())
{
_stack.emplace_back(entry {
d.begin(),
d.end(),
});
}

return ret;
}
}
};

template<
chaining_mode X_mode,
typename X_self>
inline auto read_all_impl(X_self&& p_self)
{ return read_all_stream(std::forward<X_self>(p_self)); }

} } }

namespace asyncpp {
namespace fs {

template<chaining_mode X_mode>
auto directory
::read_all() &
{
return __directory::read_all_impl<X_mode>(*this);
}

template<chaining_mode X_mode>
auto directory
::read_all() &&
{
static_assert(
X_mode != ref,
"Can not store rvalue reference as lvalue reference!");

return __directory::read_all_impl<X_mode>(std::move(*this));
}

} }

+ 49
- 0
include/asyncpp/fs/directory/remove.inl View File

@@ -0,0 +1,49 @@
#pragma once

#include <asyncpp/core/future/future.h>

#include "directory.h"

namespace asyncpp {
namespace fs {
namespace __directory {

template<
chaining_mode X_mode,
typename X_self>
inline auto remove_impl(X_self&& p_self)
{
return lazy([self = std::forward<X_self>(p_self)] {
if (self.handle.exists())
self.handle.remove(false);

return self; // TODO: use std::forward
});
}

} } }

namespace asyncpp {
namespace fs {

/* directory::remove */

template<chaining_mode X_mode>
auto directory
::remove() &
{
return __directory::remove_impl<X_mode>(*this);
}

template<chaining_mode X_mode>
auto directory
::remove() &&
{
static_assert(
X_mode != ref,
"Can not store rvalue reference as lvalue reference!");

return __directory::remove_impl<X_mode>(std::move(*this));
}

} }

+ 49
- 0
include/asyncpp/fs/directory/remove_all.inl View File

@@ -0,0 +1,49 @@
#pragma once

#include <asyncpp/core/future/future.h>

#include "directory.h"

namespace asyncpp {
namespace fs {
namespace __directory {

template<
chaining_mode X_mode,
typename X_self>
inline auto remove_all_impl(X_self&& p_self)
{
return lazy([self = std::forward<X_self>(p_self)] {
if (self.handle.exists())
self.handle.remove(true);

return self; // TODO: use std::forward
});
}

} } }

namespace asyncpp {
namespace fs {

/* directory::create */

template<chaining_mode X_mode>
auto directory
::remove_all() &
{
return __directory::remove_all_impl<X_mode>(*this);
}

template<chaining_mode X_mode>
auto directory
::remove_all() &&
{
static_assert(
X_mode != ref,
"Can not store rvalue reference as lvalue reference!");

return __directory::remove_all_impl<X_mode>(std::move(*this));
}

} }

+ 1
- 1
include/asyncpp/timing.h View File

@@ -1,6 +1,6 @@
#pragma once

#define ASYNCPP_FEATURE_TIMING_ENABLED
#define ASYNCPP_ENABLE_FEATURE_TIMING

#include "timing/delay.h"
#include "timing/interval.h"


+ 10
- 22
test/asyncpp/fs/directory_tests.cpp View File

@@ -67,7 +67,7 @@ TEST_F(directory_tests, read_dir)
using namespace cppfs;
using namespace std::string_literals;

auto s = fs::read_dir("."s);
auto s = fs::directory("."s).read();
auto v = std::vector<std::string>();
auto r = decltype(s)::result_type::not_ready();

@@ -89,7 +89,7 @@ TEST_F(directory_tests, read_dir_all)
using namespace cppfs;
using namespace std::string_literals;

auto s = fs::read_dir_all("."s);
auto s = fs::directory("."s).read_all();
auto r = decltype(s)::result_type::not_ready();

auto entries = std::vector<cppfs::directory::entry>();
@@ -137,11 +137,8 @@ TEST_F(directory_tests, read_dir_all)

TEST_F(directory_tests, create_dir)
{
auto f =
lazy([path=path_test_dir_single()]{
return path;
})
.and_then(fs::create_dir);
auto f = fs::directory(path_test_dir_single())
.create();

auto_remove_dir d(path_test_dir_single());

@@ -155,11 +152,8 @@ TEST_F(directory_tests, create_dir)

TEST_F(directory_tests, create_dir_all)
{
auto f =
lazy([path=path_test_dir_child()]{
return path;
})
.and_then(fs::create_dir_all);
auto f = fs::directory(path_test_dir_child())
.create_all();

auto_remove_dir d(path_test_dir_child());

@@ -173,11 +167,8 @@ TEST_F(directory_tests, create_dir_all)

TEST_F(directory_tests, remove_dir)
{
auto f =
lazy([path=path_test_dir_single()]{
return path;
})
.and_then(fs::remove_dir);
auto f = fs::directory(path_test_dir_single())
.remove();

auto_remove_dir d(path_test_dir_single());
d.create(true);
@@ -192,11 +183,8 @@ TEST_F(directory_tests, remove_dir)

TEST_F(directory_tests, remove_dir_all)
{
auto f =
lazy([path=path_test_dir_parent()]{
return path;
})
.and_then(fs::remove_dir_all);
auto f = fs::directory(path_test_dir_child())
.remove_all();

auto_remove_dir d(path_test_dir_child());
d.create(true);


Loading…
Cancel
Save