5 #if !defined(RXCPP_RX_UTIL_HPP) 6 #define RXCPP_RX_UTIL_HPP 10 #if !defined(RXCPP_ON_IOS) && !defined(RXCPP_ON_ANDROID) && !defined(RXCPP_THREAD_LOCAL) 12 #define RXCPP_THREAD_LOCAL __declspec(thread) 14 #define RXCPP_THREAD_LOCAL __thread 18 #if !defined(RXCPP_DELETE) 20 #define RXCPP_DELETE __pragma(warning(disable: 4822)) =delete 22 #define RXCPP_DELETE =delete 26 #define RXCPP_CONCAT(Prefix, Suffix) Prefix ## Suffix 27 #define RXCPP_CONCAT_EVALUATE(Prefix, Suffix) RXCPP_CONCAT(Prefix, Suffix) 29 #define RXCPP_MAKE_IDENTIFIER(Prefix) RXCPP_CONCAT_EVALUATE(Prefix, __LINE__) 33 #if RXCPP_USE_EXCEPTIONS 35 #define RXCPP_CATCH(...) catch(__VA_ARGS__) 38 #define RXCPP_TRY if ((true)) 39 #define RXCPP_CATCH(...) if ((false)) 47 template<
class T>
using value_type_t =
typename std::decay<T>::type::value_type;
48 template<
class T>
using decay_t =
typename std::decay<T>::type;
49 template<
class... TN>
using result_of_t =
typename std::result_of<TN...>::type;
51 template<
class T, std::
size_t size>
53 return std::vector<T>(std::begin(arr), std::end(arr));
57 std::vector<T>
to_vector(std::initializer_list<T> il) {
58 return std::vector<T>(il);
61 template<
class T0,
class... TN>
62 typename std::enable_if<!std::is_array<T0>::value && std::is_pod<T0>::value, std::vector<T0>>::type
to_vector(T0 t0, TN... tn) {
76 template<
class T, T... ValueN>
79 template<
class T,
int Remaining, T Step = 1, T Cursor = 0, T... ValueN>
82 template<
class T, T Step, T Cursor, T... ValueN>
88 template<
class T,
int Remaining, T Step, T Cursor, T... ValueN>
100 static const bool value = B;
102 template<
bool B,
bool... BN>
105 static const bool value = B &&
all_true<BN...>::value;
111 template<
class... BN>
117 static const bool value = B::value;
119 template<
class B,
class... BN>
125 template<
class... BN>
129 template<
class... ValueN>
132 template<
class Value0>
137 template<
class Value0,
class... ValueN>
144 template<
class... ValueN>
147 template<
class Value0>
152 template<
class Value0,
class... ValueN>
158 template<
class... TN>
172 template<
class... TN>
175 template<
class... TN>
179 template<
class Types,
class =types_checked>
181 template<
class... TN>
186 template<
class... TN>
190 template<
class T,
class C = types_checked>
198 template<
class F,
class... ParamN,
int... IndexN>
200 -> decltype(f(std::forward<ParamN>(std::get<IndexN>(p))...)) {
201 return f(std::forward<ParamN>(std::get<IndexN>(p))...);
204 template<
class F_inner,
class F_outer,
class... ParamN,
int... IndexN>
205 auto apply_to_each(std::tuple<ParamN...>& p, values<int, IndexN...>, F_inner& f_inner, F_outer& f_outer)
206 -> decltype(f_outer(std::move(f_inner(std::get<IndexN>(p)))...)) {
207 return f_outer(std::move(f_inner(std::get<IndexN>(p)))...);
210 template<
class F_inner,
class F_outer,
class... ParamN,
int... IndexN>
211 auto apply_to_each(std::tuple<ParamN...>& p, values<int, IndexN...>,
const F_inner& f_inner,
const F_outer& f_outer)
212 -> decltype(f_outer(std::move(f_inner(std::get<IndexN>(p)))...)) {
213 return f_outer(std::move(f_inner(std::get<IndexN>(p)))...);
217 template<
class F,
class... ParamN>
218 auto apply(std::tuple<ParamN...> p, F&& f)
219 -> decltype(
detail::apply(std::move(p),
typename values_from<
int,
sizeof...(ParamN)>::type(), std::forward<F>(f))) {
223 template<
class F_inner,
class F_outer,
class... ParamN>
224 auto apply_to_each(std::tuple<ParamN...>& p, F_inner& f_inner, F_outer& f_outer)
229 template<
class F_inner,
class F_outer,
class... ParamN>
230 auto apply_to_each(std::tuple<ParamN...>& p,
const F_inner& f_inner,
const F_outer& f_outer)
247 template<
class... ParamN>
248 auto operator()(std::tuple<ParamN...> p)
252 template<
class... ParamN>
253 auto operator()(std::tuple<ParamN...> p)
const 263 -> detail::apply_to<F> {
264 return detail::apply_to<F>(std::move(f));
271 template<
class... ParamN>
272 auto operator()(ParamN... pn)
273 -> decltype(std::make_tuple(std::move(pn)...)) {
274 return std::make_tuple(std::move(pn)...);
276 template<
class... ParamN>
277 auto operator()(ParamN... pn)
const 278 -> decltype(std::make_tuple(std::move(pn)...)) {
279 return std::make_tuple(std::move(pn)...);
295 template<
class... ParamN>
296 auto operator()(ParamN... pn)
297 ->
typename std::tuple_element<Index, std::tuple<decay_t<ParamN>...>>::type {
298 return std::get<Index>(std::make_tuple(std::move(pn)...));
300 template<
class... ParamN>
301 auto operator()(ParamN... pn)
const 302 ->
typename std::tuple_element<Index, std::tuple<decay_t<ParamN>...>>::type {
303 return std::get<Index>(std::make_tuple(std::move(pn)...));
311 -> detail::take_at<Index> {
312 return detail::take_at<Index>();
318 template <
template<
class... TN>
class Deferred, class...
AN>
322 struct tag_valid {
static const bool valid =
true;
static const bool value = R;};
323 struct tag_not_valid {
static const bool valid =
false;
static const bool value =
false;};
325 template<
class... CN>
327 template<
class... CN>
330 typedef decltype(check<AN...>(0)) tag_type;
331 static const
bool valid = tag_type::valid;
332 static const
bool value = tag_type::value;
333 static const
bool not_value = valid && !value;
336 template <template<class... TN> class Deferred, class...
AN>
343 template<
class... CN>
345 template<
class... CN>
348 typedef decltype(check<AN...>(0)) tag_type;
350 static const
bool value = tag_type::value;
353 template <template<class... TN> class Deferred, class...
AN>
360 template<
class... CN>
362 template<
class... CN>
365 typedef decltype(check<AN...>(0)) tag_type;
367 static const
bool value = tag_type::value;
370 template <template<class... TN> class Deferred, class...
AN>
377 template<
class... CN>
379 template<
class... CN>
382 typedef decltype(check<AN...>(0)) tag_type;
384 static const
bool value = tag_type::value;
392 template <
template<
class... TN>
class Deferred, class...
AN>
397 template <
template<
class... TN>
class Deferred, class...
AN>
402 template <
template<
class... TN>
class Deferred, class...
AN>
410 template <
class LHS,
class RHS>
412 -> decltype(std::forward<LHS>(lhs) + std::forward<RHS>(rhs))
413 {
return std::forward<LHS>(lhs) + std::forward<RHS>(rhs); }
425 template <
class LHS,
class RHS>
427 -> decltype(std::forward<LHS>(lhs) < std::forward<RHS>(rhs))
428 {
return std::forward<LHS>(lhs) < std::forward<RHS>(rhs); }
440 template<
class T =
void>
443 bool operator()(
const T& lhs,
const T& rhs)
const {
return lhs == rhs; }
449 template<
class LHS,
class RHS>
451 -> decltype(std::forward<LHS>(lhs) == std::forward<RHS>(rhs))
452 {
return std::forward<LHS>(lhs) == std::forward<RHS>(rhs); }
456 template<
class OStream,
class Delimit>
457 struct print_function
461 print_function(OStream& os, Delimit d) : os(os), delimit(std::move(d)) {}
463 template<
class... TN>
464 void operator()(
const TN&... tn)
const {
465 bool inserts[] = {(os << tn,
true)...};
466 inserts[0] = *
reinterpret_cast<bool*
>(inserts);
470 template<
class... TN>
471 void operator()(
const std::tuple<TN...>& tpl)
const {
476 template<
class OStream>
480 endline(OStream& os) : os(os) {}
481 void operator()()
const {
488 template<
class OStream,
class ValueType>
493 insert_value(OStream& os, ValueType v) : os(os), value(std::move(v)) {}
494 void operator()()
const {
498 insert_value& operator=(
const insert_value&) RXCPP_DELETE;
501 template<
class OStream,
class Function>
502 struct insert_function
506 insert_function(OStream& os, Function f) : os(os), call(std::move(f)) {}
507 void operator()()
const {
511 insert_function& operator=(
const insert_function&) RXCPP_DELETE;
514 template<
class OStream,
class Delimit>
516 -> detail::print_function<OStream, Delimit> {
517 return detail::print_function<OStream, Delimit>(os, std::move(d));
522 template<
class OStream>
524 -> detail::endline<OStream> {
525 return detail::endline<OStream>(os);
528 template<
class OStream>
533 template<
class OStream,
class Delimit>
538 template<
class OStream,
class DelimitValue>
544 inline std::string
what(std::exception_ptr ep) {
545 #if RXCPP_USE_EXCEPTIONS 547 catch (
const std::exception& ex) {
550 return std::string(
"<not derived from std::exception>");
554 return std::string(
"<exceptions are disabled>");
563 typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type
574 new (
reinterpret_cast<T*
>(&storage)) T(value);
578 maybe(
const maybe& other)
582 new (
reinterpret_cast<T*
>(&storage)) T(other.get());
590 new (
reinterpret_cast<T*
>(&storage)) T(std::move(other.get()));
601 typedef T value_type;
603 typedef const T* const_iterator;
609 std::size_t size()
const {
610 return is_set ? 1 : 0;
614 return reinterpret_cast<T*
>(&storage);
616 const_iterator begin()
const {
617 return reinterpret_cast<T*
>(&storage);
621 return reinterpret_cast<T*
>(&storage) + size();
623 const_iterator end()
const {
624 return reinterpret_cast<T*
>(&storage) + size();
628 if (!is_set) std::terminate();
629 return reinterpret_cast<T*
>(&storage);
631 const T* operator->()
const {
632 if (!is_set) std::terminate();
633 return reinterpret_cast<T*
>(&storage);
637 if (!is_set) std::terminate();
638 return *
reinterpret_cast<T*
>(&storage);
640 const T& operator*()
const {
641 if (!is_set) std::terminate();
642 return *
reinterpret_cast<T*
>(&storage);
646 if (!is_set) std::terminate();
647 return *
reinterpret_cast<T*
>(&storage);
649 const T&
get()
const {
650 if (!is_set) std::terminate();
651 return *
reinterpret_cast<const T*
>(&storage);
658 reinterpret_cast<T*
>(&storage)->~T();
664 void reset(U&& value) {
666 new (
reinterpret_cast<T*
>(&storage)) T(std::forward<U>(value));
670 maybe& operator=(
const T& other) {
674 maybe& operator=(
const maybe& other) {
675 if (!other.empty()) {
691 auto operator()(T... t)
692 -> decltype(std::make_tuple(t.get()...)) {
693 return std::make_tuple(t.get()...);
696 auto operator()(T... t)
const 697 -> decltype(std::make_tuple(t.get()...)) {
698 return std::make_tuple(t.get()...);
704 inline auto surely(
const std::tuple<T...>& tpl)
711 template<
typename Function>
727 explicit unwinder(Function* functionArg)
728 : function(functionArg)
739 unwinder(
const unwinder&);
740 unwinder& operator=(
const unwinder&);
747 #if !defined(RXCPP_THREAD_LOCAL) 749 class thread_local_storage
755 thread_local_storage()
757 pthread_key_create(&key, NULL);
760 ~thread_local_storage()
762 pthread_key_delete(key);
765 thread_local_storage& operator =(T* p)
767 pthread_setspecific(key, p);
773 return pthread_getspecific(key) == NULL;
778 return static_cast<T*
>(pthread_getspecific(key));
783 return static_cast<T*
>(pthread_getspecific(key));
788 template<
typename,
typename C = types_checked>
792 template <
typename T>
795 typename T::value_type,
796 typename T::traits_type,
797 typename T::allocator_type>::type>
800 typename T::value_type,
801 typename T::traits_type,
802 typename T::allocator_type>, T> {
807 template <
class T,
class = types_checked>
811 struct is_duration<T,
types_checked_t<T, typename T::rep, typename T::period>>
812 : std::is_convertible<T*, std::chrono::duration<typename T::rep, typename T::period>*> {};
816 template <
class T,
class Decayed = decay_t<T>>
823 struct not_value : std::conditional<T::value, std::false_type, std::true_type>::type {
832 #if !RXCPP_USE_EXCEPTIONS 838 virtual const char*
what() = 0;
839 virtual ~error_base() {}
848 struct error_specific :
public error_base {
849 error_specific(
const E& e) : data(e) {}
850 error_specific(E&& e) : data(std::move(e)) {}
852 virtual ~error_specific() {}
854 virtual const char*
what() {
868 #if RXCPP_USE_EXCEPTIONS 874 using error_ptr = std::shared_ptr<util::detail::error_base>;
877 return std::string(ep->what());
891 #if RXCPP_USE_EXCEPTIONS 892 return std::make_exception_ptr(std::forward<E>(e));
895 using pointed_to_type = rxcpp::util::detail::error_specific<e_type>;
896 auto sp = std::make_shared<pointed_to_type>(std::forward<E>(e));
897 return std::static_pointer_cast<rxcpp::util::detail::error_base>(sp);
903 #if RXCPP_USE_EXCEPTIONS 919 template <
typename E>
921 #if RXCPP_USE_EXCEPTIONS 922 throw std::forward<E>(e);
934 #if RXCPP_USE_EXCEPTIONS 944 #if RXCPP_USE_EXCEPTIONS 964 template <
class T,
typename =
void>
969 struct filtered_hash<T, typename std::enable_if<std::is_enum<T>::value>::type> : std::hash<T> {
971 #elif RXCPP_HASH_ENUM_UNDERLYING 973 struct filtered_hash<T, typename std::enable_if<std::is_enum<T>::value>::type> : std::hash<typename std::underlying_type<T>::type> {
978 struct filtered_hash<T, typename std::enable_if<std::is_integral<T>::value>::type> : std::hash<T> {
981 struct filtered_hash<T, typename std::enable_if<std::is_pointer<T>::value>::type> : std::hash<T> {
984 struct filtered_hash<T, typename std::enable_if<rxu::is_string<T>::value>::type> : std::hash<T> {
987 struct filtered_hash<T, typename std::enable_if<std::is_convertible<T, std::chrono::duration<typename T::rep, typename T::period>>::value>::type> {
993 return std::hash<typename argument_type::rep>{}(dur.count());
997 struct filtered_hash<T, typename std::enable_if<std::is_convertible<T, std::chrono::time_point<typename T::clock, typename T::duration>>::value>::type> {
1003 return std::hash<typename argument_type::rep>{}(tp.time_since_epoch().count());
1007 template<
typename,
typename C = rxu::types_checked>
1009 : std::false_type {};
1011 template<
typename T>
1013 typename rxu::types_checked_from<
1014 typename filtered_hash<T>::result_type,
1015 typename filtered_hash<T>::argument_type,
1016 typename std::result_of<filtered_hash<T>(T)>::type>::type>
1017 : std::true_type {};
1021 #define RXCPP_UNWIND(Name, Function) \ 1022 RXCPP_UNWIND_EXPLICIT(uwfunc_ ## Name, Name, Function) 1024 #define RXCPP_UNWIND_AUTO(Function) \ 1025 RXCPP_UNWIND_EXPLICIT(RXCPP_MAKE_IDENTIFIER(uwfunc_), RXCPP_MAKE_IDENTIFIER(unwind_), Function) 1027 #define RXCPP_UNWIND_EXPLICIT(FunctionName, UnwinderName, Function) \ 1028 auto FunctionName = (Function); \ 1029 rxcpp::util::detail::unwinder<decltype(FunctionName)> UnwinderName(std::addressof(FunctionName)) typename std::enable_if< all_true< BN... >::value >::type enable_if_all_true_t
Definition: rx-util.hpp:109
#define RXCPP_TRY
Definition: rx-util.hpp:38
void type
Definition: rx-util.hpp:358
Definition: rx-util.hpp:817
Definition: rx-util.hpp:173
Definition: rx-util.hpp:112
bool operator()(Value0 v0) const
Definition: rx-util.hpp:133
auto print_followed_with(OStream &os, Delimit d) -> decltype(detail::print_followed_with(os, detail::insert_function< OStream, Delimit >(os, std::move(d))))
Definition: rx-util.hpp:534
Definition: rx-util.hpp:191
tag_type::type type
Definition: rx-util.hpp:383
Definition: rx-util.hpp:340
Definition: rx-util.hpp:371
std::shared_ptr< util::detail::error_base > error_ptr
Definition: rx-util.hpp:874
Definition: rx-all.hpp:26
Definition: rx-util.hpp:319
Definition: rx-util.hpp:180
typename std::decay< T >::type::value_type value_type_t
Definition: rx-util.hpp:47
error_ptr make_error_ptr(error_ptr e)
Definition: rx-util.hpp:883
RXCPP_NORETURN void rethrow_current_exception()
Definition: rx-util.hpp:933
std::vector< T > to_vector(const T(&arr) [size])
Definition: rx-util.hpp:52
Definition: rx-util.hpp:357
auto empty() -> decltype(from< T >())
Returns an observable that sends no items to observer and immediately completes, on the specified sch...
Definition: rx-empty.hpp:37
auto AN
Definition: rx-finally.hpp:105
Deferred< typename resolve_type< AN >::type... > resolved_type
Definition: rx-util.hpp:324
R type
Definition: rx-util.hpp:340
R type
Definition: rx-util.hpp:357
#define RXCPP_CATCH(...)
Definition: rx-util.hpp:39
auto println(OStream &os) -> decltype(detail::print_followed_with(os, endline(os)))
Definition: rx-util.hpp:529
Definition: rx-util.hpp:1008
typename std::decay< T >::type decay_t
Definition: rx-util.hpp:48
bool operator()(Value0 v0) const
Definition: rx-util.hpp:148
auto pack() -> detail::pack
Definition: rx-util.hpp:285
RXCPP_NORETURN void throw_exception(E &&e)
Definition: rx-util.hpp:920
auto operator()(LHS &&) const -> decltype(T())
Definition: rx-util.hpp:435
Definition: rx-util.hpp:354
tag_type::type type
Definition: rx-util.hpp:349
Definition: rx-util.hpp:965
Definition: rx-util.hpp:416
auto operator()(LHS &&lhs, RHS &&rhs) const -> decltype(std::forward< LHS >(lhs)==std::forward< RHS >(rhs))
Definition: rx-util.hpp:450
Definition: rx-util.hpp:374
Definition: rx-util.hpp:166
defer_seed_type< Deferred, AN... >::type type
Definition: rx-util.hpp:405
auto apply_to(F f) -> detail::apply_to< F >
Definition: rx-util.hpp:262
Definition: rx-util.hpp:408
typename std::enable_if< all_true_type< BN... >::value >::type enable_if_all_true_type_t
Definition: rx-util.hpp:126
T const & as_const(T &t)
Definition: rx-util.hpp:69
Definition: rx-util.hpp:159
D type
Definition: rx-util.hpp:390
Definition: rx-util.hpp:337
T argument_type
Definition: rx-util.hpp:988
result_type operator()(argument_type const &dur) const
Definition: rx-util.hpp:991
std::size_t result_type
Definition: rx-util.hpp:999
defer_type< Deferred, AN... >::type type
Definition: rx-util.hpp:395
Definition: rx-util.hpp:375
auto endline(OStream &os) -> detail::endline< OStream >
Definition: rx-util.hpp:523
Deferred< typename resolve_type< AN >::type... > resolved_type
Definition: rx-util.hpp:359
Definition: rx-util.hpp:432
Deferred< typename resolve_type< AN >::type... > resolved_type
Definition: rx-util.hpp:376
auto surely(const std::tuple< T... > &tpl) -> decltype(apply(tpl, detail::surely()))
Definition: rx-util.hpp:704
void type
Definition: rx-util.hpp:341
bool operator()(Value0 v0, ValueN... vn) const
Definition: rx-util.hpp:153
int operator()(int cnt, T &&) const
Definition: rx-util.hpp:419
error_ptr current_exception()
Definition: rx-util.hpp:943
auto take_at() -> detail::take_at< Index >
Definition: rx-util.hpp:310
T argument_type
Definition: rx-util.hpp:998
auto apply(std::tuple< ParamN... > p, F &&f) -> decltype(detail::apply(std::move(p), typename values_from< int, sizeof...(ParamN)>::type(), std::forward< F >(f)))
Definition: rx-util.hpp:218
Definition: rx-util.hpp:95
bool operator()(ValueN... vn) const
std::size_t result_type
Definition: rx-util.hpp:989
bool operator()(ValueN... vn) const
bool operator()(Value0 v0, ValueN... vn) const
Definition: rx-util.hpp:138
Definition: rx-util.hpp:341
Definition: rx-util.hpp:423
auto print_followed_by(OStream &os, DelimitValue dv) -> decltype(detail::print_followed_with(os, detail::insert_value< OStream, DelimitValue >(os, std::move(dv))))
Definition: rx-util.hpp:539
Definition: rx-util.hpp:316
typename types_checked_from< TN... >::type types_checked_t
Definition: rx-util.hpp:176
typename expand_value_types< types< TN... > >::type value_types_t
Definition: rx-util.hpp:187
bool operator()(const T &lhs, const T &rhs) const
Definition: rx-util.hpp:443
detail::types_checked_from< TN... >::type type
Definition: rx-util.hpp:173
values_from< T, Remaining - 1, Step, Cursor+Step, ValueN..., Cursor >::type type
Definition: rx-util.hpp:91
RXCPP_NORETURN void rethrow_exception(error_ptr e)
Definition: rx-util.hpp:902
auto operator()(LHS &&lhs, RHS &&rhs) const -> decltype(std::forward< LHS >(lhs)+std::forward< RHS >(rhs))
Definition: rx-util.hpp:411
values< T, ValueN... > type
Definition: rx-util.hpp:85
tag_type::type type
Definition: rx-util.hpp:366
Definition: rx-util.hpp:322
Deferred< typename resolve_type< AN >::type... > resolved_type
Definition: rx-util.hpp:342
Definition: rx-util.hpp:77
result_type operator()(argument_type const &tp) const
Definition: rx-util.hpp:1001
Definition: rx-util.hpp:323
Definition: rx-util.hpp:441
Definition: rx-util.hpp:143
R type
Definition: rx-util.hpp:374
void type
Definition: rx-util.hpp:375
std::string what(std::exception_ptr ep)
Definition: rx-util.hpp:544
auto apply_to_each(std::tuple< ParamN... > &p, const F_inner &f_inner, const F_outer &f_outer) -> decltype(detail::apply_to_each(p, typename values_from< int, sizeof...(ParamN)>::type(), f_inner, f_outer))
Definition: rx-util.hpp:230
Definition: rx-util.hpp:358
typename std::result_of< TN... >::type result_of_t
Definition: rx-util.hpp:49
defer_value_type< Deferred, AN... >::type type
Definition: rx-util.hpp:400
Definition: rx-util.hpp:828
Definition: rx-util.hpp:128
auto operator()(LHS &&lhs, RHS &&rhs) const -> decltype(std::forward< LHS >(lhs)< std::forward< RHS >(rhs))
Definition: rx-util.hpp:426
types_checked type
Definition: rx-util.hpp:191
value_type_t< T > type
Definition: rx-util.hpp:195
Definition: rx-util.hpp:789
Definition: rx-util.hpp:80
auto apply_to_each(std::tuple< ParamN... > &p, F_inner &f_inner, F_outer &f_outer) -> decltype(detail::apply_to_each(p, typename values_from< int, sizeof...(ParamN)>::type(), f_inner, f_outer))
Definition: rx-util.hpp:224