doc cleanups
parent
220f9ee374
commit
09c3c02c33
|
@ -435,7 +435,7 @@ LOOKUP_CACHE_SIZE = 0
|
||||||
# normally produced when WARNINGS is set to YES.
|
# normally produced when WARNINGS is set to YES.
|
||||||
# The default value is: NO.
|
# The default value is: NO.
|
||||||
|
|
||||||
EXTRACT_ALL = YES
|
EXTRACT_ALL = NO
|
||||||
|
|
||||||
# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
|
# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
|
||||||
# be included in the documentation.
|
# be included in the documentation.
|
||||||
|
|
|
@ -32,7 +32,7 @@ namespace ostd {
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** Thrown when manipulating a channel that has been closed. */
|
/** @brief Thrown when manipulating a channel that has been closed. */
|
||||||
struct channel_error: std::logic_error {
|
struct channel_error: std::logic_error {
|
||||||
using std::logic_error::logic_error;
|
using std::logic_error::logic_error;
|
||||||
};
|
};
|
||||||
|
@ -48,6 +48,12 @@ struct channel_error: std::logic_error {
|
||||||
* state is freed as soon as the last channel instance referencing it is
|
* state is freed as soon as the last channel instance referencing it is
|
||||||
* destroyed.
|
* destroyed.
|
||||||
*
|
*
|
||||||
|
* Channels are move constructible. Moving a channel transfers the state
|
||||||
|
* into another channel and leaves the original state in an unusable
|
||||||
|
* state, with no reference count change. Copying a channel increases
|
||||||
|
* the reference count, so both instances point to the ssame state and
|
||||||
|
* both are valid.
|
||||||
|
*
|
||||||
* @tparam T The type of the values in the queue.
|
* @tparam T The type of the values in the queue.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -80,34 +86,9 @@ struct channel {
|
||||||
template<typename F>
|
template<typename F>
|
||||||
channel(F func): p_state(new impl{func}) {}
|
channel(F func): p_state(new impl{func}) {}
|
||||||
|
|
||||||
/** @brief Creates a new reference to the channel.
|
|
||||||
*
|
|
||||||
* This does not copy per se, as channels store a refcounted internal
|
|
||||||
* state. It increments the reference count on the state and creates
|
|
||||||
* a new channel instance that references this state.
|
|
||||||
*
|
|
||||||
* If you don't want to increment and instead you want to transfer the
|
|
||||||
* reference to a new instance, use channel(channel &&).
|
|
||||||
*
|
|
||||||
* @see channel(channel &&), operator=(channel const &)
|
|
||||||
*/
|
|
||||||
channel(channel const &) = default;
|
channel(channel const &) = default;
|
||||||
|
|
||||||
/** @brief Moves the internal state reference to a new channel instance.
|
|
||||||
*
|
|
||||||
* This is like channel(channel const &) except it does not increment
|
|
||||||
* the reference; it moves the reference to a new container instead,
|
|
||||||
* leaving the other one uninitialized. You cannot use the channel
|
|
||||||
* the reference was moved from anymore afterwards.
|
|
||||||
*
|
|
||||||
* @see channel(channel const &), operator=(channel &&)
|
|
||||||
*/
|
|
||||||
channel(channel &&) = default;
|
channel(channel &&) = default;
|
||||||
|
|
||||||
/** @see channel(channel const &) */
|
|
||||||
channel &operator=(channel const &) = default;
|
channel &operator=(channel const &) = default;
|
||||||
|
|
||||||
/** @see channel(channel &&) */
|
|
||||||
channel &operator=(channel &&) = default;
|
channel &operator=(channel &&) = default;
|
||||||
|
|
||||||
/** @brief Inserts a copy of a value into the queue.
|
/** @brief Inserts a copy of a value into the queue.
|
||||||
|
@ -205,7 +186,7 @@ struct channel {
|
||||||
return p_state->closed();
|
return p_state->closed();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Closes the channel. No effect if already closed. */
|
/** @brief Closes the channel. No effect if already closed. */
|
||||||
void close() noexcept {
|
void close() noexcept {
|
||||||
p_state->close();
|
p_state->close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,23 +97,16 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Does nothing, this base class is empty. */
|
/** @brief Does nothing, this base class is empty. */
|
||||||
scheduler() {}
|
scheduler() {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Does nothing, this base class is empty. */
|
/** @brief Does nothing, this base class is empty. */
|
||||||
virtual ~scheduler() {}
|
virtual ~scheduler() {}
|
||||||
|
|
||||||
/** A scheduler is not copy constructible. */
|
|
||||||
scheduler(scheduler const &) = delete;
|
scheduler(scheduler const &) = delete;
|
||||||
|
|
||||||
/** A scheduler is not move constructible. */
|
|
||||||
scheduler(scheduler &&) = delete;
|
scheduler(scheduler &&) = delete;
|
||||||
|
|
||||||
/** A scheduler is not copy assignable. */
|
|
||||||
scheduler &operator=(scheduler const &) = delete;
|
scheduler &operator=(scheduler const &) = delete;
|
||||||
|
|
||||||
/** A scheduler is not move assignable. */
|
|
||||||
scheduler &operator=(scheduler &&) = delete;
|
scheduler &operator=(scheduler &&) = delete;
|
||||||
|
|
||||||
/** @brief Spawns a task.
|
/** @brief Spawns a task.
|
||||||
|
@ -128,7 +121,7 @@ public:
|
||||||
|
|
||||||
/** @brief Tells the scheduler to re-schedule the current task.
|
/** @brief Tells the scheduler to re-schedule the current task.
|
||||||
*
|
*
|
||||||
* In #ostd::thread_scheduler, this is just a hint, as it uses OS threading
|
* In ostd::thread_scheduler, this is just a hint, as it uses OS threading
|
||||||
* facilities. In coroutine based schedulers, this will typically suspend
|
* facilities. In coroutine based schedulers, this will typically suspend
|
||||||
* the currently running task and re-schedule it for later.
|
* the currently running task and re-schedule it for later.
|
||||||
*
|
*
|
||||||
|
@ -136,7 +129,7 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual void yield() noexcept = 0;
|
virtual void yield() noexcept = 0;
|
||||||
|
|
||||||
/** @brief Creates a condition variable using #ostd::generic_condvar.
|
/** @brief Creates a condition variable using ostd::generic_condvar.
|
||||||
*
|
*
|
||||||
* A scheduler might be using a custom condition variable type depending
|
* A scheduler might be using a custom condition variable type depending
|
||||||
* on how its tasks are implemented. Other data structures might want to
|
* on how its tasks are implemented. Other data structures might want to
|
||||||
|
@ -292,7 +285,10 @@ namespace detail {
|
||||||
*/
|
*/
|
||||||
template<typename SA>
|
template<typename SA>
|
||||||
struct basic_thread_scheduler: scheduler {
|
struct basic_thread_scheduler: scheduler {
|
||||||
/* @brief Creates the scheduler.
|
/** @brief The stack allocator type. */
|
||||||
|
using allocator_type = SA;
|
||||||
|
|
||||||
|
/** @brief Creates the scheduler.
|
||||||
*
|
*
|
||||||
* @param[in] sa The provided stack allocator.
|
* @param[in] sa The provided stack allocator.
|
||||||
*/
|
*/
|
||||||
|
@ -393,7 +389,7 @@ private:
|
||||||
std::mutex p_lock;
|
std::mutex p_lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** An #ostd::basic_thread_scheduler using #ostd::stack_pool. */
|
/** @brief An ostd::basic_thread_scheduler using ostd::stack_pool. */
|
||||||
using thread_scheduler = basic_thread_scheduler<stack_pool>;
|
using thread_scheduler = basic_thread_scheduler<stack_pool>;
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
@ -464,6 +460,9 @@ namespace detail {
|
||||||
*/
|
*/
|
||||||
template<typename SA>
|
template<typename SA>
|
||||||
struct basic_simple_coroutine_scheduler: scheduler {
|
struct basic_simple_coroutine_scheduler: scheduler {
|
||||||
|
/** @brief The stack allocator type. */
|
||||||
|
using allocator_type = SA;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/* simple one just for channels */
|
/* simple one just for channels */
|
||||||
struct coro_cond {
|
struct coro_cond {
|
||||||
|
@ -620,7 +619,7 @@ private:
|
||||||
typename std::list<detail::csched_task>::iterator p_idx = p_coros.end();
|
typename std::list<detail::csched_task>::iterator p_idx = p_coros.end();
|
||||||
};
|
};
|
||||||
|
|
||||||
/** An #ostd::basic_simple_coroutine_scheduler using #ostd::stack_pool. */
|
/** @brief An ostd::basic_simple_coroutine_scheduler using ostd::stack_pool. */
|
||||||
using simple_coroutine_scheduler = basic_simple_coroutine_scheduler<stack_pool>;
|
using simple_coroutine_scheduler = basic_simple_coroutine_scheduler<stack_pool>;
|
||||||
|
|
||||||
/** @brief A scheduler that uses a coroutine type for tasks on several threads.
|
/** @brief A scheduler that uses a coroutine type for tasks on several threads.
|
||||||
|
@ -636,6 +635,9 @@ using simple_coroutine_scheduler = basic_simple_coroutine_scheduler<stack_pool>;
|
||||||
*/
|
*/
|
||||||
template<typename SA>
|
template<typename SA>
|
||||||
struct basic_coroutine_scheduler: scheduler {
|
struct basic_coroutine_scheduler: scheduler {
|
||||||
|
/** @brief The stack allocator type. */
|
||||||
|
using allocator_type = SA;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct task_cond;
|
struct task_cond;
|
||||||
struct task;
|
struct task;
|
||||||
|
@ -961,7 +963,7 @@ private:
|
||||||
tlist p_running;
|
tlist p_running;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** An #ostd::basic_coroutine_scheduler using #ostd::stack_pool. */
|
/** @brief An ostd::basic_coroutine_scheduler using ostd::stack_pool. */
|
||||||
using coroutine_scheduler = basic_coroutine_scheduler<stack_pool>;
|
using coroutine_scheduler = basic_coroutine_scheduler<stack_pool>;
|
||||||
|
|
||||||
/** @brief Spawns a task on the currently in use scheduler.
|
/** @brief Spawns a task on the currently in use scheduler.
|
||||||
|
|
|
@ -99,7 +99,7 @@ struct coroutine_context {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Does nothing, just default-initializes the members. */
|
/** @brief Does nothing, just default-initializes the members. */
|
||||||
coroutine_context() {}
|
coroutine_context() {}
|
||||||
|
|
||||||
/** @brief Unwinds the stack and frees it.
|
/** @brief Unwinds the stack and frees it.
|
||||||
|
@ -115,7 +115,6 @@ protected:
|
||||||
free_stack();
|
free_stack();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Coroutine contexts are not copy constructible. */
|
|
||||||
coroutine_context(coroutine_context const &) = delete;
|
coroutine_context(coroutine_context const &) = delete;
|
||||||
|
|
||||||
/** @brief Moves the given context into this one.
|
/** @brief Moves the given context into this one.
|
||||||
|
@ -134,7 +133,6 @@ protected:
|
||||||
c.set_dead();
|
c.set_dead();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Coroutine contexts are not copy assignable. */
|
|
||||||
coroutine_context &operator=(coroutine_context const &) = delete;
|
coroutine_context &operator=(coroutine_context const &) = delete;
|
||||||
|
|
||||||
/** @brief Moves the given context into this one.
|
/** @brief Moves the given context into this one.
|
||||||
|
@ -203,22 +201,22 @@ protected:
|
||||||
p_orig = detail::ostd_jump_fcontext(p_orig, nullptr).ctx;
|
p_orig = detail::ostd_jump_fcontext(p_orig, nullptr).ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Checks if the coroutine is suspended. */
|
/** @brief Checks if the coroutine is suspended. */
|
||||||
bool is_hold() const {
|
bool is_hold() const {
|
||||||
return (p_state == state::HOLD);
|
return (p_state == state::HOLD);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Checks if the coroutine is dead. */
|
/** @brief Checks if the coroutine is dead. */
|
||||||
bool is_dead() const {
|
bool is_dead() const {
|
||||||
return (p_state == state::TERM);
|
return (p_state == state::TERM);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Marks the coroutine as dead. Only valid without an active context. */
|
/** @brief Marks the coroutine as dead. Only valid without an active context. */
|
||||||
void set_dead() {
|
void set_dead() {
|
||||||
p_state = state::TERM;
|
p_state = state::TERM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Marks the coroutine as executing. Only valid before coro_jump(). */
|
/** @brief Marks the coroutine as executing. Only valid before coro_jump(). */
|
||||||
void set_exec() {
|
void set_exec() {
|
||||||
p_state = state::EXEC;
|
p_state = state::EXEC;
|
||||||
}
|
}
|
||||||
|
@ -235,7 +233,7 @@ protected:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Swaps the current context with another. */
|
/** @brief Swaps the current context with another. */
|
||||||
void swap(coroutine_context &other) noexcept {
|
void swap(coroutine_context &other) noexcept {
|
||||||
using std::swap;
|
using std::swap;
|
||||||
swap(p_stack, other.p_stack);
|
swap(p_stack, other.p_stack);
|
||||||
|
@ -725,10 +723,9 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** The yielder type for the coroutine. Not opaque, but internal. */
|
/** @brief The yielder type for the coroutine. Not opaque, but internal. */
|
||||||
using yield_type = yielder<R, A...>;
|
using yield_type = yielder<R, A...>;
|
||||||
|
|
||||||
/** Coroutines are not default constructible. */
|
|
||||||
coroutine() = delete;
|
coroutine() = delete;
|
||||||
|
|
||||||
/** @brief Creates a coroutine using the given function.
|
/** @brief Creates a coroutine using the given function.
|
||||||
|
@ -763,7 +760,6 @@ public:
|
||||||
this->set_dead();
|
this->set_dead();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Coroutines are not copy constructible. */
|
|
||||||
coroutine(coroutine const &) = delete;
|
coroutine(coroutine const &) = delete;
|
||||||
|
|
||||||
/** @brief Moves a coroutine.
|
/** @brief Moves a coroutine.
|
||||||
|
@ -779,7 +775,6 @@ public:
|
||||||
c.p_stor.p_func = nullptr;
|
c.p_stor.p_func = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Coroutines are not copy assignable. */
|
|
||||||
coroutine &operator=(coroutine const &) = delete;
|
coroutine &operator=(coroutine const &) = delete;
|
||||||
|
|
||||||
/** @brief Moves a coroutine.
|
/** @brief Moves a coroutine.
|
||||||
|
@ -791,7 +786,7 @@ public:
|
||||||
p_stor.swap(c.p_stor);
|
p_stor.swap(c.p_stor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Checks if the coroutine is alive, returning `true` if it is. */
|
/** @brief Checks if the coroutine is alive. */
|
||||||
explicit operator bool() const noexcept {
|
explicit operator bool() const noexcept {
|
||||||
return !this->is_dead();
|
return !this->is_dead();
|
||||||
}
|
}
|
||||||
|
@ -833,13 +828,13 @@ public:
|
||||||
return p_stor.get_result();
|
return p_stor.get_result();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Swaps two coroutines' states. */
|
/** @brief Swaps two coroutines' states. */
|
||||||
void swap(coroutine &other) noexcept {
|
void swap(coroutine &other) noexcept {
|
||||||
p_stor.swap(other.p_stor);
|
p_stor.swap(other.p_stor);
|
||||||
base_t::swap(other);
|
base_t::swap(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the RTTI of the function stored in the coroutine. */
|
/** @brief Returns the RTTI of the function stored in the coroutine. */
|
||||||
std::type_info const &target_type() const {
|
std::type_info const &target_type() const {
|
||||||
return p_stor.p_func.target_type();
|
return p_stor.p_func.target_type();
|
||||||
}
|
}
|
||||||
|
@ -868,7 +863,7 @@ private:
|
||||||
detail::coro_stor<yield_type, R, A...> p_stor;
|
detail::coro_stor<yield_type, R, A...> p_stor;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Swaps two coroutines' states. */
|
/** @brief Swaps two coroutines' states. */
|
||||||
template<typename R, typename ...A>
|
template<typename R, typename ...A>
|
||||||
inline void swap(coroutine<R(A...)> &a, coroutine<R(A...)> &b) noexcept {
|
inline void swap(coroutine<R(A...)> &a, coroutine<R(A...)> &b) noexcept {
|
||||||
a.swap(b);
|
a.swap(b);
|
||||||
|
@ -970,13 +965,12 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** As generators can be used with ranges, this is defined. */
|
/** @brief As generators can be used with ranges, this is defined. */
|
||||||
using range = generator_range<T>;
|
using range = generator_range<T>;
|
||||||
|
|
||||||
/** The yielder type for the generator. Not opaque, but internal. */
|
/** @brief The yielder type for the generator. Not opaque, but internal. */
|
||||||
using yield_type = yielder<T>;
|
using yield_type = yielder<T>;
|
||||||
|
|
||||||
/** Generators are not default constructible. */
|
|
||||||
generator() = delete;
|
generator() = delete;
|
||||||
|
|
||||||
/** @brief Creates a generator using the given function.
|
/** @brief Creates a generator using the given function.
|
||||||
|
@ -1018,7 +1012,6 @@ public:
|
||||||
this->set_dead();
|
this->set_dead();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Generators are not copy constructible. */
|
|
||||||
generator(generator const &) = delete;
|
generator(generator const &) = delete;
|
||||||
|
|
||||||
/** @brief Moves a generator.
|
/** @brief Moves a generator.
|
||||||
|
@ -1035,7 +1028,6 @@ public:
|
||||||
c.p_result = nullptr;
|
c.p_result = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Generators are not copy assignable. */
|
|
||||||
generator &operator=(generator const &) = delete;
|
generator &operator=(generator const &) = delete;
|
||||||
|
|
||||||
/** @brief Moves a generator.
|
/** @brief Moves a generator.
|
||||||
|
@ -1050,7 +1042,7 @@ public:
|
||||||
c.p_result = nullptr;
|
c.p_result = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Checks if the generator is alive, returning `true` if it is. */
|
/** @brief Checks if the generator is alive. */
|
||||||
explicit operator bool() const noexcept {
|
explicit operator bool() const noexcept {
|
||||||
return !this->is_dead();
|
return !this->is_dead();
|
||||||
}
|
}
|
||||||
|
@ -1100,7 +1092,7 @@ public:
|
||||||
return *p_result;
|
return *p_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Checks if the generator is has a value, returning `false` if it does. */
|
/** @brief Checks if the generator has no value. */
|
||||||
bool empty() const noexcept {
|
bool empty() const noexcept {
|
||||||
return !p_result;
|
return !p_result;
|
||||||
}
|
}
|
||||||
|
@ -1113,19 +1105,19 @@ public:
|
||||||
*/
|
*/
|
||||||
generator_range<T> iter() noexcept;
|
generator_range<T> iter() noexcept;
|
||||||
|
|
||||||
/** Implements a minimal iterator just for range-based for loop.
|
/** @brief Implements a minimal iterator just for range-based for loop.
|
||||||
* Do not use directly.
|
* Do not use directly.
|
||||||
*/
|
*/
|
||||||
detail::generator_iterator<T> begin() noexcept;
|
detail::generator_iterator<T> begin() noexcept;
|
||||||
|
|
||||||
/** Implements a minimal iterator just for range-based for loop.
|
/** @brief Implements a minimal iterator just for range-based for loop.
|
||||||
* Do not use directly.
|
* Do not use directly.
|
||||||
*/
|
*/
|
||||||
std::nullptr_t end() noexcept {
|
std::nullptr_t end() noexcept {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Swaps two generators' states. */
|
/** @brief Swaps two generators' states. */
|
||||||
void swap(generator &other) noexcept {
|
void swap(generator &other) noexcept {
|
||||||
using std::swap;
|
using std::swap;
|
||||||
swap(p_func, other.p_func);
|
swap(p_func, other.p_func);
|
||||||
|
@ -1133,7 +1125,7 @@ public:
|
||||||
coroutine_context::swap(other);
|
coroutine_context::swap(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the RTTI of the function stored in the generator. */
|
/** @brief Returns the RTTI of the function stored in the generator. */
|
||||||
std::type_info const &target_type() const {
|
std::type_info const &target_type() const {
|
||||||
return p_func.target_type();
|
return p_func.target_type();
|
||||||
}
|
}
|
||||||
|
@ -1168,7 +1160,7 @@ private:
|
||||||
std::remove_reference_t<T> *p_result = nullptr;
|
std::remove_reference_t<T> *p_result = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Swaps two generators' states. */
|
/** @brief Swaps two generators' states. */
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline void swap(generator<T> &a, generator<T> &b) noexcept {
|
inline void swap(generator<T> &a, generator<T> &b) noexcept {
|
||||||
a.swap(b);
|
a.swap(b);
|
||||||
|
@ -1207,34 +1199,33 @@ struct generator_range: input_range<generator_range<T>> {
|
||||||
using size_type = std::size_t;
|
using size_type = std::size_t;
|
||||||
using difference_type = std::ptrdiff_t;
|
using difference_type = std::ptrdiff_t;
|
||||||
|
|
||||||
/** Generator ranges are not default constructible. */
|
|
||||||
generator_range() = delete;
|
generator_range() = delete;
|
||||||
|
|
||||||
/** Generator ranges are constructed using a reference to a generator. */
|
/** @brief Generator ranges are constructed using a generator reference. */
|
||||||
generator_range(generator<T> &g): p_gen(&g) {}
|
generator_range(generator<T> &g): p_gen(&g) {}
|
||||||
|
|
||||||
/** Like ostd::generator<T>::empty(). */
|
/** @brief Like ostd::generator<T>::empty(). */
|
||||||
bool empty() const noexcept {
|
bool empty() const noexcept {
|
||||||
return p_gen->empty();
|
return p_gen->empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Like ostd::generator<T>::resume(). */
|
/** @brief Like ostd::generator<T>::resume(). */
|
||||||
void pop_front() {
|
void pop_front() {
|
||||||
p_gen->resume();
|
p_gen->resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Like ostd::generator<T>::value(). */
|
/** @brief Like ostd::generator<T>::value(). */
|
||||||
reference front() const {
|
reference front() const {
|
||||||
return p_gen->value();
|
return p_gen->value();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Implements a minimal iterator just for range-based for loop.
|
/** @brief Implements a minimal iterator just for range-based for loop.
|
||||||
* Do not use directly.
|
* Do not use directly.
|
||||||
*/
|
*/
|
||||||
detail::generator_iterator<T> begin() noexcept;
|
detail::generator_iterator<T> begin() noexcept;
|
||||||
|
|
||||||
/** Implements a minimal iterator just for range-based for loop.
|
/** @brief Implements a minimal iterator just for range-based for loop.
|
||||||
* Do not use directly.
|
* Do not use directly.
|
||||||
*/
|
*/
|
||||||
std::nullptr_t end() noexcept {
|
std::nullptr_t end() noexcept {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -65,7 +65,7 @@ namespace detail {
|
||||||
* space is the size of that).
|
* space is the size of that).
|
||||||
*/
|
*/
|
||||||
struct generic_condvar {
|
struct generic_condvar {
|
||||||
/** Constructs the condvar using std::condition_variable. */
|
/** @brief Constructs the condvar using std::condition_variable. */
|
||||||
generic_condvar() {
|
generic_condvar() {
|
||||||
new (reinterpret_cast<void *>(&p_condbuf))
|
new (reinterpret_cast<void *>(&p_condbuf))
|
||||||
detail::cond_impl<std::condition_variable>();
|
detail::cond_impl<std::condition_variable>();
|
||||||
|
@ -86,19 +86,12 @@ struct generic_condvar {
|
||||||
detail::cond_impl<std::result_of_t<F()>>(func);
|
detail::cond_impl<std::result_of_t<F()>>(func);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Condvars are not copy constructible. */
|
|
||||||
generic_condvar(generic_condvar const &) = delete;
|
generic_condvar(generic_condvar const &) = delete;
|
||||||
|
|
||||||
/** Condvars are not move constructible. */
|
|
||||||
generic_condvar(generic_condvar &&) = delete;
|
generic_condvar(generic_condvar &&) = delete;
|
||||||
|
|
||||||
/** Condvars are not copy assignable. */
|
|
||||||
generic_condvar &operator=(generic_condvar const &) = delete;
|
generic_condvar &operator=(generic_condvar const &) = delete;
|
||||||
|
|
||||||
/** Condvars are not move assignable. */
|
|
||||||
generic_condvar &operator=(generic_condvar &&) = delete;
|
generic_condvar &operator=(generic_condvar &&) = delete;
|
||||||
|
|
||||||
/** Destroys the stored condvar. */
|
/** @brief Destroys the stored condvar. */
|
||||||
~generic_condvar() {
|
~generic_condvar() {
|
||||||
reinterpret_cast<detail::cond_iface *>(&p_condbuf)->~cond_iface();
|
reinterpret_cast<detail::cond_iface *>(&p_condbuf)->~cond_iface();
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,6 @@ struct OSTD_EXPORT file_stream: stream {
|
||||||
*/
|
*/
|
||||||
file_stream(): p_f(), p_owned(false) {}
|
file_stream(): p_f(), p_owned(false) {}
|
||||||
|
|
||||||
/** @brief File streams are not copy constructible. */
|
|
||||||
file_stream(file_stream const &) = delete;
|
file_stream(file_stream const &) = delete;
|
||||||
|
|
||||||
/** @brief Creates a file stream by moving.
|
/** @brief Creates a file stream by moving.
|
||||||
|
@ -107,7 +106,6 @@ struct OSTD_EXPORT file_stream: stream {
|
||||||
/** @brief Calls close() on the stream. */
|
/** @brief Calls close() on the stream. */
|
||||||
~file_stream() { close(); }
|
~file_stream() { close(); }
|
||||||
|
|
||||||
/** @brief File streams are not copy assignable. */
|
|
||||||
file_stream &operator=(file_stream const &) = delete;
|
file_stream &operator=(file_stream const &) = delete;
|
||||||
|
|
||||||
/** @brief Assigns another stream to this one by move.
|
/** @brief Assigns another stream to this one by move.
|
||||||
|
|
|
@ -231,7 +231,7 @@ namespace ostd {
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(OSTD_TOOLCHAIN_GNU)
|
#if defined(OSTD_TOOLCHAIN_GNU) && !defined(OSTD_GENERATING_DOC)
|
||||||
|
|
||||||
/* using gcc/clang builtins */
|
/* using gcc/clang builtins */
|
||||||
inline std::uint16_t endian_swap16(std::uint16_t x) noexcept {
|
inline std::uint16_t endian_swap16(std::uint16_t x) noexcept {
|
||||||
|
@ -244,7 +244,7 @@ inline std::uint64_t endian_swap64(std::uint64_t x) noexcept {
|
||||||
return __builtin_bswap64(x);
|
return __builtin_bswap64(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(OSTD_TOOLCHAIN_MSVC)
|
#elif defined(OSTD_TOOLCHAIN_MSVC) && !defined(OSTD_GENERATING_DOC)
|
||||||
|
|
||||||
/* using msvc builtins */
|
/* using msvc builtins */
|
||||||
inline std::uint16_t endian_swap16(std::uint16_t x) noexcept {
|
inline std::uint16_t endian_swap16(std::uint16_t x) noexcept {
|
||||||
|
@ -261,12 +261,18 @@ inline std::uint64_t endian_swap64(std::uint64_t x) noexcept {
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/* fallback */
|
/* fallback */
|
||||||
|
|
||||||
|
/** @brief 16-bit byte swap. */
|
||||||
inline std::uint16_t endian_swap16(std::uint16_t x) noexcept {
|
inline std::uint16_t endian_swap16(std::uint16_t x) noexcept {
|
||||||
return (x << 8) | (x >> 8);
|
return (x << 8) | (x >> 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief 32-bit byte swap. */
|
||||||
inline std::uint32_t endian_swap32(std::uint32_t x) noexcept {
|
inline std::uint32_t endian_swap32(std::uint32_t x) noexcept {
|
||||||
return (x << 24) | (x >> 24) | ((x >> 8) & 0xFF00) | ((x << 8) & 0xFF0000);
|
return (x << 24) | (x >> 24) | ((x >> 8) & 0xFF00) | ((x << 8) & 0xFF0000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief 64-bit byte swap. */
|
||||||
inline std::uint64_t endian_swap64(std::uint64_t x) noexcept {
|
inline std::uint64_t endian_swap64(std::uint64_t x) noexcept {
|
||||||
return endian_swap32(
|
return endian_swap32(
|
||||||
std::uint32_t(x >> 32)) |
|
std::uint32_t(x >> 32)) |
|
||||||
|
|
|
@ -782,7 +782,6 @@ private:
|
||||||
size_type p_written = 0;
|
size_type p_written = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** @brief A range to wrap is needed. */
|
|
||||||
counting_output_range() = delete;
|
counting_output_range() = delete;
|
||||||
|
|
||||||
/** @brief Constructs the range from an existing range. */
|
/** @brief Constructs the range from an existing range. */
|
||||||
|
@ -1017,7 +1016,6 @@ private:
|
||||||
T p_range;
|
T p_range;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** @brief Not default constructible. */
|
|
||||||
reverse_range() = delete;
|
reverse_range() = delete;
|
||||||
|
|
||||||
/** @brief Constructs a reverse range from a range. */
|
/** @brief Constructs a reverse range from a range. */
|
||||||
|
@ -1099,7 +1097,6 @@ private:
|
||||||
T p_range;
|
T p_range;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** @brief Not default constructible. */
|
|
||||||
move_range() = delete;
|
move_range() = delete;
|
||||||
|
|
||||||
/** @brief Constructs a move range from a range. */
|
/** @brief Constructs a move range from a range. */
|
||||||
|
@ -1139,7 +1136,6 @@ struct number_range: input_range<number_range<T>> {
|
||||||
using size_type = std::size_t;
|
using size_type = std::size_t;
|
||||||
using difference_type = std::ptrdiff_t;
|
using difference_type = std::ptrdiff_t;
|
||||||
|
|
||||||
/** @brief Not default constructible. */
|
|
||||||
number_range() = delete;
|
number_range() = delete;
|
||||||
|
|
||||||
/** @brief Constructs the range from inputs.
|
/** @brief Constructs the range from inputs.
|
||||||
|
@ -1240,7 +1236,6 @@ private:
|
||||||
size_type p_index;
|
size_type p_index;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** @brief Not default constructible. */
|
|
||||||
enumerated_range() = delete;
|
enumerated_range() = delete;
|
||||||
|
|
||||||
/** @brief Constructs an enumerated range from a range. */
|
/** @brief Constructs an enumerated range from a range. */
|
||||||
|
@ -1296,7 +1291,6 @@ private:
|
||||||
size_type p_remaining;
|
size_type p_remaining;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** @brief Not default constructible. */
|
|
||||||
take_range() = delete;
|
take_range() = delete;
|
||||||
|
|
||||||
/** @brief Constructs the range with some number of elements. */
|
/** @brief Constructs the range with some number of elements. */
|
||||||
|
@ -1347,7 +1341,6 @@ private:
|
||||||
size_type p_chunksize;
|
size_type p_chunksize;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** @brief Not default constructible. */
|
|
||||||
chunks_range() = delete;
|
chunks_range() = delete;
|
||||||
|
|
||||||
/** @brief Constructs the range with some number of elements per chunk. */
|
/** @brief Constructs the range with some number of elements per chunk. */
|
||||||
|
@ -1416,7 +1409,6 @@ private:
|
||||||
std::tuple<R...> p_ranges;
|
std::tuple<R...> p_ranges;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** @brief Not default constructible. */
|
|
||||||
join_range() = delete;
|
join_range() = delete;
|
||||||
|
|
||||||
/** @brief Constructs the range from some ranges. */
|
/** @brief Constructs the range from some ranges. */
|
||||||
|
@ -1484,7 +1476,6 @@ private:
|
||||||
std::tuple<R...> p_ranges;
|
std::tuple<R...> p_ranges;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** @brief Not default constructible. */
|
|
||||||
zip_range() = delete;
|
zip_range() = delete;
|
||||||
|
|
||||||
/** @brief Constructs the range from some ranges. */
|
/** @brief Constructs the range from some ranges. */
|
||||||
|
|
|
@ -560,7 +560,6 @@ struct stream_range<T, true>: input_range<stream_range<T>> {
|
||||||
using size_type = std::size_t;
|
using size_type = std::size_t;
|
||||||
using difference_type = stream_off_t;
|
using difference_type = stream_off_t;
|
||||||
|
|
||||||
/** @brief Stream ranges are not default constructible. */
|
|
||||||
stream_range() = delete;
|
stream_range() = delete;
|
||||||
|
|
||||||
/** @brief Creates a stream range using a stream. */
|
/** @brief Creates a stream range using a stream. */
|
||||||
|
@ -674,7 +673,6 @@ struct stream_line_range: input_range<stream_line_range<T, TC>> {
|
||||||
using size_type = std::size_t;
|
using size_type = std::size_t;
|
||||||
using difference_type = stream_off_t;
|
using difference_type = stream_off_t;
|
||||||
|
|
||||||
/** @brief Stream line ranges are not default constructible. */
|
|
||||||
stream_line_range() = delete;
|
stream_line_range() = delete;
|
||||||
|
|
||||||
/** @brief Creates a stream line range using a stream.
|
/** @brief Creates a stream line range using a stream.
|
||||||
|
|
|
@ -126,7 +126,7 @@ struct thread_pool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Calls destroy(). */
|
/** @brief Calls destroy(). */
|
||||||
~thread_pool() {
|
~thread_pool() {
|
||||||
destroy();
|
destroy();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue