Kaynağa Gözat

* Refactored future classes

master
bergmann 6 yıl önce
ebeveyn
işleme
4e6c1f5f20
26 değiştirilmiş dosya ile 381 ekleme ve 299 silme
  1. +8
    -2
      include/asyncpp/core.h
  2. +21
    -27
      include/asyncpp/core/future.h
  3. +0
    -186
      include/asyncpp/core/future.inl
  4. +7
    -4
      include/asyncpp/core/future/and_then.h
  5. +64
    -6
      include/asyncpp/core/future/and_then.inl
  6. +7
    -4
      include/asyncpp/core/future/lazy.h
  7. +5
    -5
      include/asyncpp/core/future/lazy.inl
  8. +7
    -4
      include/asyncpp/core/future/map.h
  9. +62
    -5
      include/asyncpp/core/future/map.inl
  10. +63
    -0
      include/asyncpp/core/future/timeout.inl
  11. +5
    -26
      include/asyncpp/core/misc.h
  12. +39
    -0
      include/asyncpp/core/misc/chaining.h
  13. +34
    -0
      include/asyncpp/core/misc/chaining.inl
  14. +28
    -0
      include/asyncpp/core/misc/timing.h
  15. +2
    -2
      include/asyncpp/core/misc/timing.inl
  16. +3
    -3
      include/asyncpp/core/stream.inl
  17. +4
    -4
      include/asyncpp/core/stream/map.h
  18. +4
    -4
      include/asyncpp/core/stream/map.inl
  19. +2
    -2
      include/asyncpp/timing/impl/timer_impl.h
  20. +2
    -2
      include/asyncpp/timing/impl/timer_impl.inl
  21. +4
    -5
      include/asyncpp/timing/interval.inl
  22. +1
    -1
      include/asyncpp/timing/timeout.h
  23. +0
    -2
      include/asyncpp/timing/timeout.inl
  24. +1
    -1
      include/asyncpp/timing/timer.h
  25. +1
    -3
      include/asyncpp/timing/timer.inl
  26. +7
    -1
      test/asyncpp/timing/timeout_tests.cpp

+ 8
- 2
include/asyncpp/core.h Dosyayı Görüntüle

@@ -6,7 +6,13 @@
#include "core/stream.h" #include "core/stream.h"
#include "core/task.h" #include "core/task.h"


#include "core/future.inl"
#include "core/misc.inl"
#include "core/result.inl" #include "core/result.inl"
#include "core/stream.inl" #include "core/stream.inl"

#include "core/future/map.inl"
#include "core/future/lazy.inl"
#include "core/future/and_then.inl"

#ifdef asyncpp_timing
#include "core/future/timeout.inl"
#endif

+ 21
- 27
include/asyncpp/core/future.h Dosyayı Görüntüle

@@ -2,6 +2,7 @@


#include <type_traits> #include <type_traits>


#include "misc.h"
#include "result.h" #include "result.h"
#include "future.pre.h" #include "future.pre.h"


@@ -28,19 +29,17 @@ namespace asyncpp
/** /**
* @brief Transform the result of this future. * @brief Transform the result of this future.
*/ */
template<typename X_lambda>
inline auto map(X_lambda&& p_lambda) const &;

/**
* @brief Transform the result of this future.
*/
template<typename X_lambda>
template<
chaining_mode X_mode = copy,
typename X_lambda>
inline auto map(X_lambda&& p_lambda) &; inline auto map(X_lambda&& p_lambda) &;


/** /**
* @brief Transform the result of this future. * @brief Transform the result of this future.
*/ */
template<typename X_lambda>
template<
chaining_mode X_mode = move,
typename X_lambda>
inline auto map(X_lambda&& p_lambda) &&; inline auto map(X_lambda&& p_lambda) &&;


public: public:
@@ -48,21 +47,18 @@ namespace asyncpp
* @brief Execute the given lambda after the future is finished and * @brief Execute the given lambda after the future is finished and
* wait for the future returned by the lambda. * wait for the future returned by the lambda.
*/ */
template<typename X_lambda>
inline auto and_then(X_lambda&& p_lambda) const &;

/**
* @brief Execute the given lambda after the future is finished and
* wait for the future returned by the lambda.
*/
template<typename X_lambda>
template<
chaining_mode X_mode = copy,
typename X_lambda>
inline auto and_then(X_lambda&& p_lambda) &; inline auto and_then(X_lambda&& p_lambda) &;


/** /**
* @brief Execute the given lambda after the future is finished and * @brief Execute the given lambda after the future is finished and
* wait for the future returned by the lambda. * wait for the future returned by the lambda.
*/ */
template<typename X_lambda>
template<
chaining_mode X_mode = move,
typename X_lambda>
inline auto and_then(X_lambda&& p_lambda) &&; inline auto and_then(X_lambda&& p_lambda) &&;


#ifdef asyncpp_timing #ifdef asyncpp_timing
@@ -72,15 +68,10 @@ namespace asyncpp
* *
* This method is only enabled if timer.h is included before. * This method is only enabled if timer.h is included before.
*/ */
template<typename X_base, typename X_ratio>
inline auto timeout(const duration<X_base, X_ratio>& p_timeout) const &;

/**
* @brief Throw an execption if the timeout has passed.
*
* This method is only enabled if timer.h is included before.
*/
template<typename X_base, typename X_ratio>
template<
chaining_mode X_mode = copy,
typename X_base,
typename X_ratio>
inline auto timeout(const duration<X_base, X_ratio>& p_timeout) &; inline auto timeout(const duration<X_base, X_ratio>& p_timeout) &;


/** /**
@@ -88,7 +79,10 @@ namespace asyncpp
* *
* This method is only enabled if timer.h is included before. * This method is only enabled if timer.h is included before.
*/ */
template<typename X_base, typename X_ratio>
template<
chaining_mode X_mode = move,
typename X_base,
typename X_ratio>
inline auto timeout(const duration<X_base, X_ratio>& p_timeout) &&; inline auto timeout(const duration<X_base, X_ratio>& p_timeout) &&;
#endif #endif
}; };


+ 0
- 186
include/asyncpp/core/future.inl Dosyayı Görüntüle

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

#include "future.h"

#include "future/map.inl"
#include "future/lazy.inl"
#include "future/and_then.inl"

#ifdef asyncpp_timing
#include <asyncpp/timing/timeout.inl>
#endif

namespace asyncpp
{

/* base_future::map */

template<
typename T_value,
typename T_derived>
template<
typename X_lambda>
auto base_future<T_value, T_derived>
::map(X_lambda&& p_lambda) const &
{
using lambda_type = X_lambda;
using map_type = __future::map_impl<derived_type, lambda_type>;

auto& self = static_cast<derived_type const &>(*this);

return map_type(
std::forward<derived_type const>(self),
std::forward<X_lambda>(p_lambda));
}

template<
typename T_value,
typename T_derived>
template<
typename X_lambda>
auto base_future<T_value, T_derived>
::map(X_lambda&& p_lambda) &
{
using lambda_type = X_lambda;
using map_type = __future::map_impl<derived_type&, lambda_type>;

auto& self = static_cast<derived_type &>(*this);

return map_type(
std::forward<derived_type &>(self),
std::forward<X_lambda>(p_lambda));
}

template<
typename T_value,
typename T_derived>
template<
typename X_lambda>
auto base_future<T_value, T_derived>
::map(X_lambda&& p_lambda) &&
{
using lambda_type = X_lambda;
using map_type = __future::map_impl<derived_type, lambda_type>;

auto& self = static_cast<derived_type &>(*this);

return map_type(
std::forward<derived_type &&>(self),
std::forward<X_lambda>(p_lambda));
}

/* base_future::and_then */

template<
typename T_value,
typename T_derived>
template<
typename X_lambda>
auto base_future<T_value, T_derived>
::and_then(X_lambda&& p_lambda) const &
{
using lambda_type = X_lambda;
using and_then_type = __future::and_then_impl<derived_type, lambda_type>;

auto& self = static_cast<derived_type const &>(*this);

return and_then_type(
std::forward<derived_type const>(self),
std::forward<X_lambda>(p_lambda));
}

template<
typename T_value,
typename T_derived>
template<
typename X_lambda>
auto base_future<T_value, T_derived>
::and_then(X_lambda&& p_lambda) &
{
using lambda_type = X_lambda;
using and_then_type = __future::and_then_impl<derived_type&, lambda_type>;

auto& self = static_cast<derived_type &>(*this);

return and_then_type(
std::forward<derived_type &>(self),
std::forward<X_lambda>(p_lambda));
}

template<
typename T_value,
typename T_derived>
template<
typename X_lambda>
auto base_future<T_value, T_derived>
::and_then(X_lambda&& p_lambda) &&
{
using lambda_type = X_lambda;
using and_then_type = __future::and_then_impl<derived_type, lambda_type>;

auto& self = static_cast<derived_type &>(*this);

return and_then_type(
std::forward<derived_type &&>(self),
std::forward<X_lambda>(p_lambda));
}

/* base_future::timeout */

#ifdef asyncpp_timing
template<
typename T_value,
typename T_derived>
template<
typename X_base,
typename X_ratio>
auto base_future<T_value, T_derived>
::timeout(const duration<X_base, X_ratio>& p_timeout) const &
{
using timeout_type = timing::timeout<derived_type>;

auto& self = static_cast<derived_type const &>(*this);

return timeout_type(
std::forward<derived_type const>(self),
p_timeout);
}

template<
typename T_value,
typename T_derived>
template<
typename X_base,
typename X_ratio>
auto base_future<T_value, T_derived>
::timeout(const duration<X_base, X_ratio>& p_timeout) &
{
using timeout_type = timing::timeout<derived_type&>;

auto& self = static_cast<derived_type &>(*this);

return timeout_type(
std::forward<derived_type &>(self),
p_timeout);
}

template<
typename T_value,
typename T_derived>
template<
typename X_base,
typename X_ratio>
auto base_future<T_value, T_derived>
::timeout(const duration<X_base, X_ratio>& p_timeout) &&
{
using timeout_type = timing::timeout<derived_type>;

auto& self = static_cast<derived_type &>(*this);

return timeout_type(
std::forward<derived_type &&>(self),
p_timeout);
}
#endif

}

+ 7
- 4
include/asyncpp/core/future/and_then.h Dosyayı Görüntüle

@@ -10,10 +10,10 @@ namespace __future {
template< template<
typename T_future, typename T_future,
typename T_lambda> typename T_lambda>
struct and_then_impl final :
struct and_then_future final :
public base_future< public base_future<
decltype(std::declval<T_lambda>()(std::declval<typename std::decay_t<T_future>::value_type>())), decltype(std::declval<T_lambda>()(std::declval<typename std::decay_t<T_future>::value_type>())),
and_then_impl<T_future, T_lambda>
and_then_future<T_future, T_lambda>
> >
{ {
public: public:
@@ -23,7 +23,7 @@ namespace __future {
using second_future_type = decltype(std::declval<lambda_type>()(std::declval<first_value_type>())); using second_future_type = decltype(std::declval<lambda_type>()(std::declval<first_value_type>()));
using second_future_type_ptr = std::unique_ptr<second_future_type>; using second_future_type_ptr = std::unique_ptr<second_future_type>;
using value_type = typename second_future_type::value_type; using value_type = typename second_future_type::value_type;
using this_type = and_then_impl<value_type, lambda_type>;
using this_type = and_then_future<value_type, lambda_type>;
using base_future_type = base_future<value_type, this_type>; using base_future_type = base_future<value_type, this_type>;
using result_type = typename base_future_type::result_type; using result_type = typename base_future_type::result_type;


@@ -39,10 +39,13 @@ namespace __future {
template< template<
typename X_future, typename X_future,
typename X_lambda> typename X_lambda>
inline and_then_impl(
inline and_then_future(
X_future&& p_outer, X_future&& p_outer,
X_lambda&& p_lambda); X_lambda&& p_lambda);


inline and_then_future(and_then_future &&) = default;
inline and_then_future(and_then_future const &) = default;

public: /* future */ public: /* future */
/** /**
* @brief Poll the result from the future. * @brief Poll the result from the future.


+ 64
- 6
include/asyncpp/core/future/and_then.inl Dosyayı Görüntüle

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


#include "map.h"
#include "and_then.h"
#include "../future.h"


namespace asyncpp { namespace asyncpp {
namespace __future { namespace __future {


/* and_then_impl */
/* and_then_future */


template< template<
typename T_future, typename T_future,
@@ -13,8 +14,8 @@ namespace __future {
template< template<
typename X_future, typename X_future,
typename X_lambda> typename X_lambda>
and_then_impl<T_future, T_lambda>
::and_then_impl(
and_then_future<T_future, T_lambda>
::and_then_future(
X_future&& p_first, X_future&& p_first,
X_lambda&& p_lambda) X_lambda&& p_lambda)
: _first (std::forward<X_future>(p_first)) : _first (std::forward<X_future>(p_first))
@@ -24,8 +25,8 @@ namespace __future {
template< template<
typename T_future, typename T_future,
typename T_lambda> typename T_lambda>
typename and_then_impl<T_future, T_lambda>::result_type
and_then_impl<T_future, T_lambda>
typename and_then_future<T_future, T_lambda>::result_type
and_then_future<T_future, T_lambda>
::poll() ::poll()
{ {
while (true) while (true)
@@ -45,4 +46,61 @@ namespace __future {
} }
} }


/* and_then_impl */

template<
chaining_mode X_mode,
typename X_self,
typename X_lambda>
auto and_then_impl(X_self&& p_self, X_lambda&& p_lambda)
{
using lambda_type = X_lambda;
using self_type = X_self;
using derived_type = typename std::decay_t<self_type>::derived_type;
using derived_storage_type = storage_type_t<X_mode, derived_type>;
using derived_ref_type = std::conditional_t<
std::is_const_v<std::remove_reference_t<self_type>>,
derived_type const &,
derived_type &>;
using derived_forward_type = forward_type_t<X_mode, derived_ref_type>;
using and_then_future_type = __future::and_then_future<derived_storage_type, lambda_type>;

static_assert(
X_mode != ref || !std::is_rvalue_reference_v<self_type>,
"Can not store rvalue reference as lvalue reference!");

auto& self = static_cast<derived_ref_type>(p_self);

return and_then_future_type(
std::forward<derived_forward_type>(self),
std::forward<X_lambda> (p_lambda));
}

} } } }

namespace asyncpp
{

/* future_base::and_then */

template<
typename T_value,
typename T_derived>
template<
chaining_mode X_mode,
typename X_lambda>
auto base_future<T_value, T_derived>
::and_then(X_lambda&& p_lambda) &
{ return __future::and_then_impl<X_mode>(*this, std::forward<X_lambda>(p_lambda)); }

template<
typename T_value,
typename T_derived>
template<
chaining_mode X_mode,
typename X_lambda>
auto base_future<T_value, T_derived>
::and_then(X_lambda&& p_lambda) &&
{ return __future::and_then_impl<X_mode>(std::move(*this), std::forward<X_lambda>(p_lambda)); }

}

+ 7
- 4
include/asyncpp/core/future/lazy.h Dosyayı Görüntüle

@@ -9,16 +9,16 @@ namespace asyncpp
{ {


template<typename T_lambda> template<typename T_lambda>
struct lazy_impl final :
struct lazy_future final :
public base_future< public base_future<
decltype(std::declval<T_lambda>()()), decltype(std::declval<T_lambda>()()),
lazy_impl<T_lambda>
lazy_future<T_lambda>
> >
{ {
public: public:
using lambda_type = T_lambda; using lambda_type = T_lambda;
using value_type = decltype(std::declval<lambda_type>()()); using value_type = decltype(std::declval<lambda_type>()());
using this_type = lazy_impl<lambda_type>;
using this_type = lazy_future<lambda_type>;
using base_future_type = base_future<value_type, this_type>; using base_future_type = base_future<value_type, this_type>;
using result_type = typename base_future_type::result_type; using result_type = typename base_future_type::result_type;


@@ -30,9 +30,12 @@ namespace asyncpp
* @brief Constructor. * @brief Constructor.
*/ */
template<typename X_lambda> template<typename X_lambda>
inline lazy_impl(
inline lazy_future(
X_lambda&& p_lambda); X_lambda&& p_lambda);


inline lazy_future(lazy_future &&) = default;
inline lazy_future(lazy_future const &) = default;

public: /* future */ public: /* future */
/** /**
* @brief Poll the result from the future. * @brief Poll the result from the future.


+ 5
- 5
include/asyncpp/core/future/lazy.inl Dosyayı Görüntüle

@@ -8,18 +8,18 @@ namespace asyncpp
namespace __future namespace __future
{ {


/* lazy_impl */
/* lazy_future */


template<typename T_lambda> template<typename T_lambda>
template<typename X_lambda> template<typename X_lambda>
lazy_impl<T_lambda>::lazy_impl(
lazy_future<T_lambda>::lazy_future(
X_lambda&& p_lambda) X_lambda&& p_lambda)
: _lambda(std::forward<X_lambda>(p_lambda)) : _lambda(std::forward<X_lambda>(p_lambda))
{ } { }


template<typename T_lambda> template<typename T_lambda>
template<typename X> template<typename X>
inline auto lazy_impl<T_lambda>
inline auto lazy_future<T_lambda>
::poll() ::poll()
-> std::enable_if_t< -> std::enable_if_t<
std::is_void_v<X>, std::is_void_v<X>,
@@ -31,7 +31,7 @@ namespace asyncpp


template<typename T_lambda> template<typename T_lambda>
template<typename X> template<typename X>
inline auto lazy_impl<T_lambda>
inline auto lazy_future<T_lambda>
::poll() ::poll()
-> std::enable_if_t< -> std::enable_if_t<
!std::is_void_v<X>, !std::is_void_v<X>,
@@ -45,7 +45,7 @@ namespace asyncpp
inline auto lazy(X_lambda&& p_lambda) inline auto lazy(X_lambda&& p_lambda)
{ {
using lambda_type = X_lambda; using lambda_type = X_lambda;
using lazy_type = __future::lazy_impl<lambda_type>;
using lazy_type = __future::lazy_future<lambda_type>;


return lazy_type(std::forward<X_lambda>(p_lambda)); return lazy_type(std::forward<X_lambda>(p_lambda));
} }


+ 7
- 4
include/asyncpp/core/future/map.h Dosyayı Görüntüle

@@ -8,10 +8,10 @@ namespace __future {
template< template<
typename T_future, typename T_future,
typename T_lambda> typename T_lambda>
struct map_impl final :
struct map_future final :
public base_future< public base_future<
typename std::decay_t<T_future>::value_type, typename std::decay_t<T_future>::value_type,
map_impl<T_future, T_lambda>
map_future<T_future, T_lambda>
> >
{ {
public: public:
@@ -19,7 +19,7 @@ namespace __future {
using lambda_type = T_lambda; using lambda_type = T_lambda;
using future_value_type = typename std::decay_t<future_type>::value_type; using future_value_type = typename std::decay_t<future_type>::value_type;
using value_type = decltype(std::declval<lambda_type>()(std::declval<future_value_type>())); using value_type = decltype(std::declval<lambda_type>()(std::declval<future_value_type>()));
using this_type = map_impl<future_type, lambda_type>;
using this_type = map_future<future_type, lambda_type>;
using base_future_type = base_future<value_type, this_type>; using base_future_type = base_future<value_type, this_type>;
using result_type = typename base_future_type::result_type; using result_type = typename base_future_type::result_type;


@@ -34,10 +34,13 @@ namespace __future {
template< template<
typename X_future, typename X_future,
typename X_lambda> typename X_lambda>
inline map_impl(
inline map_future(
X_future&& p_future, X_future&& p_future,
X_lambda&& p_lambda); X_lambda&& p_lambda);


inline map_future(map_future &&) = default;
inline map_future(map_future const &) = default;

public: /* future */ public: /* future */
/** /**
* @brief Poll the result from the future. * @brief Poll the result from the future.


+ 62
- 5
include/asyncpp/core/future/map.inl Dosyayı Görüntüle

@@ -5,7 +5,7 @@
namespace asyncpp { namespace asyncpp {
namespace __future { namespace __future {


/* map_impl */
/* map_future */


template< template<
typename T_future, typename T_future,
@@ -13,8 +13,8 @@ namespace __future {
template< template<
typename X_future, typename X_future,
typename X_lambda> typename X_lambda>
map_impl<T_future, T_lambda>
::map_impl(
map_future<T_future, T_lambda>
::map_future(
X_future&& p_future, X_future&& p_future,
X_lambda&& p_lambda) X_lambda&& p_lambda)
: _future(std::forward<X_future>(p_future)) : _future(std::forward<X_future>(p_future))
@@ -24,8 +24,8 @@ namespace __future {
template< template<
typename T_future, typename T_future,
typename T_lambda> typename T_lambda>
typename map_impl<T_future, T_lambda>::result_type
map_impl<T_future, T_lambda>
typename map_future<T_future, T_lambda>::result_type
map_future<T_future, T_lambda>
::poll() ::poll()
{ {
auto r = _future.poll(); auto r = _future.poll();
@@ -34,4 +34,61 @@ namespace __future {
: result_type::not_ready(); : result_type::not_ready();
} }


/* map_impl */

template<
chaining_mode X_mode,
typename X_self,
typename X_lambda>
auto map_impl(X_self&& p_self, X_lambda&& p_lambda)
{
using lambda_type = X_lambda;
using self_type = X_self;
using derived_type = typename std::decay_t<self_type>::derived_type;
using derived_storage_type = storage_type_t<X_mode, derived_type>;
using derived_ref_type = std::conditional_t<
std::is_const_v<std::remove_reference_t<self_type>>,
derived_type const &,
derived_type &>;
using derived_forward_type = forward_type_t<X_mode, derived_ref_type>;
using map_future_type = __future::map_future<derived_storage_type, lambda_type>;

static_assert(
X_mode != ref || !std::is_rvalue_reference_v<self_type>,
"Can not store rvalue reference as lvalue reference!");

auto& self = static_cast<derived_ref_type>(p_self);

return map_future_type(
std::forward<derived_forward_type>(self),
std::forward<X_lambda> (p_lambda));
}

} } } }

namespace asyncpp
{

/* future_base::map */

template<
typename T_value,
typename T_derived>
template<
chaining_mode X_mode,
typename X_lambda>
auto base_future<T_value, T_derived>
::map(X_lambda&& p_lambda) &
{ return __future::map_impl<X_mode>(*this, std::forward<X_lambda>(p_lambda)); }

template<
typename T_value,
typename T_derived>
template<
chaining_mode X_mode,
typename X_lambda>
auto base_future<T_value, T_derived>
::map(X_lambda&& p_lambda) &&
{ return __future::map_impl<X_mode>(std::move(*this), std::forward<X_lambda>(p_lambda)); }

}

+ 63
- 0
include/asyncpp/core/future/timeout.inl Dosyayı Görüntüle

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

#include "../future.h"

namespace asyncpp {
namespace __future {

template<
chaining_mode X_mode,
typename X_self,
typename X_base,
typename X_ratio>
auto helper_timeout(
X_self&& p_self,
const duration<X_base, X_ratio>& p_timeout)
{
using self_type = X_self;
using derived_type = typename std::decay_t<self_type>::derived_type;
using derived_storage_type = storage_type_t<X_mode, derived_type>;
using derived_ref_type = std::conditional_t<
std::is_const_v<std::remove_reference_t<self_type>>,
derived_type const &,
derived_type &>;
using derived_forward_type = forward_type_t<X_mode, derived_ref_type>;
using timeout_type = timing::timeout<derived_storage_type>;

auto& self = static_cast<derived_ref_type>(p_self);

return timeout_type(
std::forward<derived_forward_type>(self),
p_timeout);
}

} }

namespace asyncpp
{

/* future_base::timeout */

template<
typename T_value,
typename T_derived>
template<
chaining_mode X_mode,
typename X_base,
typename X_ratio>
auto base_future<T_value, T_derived>
::timeout(const duration<X_base, X_ratio>& p_timeout) &
{ return __future::helper_timeout<X_mode>(*this, p_timeout); }

template<
typename T_value,
typename T_derived>
template<
chaining_mode X_mode,
typename X_base,
typename X_ratio>
auto base_future<T_value, T_derived>
::timeout(const duration<X_base, X_ratio>& p_timeout) &&
{ return __future::helper_timeout<X_mode>(std::move(*this), p_timeout); }

}

+ 5
- 26
include/asyncpp/core/misc.h Dosyayı Görüntüle

@@ -1,28 +1,7 @@
#pragma once
#pragma


#include <chrono>
#include "misc/chaining.h"
#include "misc/timing.h"


namespace asyncpp
{

using clock = std::chrono::steady_clock;

using time_point = clock::time_point;

template<typename T_base, typename T_ratio>
using duration = std::chrono::duration<T_base ,T_ratio>;

/**
* @brief Get the current time point.
*/
inline time_point now();

/**
* @brief Returns the lowest of the two passed deadlines (if not null)
* or nullptr if no deadline was passed.
*/
inline const time_point * merge_deadlines(
const time_point * p_deadline_0,
const time_point * p_deadline_1);

}
#include "misc/chaining.inl"
#include "misc/timing.inl"

+ 39
- 0
include/asyncpp/core/misc/chaining.h Dosyayı Görüntüle

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

namespace asyncpp
{

enum chaining_mode
{
move,
copy,
ref,
};

/**
* @brief Get the storage type of the passed type for the passed mode.
*
* move: T
* copy: T
* ref T &
*/
template<chaining_mode X_mode, typename X_type, typename = void>
struct storage_type;

/**
* @brief Get the forward type of the passed type for the passed mode.
*
* move: T &&
* copy: T const &
* ref T &
*/
template<chaining_mode X_mode, typename X_type, typename = void>
struct forward_type;

template<chaining_mode X_mode, typename X_type>
using storage_type_t = typename storage_type<X_mode, X_type>::type;

template<chaining_mode X_mode, typename X_type>
using forward_type_t = typename forward_type<X_mode, X_type>::type;

}

+ 34
- 0
include/asyncpp/core/misc/chaining.inl Dosyayı Görüntüle

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

namespace asyncpp
{

/* storage_type */

template<typename X_type>
struct storage_type<move, X_type, void>
{ using type = X_type; };

template<typename X_type>
struct storage_type<copy, X_type, void>
{ using type = X_type; };

template<typename X_type>
struct storage_type<ref, X_type, void>
{ using type = X_type&; };

/* forward_type */

template<typename X_type>
struct forward_type<move, X_type, void>
{ using type = std::decay_t<X_type> &&; };

template<typename X_type>
struct forward_type<copy, X_type, void>
{ using type = std::decay_t<X_type> const &; };

template<typename X_type>
struct forward_type<ref, X_type, void>
{ using type = std::remove_reference_t<X_type> &; };

}

+ 28
- 0
include/asyncpp/core/misc/timing.h Dosyayı Görüntüle

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

#include <chrono>

namespace asyncpp
{

using clock = std::chrono::steady_clock;

using time_point = clock::time_point;

template<typename T_base, typename T_ratio>
using duration = std::chrono::duration<T_base ,T_ratio>;

/**
* @brief Get the current time point.
*/
inline time_point now();

/**
* @brief Returns the lowest of the two passed deadlines (if not null)
* or nullptr if no deadline was passed.
*/
inline const time_point * merge_deadlines(
const time_point * p_deadline_0,
const time_point * p_deadline_1);

}

include/asyncpp/core/misc.inl → include/asyncpp/core/misc/timing.inl Dosyayı Görüntüle

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


#include "misc.h"
#include "timing.h"


namespace asyncpp namespace asyncpp
{ {


#ifndef __asyncpp_has_impl_timer_now
#ifndef __asyncpp_has_impl_timer_now
time_point now() time_point now()
{ return clock::now(); } { return clock::now(); }
#endif #endif

+ 3
- 3
include/asyncpp/core/stream.inl Dosyayı Görüntüle

@@ -80,7 +80,7 @@ namespace asyncpp
::map(X_lambda&& p_lambda) const & ::map(X_lambda&& p_lambda) const &
{ {
using lambda_type = X_lambda; using lambda_type = X_lambda;
using map_type = __stream::map_impl<derived_type, lambda_type>;
using map_type = __stream::map_future<derived_type, lambda_type>;


auto& self = static_cast<derived_type const &>(*this); auto& self = static_cast<derived_type const &>(*this);


@@ -98,7 +98,7 @@ namespace asyncpp
::map(X_lambda&& p_lambda) & ::map(X_lambda&& p_lambda) &
{ {
using lambda_type = X_lambda; using lambda_type = X_lambda;
using map_type = __stream::map_impl<derived_type, lambda_type>;
using map_type = __stream::map_future<derived_type, lambda_type>;


auto& self = static_cast<derived_type &>(*this); auto& self = static_cast<derived_type &>(*this);


@@ -116,7 +116,7 @@ namespace asyncpp
::map(X_lambda&& p_lambda) && ::map(X_lambda&& p_lambda) &&
{ {
using lambda_type = X_lambda; using lambda_type = X_lambda;
using map_type = __stream::map_impl<derived_type, lambda_type>;
using map_type = __stream::map_future<derived_type, lambda_type>;


auto& self = static_cast<derived_type &>(*this); auto& self = static_cast<derived_type &>(*this);




+ 4
- 4
include/asyncpp/core/stream/map.h Dosyayı Görüntüle

@@ -8,10 +8,10 @@ namespace __stream {
template< template<
typename T_stream, typename T_stream,
typename T_lambda> typename T_lambda>
struct map_impl final :
struct map_future final :
public base_stream< public base_stream<
decltype(std::declval<T_lambda>()(std::declval<typename T_stream::value_type>())), decltype(std::declval<T_lambda>()(std::declval<typename T_stream::value_type>())),
map_impl<T_stream, T_lambda>
map_future<T_stream, T_lambda>
> >
{ {
public: public:
@@ -19,7 +19,7 @@ namespace __stream {
using lambda_type = T_lambda; using lambda_type = T_lambda;
using inner_value_type = typename stream_type::value_type; using inner_value_type = typename stream_type::value_type;
using value_type = decltype(std::declval<lambda_type>()(std::declval<inner_value_type>())); using value_type = decltype(std::declval<lambda_type>()(std::declval<inner_value_type>()));
using this_type = map_impl<stream_type, lambda_type>;
using this_type = map_future<stream_type, lambda_type>;
using base_stream_type = base_stream<value_type, this_type>; using base_stream_type = base_stream<value_type, this_type>;
using result_type = typename base_stream_type::result_type; using result_type = typename base_stream_type::result_type;


@@ -34,7 +34,7 @@ namespace __stream {
template< template<
typename X_stream, typename X_stream,
typename X_lambda> typename X_lambda>
inline map_impl(
inline map_future(
X_stream&& p_stream, X_stream&& p_stream,
X_lambda&& p_lambda); X_lambda&& p_lambda);




+ 4
- 4
include/asyncpp/core/stream/map.inl Dosyayı Görüntüle

@@ -5,7 +5,7 @@
namespace asyncpp { namespace asyncpp {
namespace __stream { namespace __stream {


/* map_impl */
/* map_future */


template< template<
typename T_stream, typename T_stream,
@@ -13,7 +13,7 @@ namespace __stream {
template< template<
typename X_stream, typename X_stream,
typename X_lambda> typename X_lambda>
map_impl<T_stream, T_lambda>::map_impl(
map_future<T_stream, T_lambda>::map_future(
X_stream&& p_stream, X_stream&& p_stream,
X_lambda&& p_lambda) X_lambda&& p_lambda)
: _stream(std::forward<X_stream>(p_stream)) : _stream(std::forward<X_stream>(p_stream))
@@ -23,8 +23,8 @@ namespace __stream {
template< template<
typename T_stream, typename T_stream,
typename T_lambda> typename T_lambda>
typename map_impl<T_stream, T_lambda>::result_type
map_impl<T_stream, T_lambda>
typename map_future<T_stream, T_lambda>::result_type
map_future<T_stream, T_lambda>
::poll() ::poll()
{ {
auto r = _stream.poll(); auto r = _stream.poll();


+ 2
- 2
include/asyncpp/timing/impl/timer_impl.h Dosyayı Görüntüle

@@ -42,7 +42,7 @@ namespace timing {
X_args&&... p_args); X_args&&... p_args);


inline void idle( inline void idle(
const asyncpp::time_point * p_deadline);
const time_point * p_deadline);


inline thread_lock_ptr_u init_thread(); inline thread_lock_ptr_u init_thread();
}; };
@@ -70,7 +70,7 @@ namespace timing {
owner_type& p_owner); owner_type& p_owner);


inline void idle( inline void idle(
const asyncpp::time_point * p_deadline);
const time_point * p_deadline);


inline thread_lock_ptr_u init_thread(); inline thread_lock_ptr_u init_thread();
}; };


+ 2
- 2
include/asyncpp/timing/impl/timer_impl.inl Dosyayı Görüntüle

@@ -30,7 +30,7 @@ namespace __impl {
{ } { }


template<typename T_inner> template<typename T_inner>
void timer_impl<T_inner>::idle(const asyncpp::time_point * p_deadline)
void timer_impl<T_inner>::idle(const time_point * p_deadline)
{ {
{ {
auto r = owner._registrations.lock(); auto r = owner._registrations.lock();
@@ -63,7 +63,7 @@ namespace __impl {
{ } { }


void timer_impl<void>::idle( void timer_impl<void>::idle(
const asyncpp::time_point * p_deadline)
const time_point * p_deadline)
{ } { }


timer_impl<void>::thread_lock_ptr_u timer_impl<void>::thread_lock_ptr_u


+ 4
- 5
include/asyncpp/timing/interval.inl Dosyayı Görüntüle

@@ -1,9 +1,8 @@
#pragma once #pragma once


#include <asyncpp/core/future.inl>
#include "interval.h"


#include "delay.inl" #include "delay.inl"
#include "interval.h"


namespace asyncpp { namespace asyncpp {
namespace timing { namespace timing {
@@ -12,7 +11,7 @@ namespace timing {


template<typename T_base, typename T_ratio> template<typename T_base, typename T_ratio>
interval::interval( interval::interval(
const asyncpp::duration<T_base, T_ratio>& p_duration,
const ::asyncpp::duration<T_base, T_ratio>& p_duration,
time_point p_deadline) time_point p_deadline)
: interval(asyncpp::now() + p_duration, p_duration, p_deadline) : interval(asyncpp::now() + p_duration, p_duration, p_deadline)
{ } { }
@@ -20,7 +19,7 @@ namespace timing {
template<typename T_base, typename T_ratio> template<typename T_base, typename T_ratio>
interval::interval( interval::interval(
const time_point& p_at, const time_point& p_at,
const asyncpp::duration<T_base, T_ratio>& p_duration,
const ::asyncpp::duration<T_base, T_ratio>& p_duration,
time_point p_deadline) time_point p_deadline)
: _delay (p_at) : _delay (p_at)
, _duration(p_duration) , _duration(p_duration)
@@ -36,7 +35,7 @@ namespace timing {
{ {
if ( _deadline.time_since_epoch().count() if ( _deadline.time_since_epoch().count()
&& _delay.deadline() >= _deadline && _delay.deadline() >= _deadline
&& asyncpp::now() >= _delay.deadline())
&& asyncpp::now() >= _delay.deadline())
return result_type::done(); return result_type::done();


auto ret = _delay.poll(); auto ret = _delay.poll();


+ 1
- 1
include/asyncpp/timing/timeout.h Dosyayı Görüntüle

@@ -68,7 +68,7 @@ namespace timing {


template<typename T_inner> template<typename T_inner>
struct timeout final struct timeout final
: public __impl::timeout_impl<timeout<T_inner>>
: public __impl::timeout_impl<timeout<T_inner>>
{ {
public: public:
using inner_type = T_inner; using inner_type = T_inner;


+ 0
- 2
include/asyncpp/timing/timeout.inl Dosyayı Görüntüle

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


#include <asyncpp/core/misc.inl>

#include "timeout.h" #include "timeout.h"


namespace asyncpp { namespace asyncpp {


+ 1
- 1
include/asyncpp/timing/timer.h Dosyayı Görüntüle

@@ -39,7 +39,7 @@ namespace timing {
* This method is called as soon as the runtime has nothing to do. * This method is called as soon as the runtime has nothing to do.
* The passed deadline is the timepoint the method should return (or null if not set). * The passed deadline is the timepoint the method should return (or null if not set).
*/ */
inline void idle(const asyncpp::time_point * p_deadline);
inline void idle(const time_point * p_deadline);


/** /**
* @brief This method is calld by the executor when a new thread needs to be initialized. * @brief This method is calld by the executor when a new thread needs to be initialized.


+ 1
- 3
include/asyncpp/timing/timer.inl Dosyayı Görüntüle

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


#include <asyncpp/core/misc.inl>

#include "timer.h" #include "timer.h"
#include "delay.inl" #include "delay.inl"


@@ -21,7 +19,7 @@ namespace timing {
{ } { }


template<typename T_inner> template<typename T_inner>
void timer<T_inner>::idle(const asyncpp::time_point * p_deadline)
void timer<T_inner>::idle(const time_point * p_deadline)
{ {
auto now = asyncpp::now(); auto now = asyncpp::now();




+ 7
- 1
test/asyncpp/timing/timeout_tests.cpp Dosyayı Görüntüle

@@ -33,6 +33,12 @@ public:
} }
}; };


auto make_test_future(int i)
{
test_future ret(i);
return ret;
}

struct test_stream struct test_stream
: public base_stream<int, test_stream> : public base_stream<int, test_stream>
{ {
@@ -70,7 +76,7 @@ TEST(timeout_tests, poll_future_no_timeout)


test_future t(0); test_future t(0);
auto f = t auto f = t
.timeout(std::chrono::seconds(5));
.timeout<ref>(std::chrono::seconds(5));


EXPECT_CALL(m, now()) EXPECT_CALL(m, now())
.WillOnce(Return(time_point(std::chrono::seconds(0)))); .WillOnce(Return(time_point(std::chrono::seconds(0))));


Yükleniyor…
İptal
Kaydet