@@ -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 ) |
@@ -1,3 +1,4 @@ | |||
#pragma once | |||
#cmakedefine ASYNCPP_FEATURE_TIMING_ENABLED | |||
#cmakedefine ASYNCPP_ENABLE_FEATURE_FS | |||
#cmakedefine ASYNCPP_ENABLE_FEATURE_TIMING |
@@ -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 |
@@ -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 |
@@ -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. | |||
@@ -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 |
@@ -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. | |||
@@ -1,5 +1,3 @@ | |||
#pragma once | |||
#include "fs/directory.h" | |||
#include "fs/directory.inl" |
@@ -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" |
@@ -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); | |||
}); | |||
} | |||
} } |
@@ -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)); | |||
} | |||
} } |
@@ -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)); | |||
} | |||
} } |
@@ -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() &&; | |||
}; | |||
} } |
@@ -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) | |||
{ } | |||
} } |
@@ -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)); | |||
} | |||
} } |
@@ -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)); | |||
} | |||
} } |
@@ -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)); | |||
} | |||
} } |
@@ -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,6 +1,6 @@ | |||
#pragma once | |||
#define ASYNCPP_FEATURE_TIMING_ENABLED | |||
#define ASYNCPP_ENABLE_FEATURE_TIMING | |||
#include "timing/delay.h" | |||
#include "timing/interval.h" | |||
@@ -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); | |||