| @@ -2,6 +2,8 @@ | |||
| #include <asyncpp/future.h> | |||
| #include <asyncpp/result.h> | |||
| #include <asyncpp/stream.h> | |||
| #include <asyncpp/future.inl> | |||
| #include <asyncpp/result.inl> | |||
| #include <asyncpp/stream.inl> | |||
| @@ -0,0 +1,36 @@ | |||
| #pragma once | |||
| #include <type_traits> | |||
| #include "result.h" | |||
| #include "stream.pre.h" | |||
| namespace asyncpp | |||
| { | |||
| template< | |||
| typename T_object, | |||
| typename T_impl> | |||
| struct stream | |||
| { | |||
| using object_type = T_object; | |||
| using clean_object_type = std::decay_t<object_type>; | |||
| using trait_type = stream_trait<clean_object_type>; | |||
| using value_type = typename trait_type::value_type; | |||
| using result_type = stream_result<value_type>; | |||
| object_type ref; | |||
| /** | |||
| * @brief Value constructor. | |||
| */ | |||
| template<typename X_object> | |||
| inline stream(X_object&& p_ref); | |||
| /** | |||
| * @brief Function that will be called repeatedly to check if the stream has values. | |||
| */ | |||
| inline result_type poll(); | |||
| }; | |||
| } | |||
| @@ -0,0 +1,39 @@ | |||
| #pragma once | |||
| #include "stream.h" | |||
| namespace asyncpp | |||
| { | |||
| /* stream */ | |||
| template< | |||
| typename T_value, | |||
| typename T_impl> | |||
| template< | |||
| typename X_object> | |||
| stream<T_value, T_impl> | |||
| ::stream(X_object&& p_ref) | |||
| : ref(std::forward<X_object>(p_ref)) | |||
| { } | |||
| template< | |||
| typename T_value, | |||
| typename T_impl> | |||
| typename stream<T_value, T_impl>::result_type | |||
| stream<T_value, T_impl> | |||
| ::poll() | |||
| { return trait_type::poll(*this); } | |||
| /* misc */ | |||
| template<typename X_value> | |||
| constexpr decltype(auto) as_stream(X_value&& value) | |||
| { | |||
| using value_type = X_value; | |||
| using stream_type = stream<value_type>; | |||
| return stream_type(std::forward<X_value>(value)); | |||
| } | |||
| } | |||
| @@ -0,0 +1,27 @@ | |||
| #pragma once | |||
| namespace asyncpp | |||
| { | |||
| template<typename T_impl> | |||
| struct stream_base | |||
| { | |||
| template<typename T_stream> | |||
| static inline auto poll(T_stream& self) = delete; | |||
| }; | |||
| template<typename T, typename = void> | |||
| struct stream_trait; | |||
| template< | |||
| typename T_object, | |||
| typename T_impl = stream_trait<std::decay_t<T_object>>> | |||
| struct stream; | |||
| /** | |||
| * @brief Construct a stream from the given value. | |||
| */ | |||
| template<typename X_value> | |||
| constexpr decltype(auto) as_stream(X_value&& value); | |||
| } | |||
| @@ -0,0 +1,68 @@ | |||
| #include <gtest/gtest.h> | |||
| #include <asyncpp.h> | |||
| using namespace ::testing; | |||
| using namespace ::asyncpp; | |||
| struct delay | |||
| { | |||
| int const delay { 5 }; | |||
| int const threshold { 2 }; | |||
| int count { 0 }; | |||
| }; | |||
| namespace asyncpp | |||
| { | |||
| template<> | |||
| struct stream_trait<delay, void> | |||
| : public future_base<future<delay, void>> | |||
| { | |||
| using value_type = int; | |||
| template<typename T_future> | |||
| static inline auto poll(T_future& self) | |||
| { | |||
| using result_type = stream_result<value_type>; | |||
| if (self.ref.count >= self.ref.delay) | |||
| return result_type::done(); | |||
| ++self.ref.count; | |||
| return self.ref.count <= self.ref.threshold | |||
| ? result_type::not_ready() | |||
| : result_type::ready(self.ref.count); | |||
| } | |||
| }; | |||
| } | |||
| TEST(stream_tests, poll) | |||
| { | |||
| delay d { 5, 2, 0 }; | |||
| auto s = as_stream(d); | |||
| auto r0 = s.poll(); | |||
| ASSERT_FALSE(r0); | |||
| auto r1 = s.poll(); | |||
| ASSERT_FALSE(r1); | |||
| auto r2 = s.poll(); | |||
| ASSERT_TRUE (r2); | |||
| ASSERT_EQ (3, *r2); | |||
| auto r3 = s.poll(); | |||
| ASSERT_TRUE (r3); | |||
| ASSERT_EQ (4, *r3); | |||
| auto r4 = s.poll(); | |||
| ASSERT_TRUE (r4); | |||
| ASSERT_EQ (5, *r4); | |||
| auto r = s.poll(); | |||
| ASSERT_FALSE(r); | |||
| ASSERT_TRUE (r.is_done()); | |||
| } | |||