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__) 35 template<
class T>
using value_type_t =
typename std::decay<T>::type::value_type;
36 template<
class T>
using decay_t =
typename std::decay<T>::type;
37 template<
class... TN>
using result_of_t =
typename std::result_of<TN...>::type;
39 template<
class T, std::
size_t size>
41 return std::vector<T>(std::begin(arr), std::end(arr));
45 std::vector<T>
to_vector(std::initializer_list<T> il) {
46 return std::vector<T>(il);
49 template<
class T0,
class... TN>
50 typename std::enable_if<!std::is_array<T0>::value && std::is_pod<T0>::value, std::vector<T0>>::type
to_vector(T0 t0, TN... tn) {
64 template<
class T, T... ValueN>
67 template<
class T,
int Remaining, T Step = 1, T Cursor = 0, T... ValueN>
70 template<
class T, T Step, T Cursor, T... ValueN>
76 template<
class T,
int Remaining, T Step, T Cursor, T... ValueN>
88 static const bool value = B;
90 template<
bool B,
bool... BN>
93 static const bool value = B &&
all_true<BN...>::value;
105 static const bool value = B::value;
107 template<
class B,
class... BN>
113 template<
class... BN>
117 template<
class... ValueN>
118 bool operator()(ValueN... vn)
const;
120 template<
class Value0>
125 template<
class Value0,
class... ValueN>
132 template<
class... ValueN>
133 bool operator()(ValueN... vn)
const;
135 template<
class Value0>
140 template<
class Value0,
class... ValueN>
146 template<
class... TN>
160 template<
class... TN>
163 template<
class... TN>
167 template<
class Types,
class =types_checked>
169 template<
class... TN>
174 template<
class... TN>
178 template<
class T,
class C = types_checked>
186 template<
class F,
class... ParamN,
int... IndexN>
188 -> decltype(f(std::forward<ParamN>(std::get<IndexN>(p))...)) {
189 return f(std::forward<ParamN>(std::get<IndexN>(p))...);
192 template<
class F_inner,
class F_outer,
class... ParamN,
int... IndexN>
194 -> decltype(f_outer(std::move(f_inner(std::get<IndexN>(p)))...)) {
195 return f_outer(std::move(f_inner(std::get<IndexN>(p)))...);
198 template<
class F_inner,
class F_outer,
class... ParamN,
int... IndexN>
200 -> decltype(f_outer(std::move(f_inner(std::get<IndexN>(p)))...)) {
201 return f_outer(std::move(f_inner(std::get<IndexN>(p)))...);
205 template<
class F,
class... ParamN>
206 auto apply(std::tuple<ParamN...> p, F&& f)
207 -> decltype(
detail::apply(std::move(p),
typename values_from<
int,
sizeof...(ParamN)>::type(), std::forward<F>(f))) {
211 template<
class F_inner,
class F_outer,
class... ParamN>
212 auto apply_to_each(std::tuple<ParamN...>& p, F_inner& f_inner, F_outer& f_outer)
217 template<
class F_inner,
class F_outer,
class... ParamN>
218 auto apply_to_each(std::tuple<ParamN...>& p,
const F_inner& f_inner,
const F_outer& f_outer)
235 template<
class... ParamN>
236 auto operator()(std::tuple<ParamN...> p)
240 template<
class... ParamN>
241 auto operator()(std::tuple<ParamN...> p)
const 251 -> detail::apply_to<F> {
252 return detail::apply_to<F>(std::move(f));
259 template<
class... ParamN>
260 auto operator()(ParamN... pn)
261 -> decltype(std::make_tuple(std::move(pn)...)) {
262 return std::make_tuple(std::move(pn)...);
264 template<
class... ParamN>
265 auto operator()(ParamN... pn)
const 266 -> decltype(std::make_tuple(std::move(pn)...)) {
267 return std::make_tuple(std::move(pn)...);
283 template<
class... ParamN>
284 auto operator()(ParamN... pn)
285 ->
typename std::tuple_element<Index, std::tuple<decay_t<ParamN>...>>::type {
286 return std::get<Index>(std::make_tuple(std::move(pn)...));
288 template<
class... ParamN>
289 auto operator()(ParamN... pn)
const 290 ->
typename std::tuple_element<Index, std::tuple<decay_t<ParamN>...>>::type {
291 return std::get<Index>(std::make_tuple(std::move(pn)...));
299 -> detail::take_at<Index> {
300 return detail::take_at<Index>();
306 template <
template<
class... TN>
class Deferred, class...
AN>
310 struct tag_valid {
static const bool valid =
true;
static const bool value = R;};
311 struct tag_not_valid {
static const bool valid =
false;
static const bool value =
false;};
313 template<
class... CN>
315 template<
class... CN>
318 typedef decltype(check<AN...>(0)) tag_type;
319 static const
bool valid = tag_type::valid;
320 static const
bool value = tag_type::value;
321 static const
bool not_value = valid && !value;
324 template <template<class... TN> class Deferred, class...
AN>
331 template<
class... CN>
333 template<
class... CN>
336 typedef decltype(check<AN...>(0)) tag_type;
338 static const
bool value = tag_type::value;
341 template <template<class... TN> class Deferred, class...
AN>
345 struct tag_valid {
typedef R type;
static const bool value =
true;};
348 template<
class... CN>
350 template<
class... CN>
353 typedef decltype(check<AN...>(0)) tag_type;
354 typedef typename tag_type::type type;
355 static const
bool value = tag_type::value;
358 template <template<class... TN> class Deferred, class...
AN>
362 struct tag_valid {
typedef R type;
static const bool value =
true;};
365 template<
class... CN>
367 template<
class... CN>
370 typedef decltype(check<AN...>(0)) tag_type;
371 typedef typename tag_type::type type;
372 static const
bool value = tag_type::value;
380 template <
template<
class... TN>
class Deferred, class...
AN>
383 typedef typename defer_type<Deferred,
AN...>::type
type;
385 template <
template<
class... TN>
class Deferred, class...
AN>
388 typedef typename defer_value_type<Deferred,
AN...>::type
type;
390 template <
template<
class... TN>
class Deferred, class...
AN>
393 typedef typename defer_seed_type<Deferred,
AN...>::type
type;
398 template <
class LHS,
class RHS>
400 -> decltype(std::forward<LHS>(lhs) + std::forward<RHS>(rhs))
401 {
return std::forward<LHS>(lhs) + std::forward<RHS>(rhs); }
413 template <
class LHS,
class RHS>
415 -> decltype(std::forward<LHS>(lhs) < std::forward<RHS>(rhs))
416 {
return std::forward<LHS>(lhs) < std::forward<RHS>(rhs); }
419 template<
class T =
void>
422 bool operator()(
const T& lhs,
const T& rhs)
const {
return lhs == rhs; }
428 template<
class LHS,
class RHS>
430 -> decltype(std::forward<LHS>(lhs) == std::forward<RHS>(rhs))
431 {
return std::forward<LHS>(lhs) == std::forward<RHS>(rhs); }
435 template<
class OStream,
class Delimit>
436 struct print_function
440 print_function(OStream& os, Delimit d) : os(os), delimit(std::move(d)) {}
442 template<
class... TN>
443 void operator()(
const TN&... tn)
const {
444 bool inserts[] = {(os << tn,
true)...};
445 inserts[0] = *
reinterpret_cast<bool*
>(inserts);
449 template<
class... TN>
450 void operator()(
const std::tuple<TN...>& tpl)
const {
455 template<
class OStream>
459 endline(OStream& os) : os(os) {}
460 void operator()()
const {
467 template<
class OStream,
class ValueType>
472 insert_value(OStream& os, ValueType v) : os(os), value(std::move(v)) {}
473 void operator()()
const {
477 insert_value& operator=(
const insert_value&) RXCPP_DELETE;
480 template<
class OStream,
class Function>
481 struct insert_function
485 insert_function(OStream& os, Function f) : os(os), call(std::move(f)) {}
486 void operator()()
const {
490 insert_function& operator=(
const insert_function&) RXCPP_DELETE;
493 template<
class OStream,
class Delimit>
495 -> detail::print_function<OStream, Delimit> {
496 return detail::print_function<OStream, Delimit>(os, std::move(d));
501 template<
class OStream>
503 -> detail::endline<OStream> {
504 return detail::endline<OStream>(os);
507 template<
class OStream>
512 template<
class OStream,
class Delimit>
517 template<
class OStream,
class DelimitValue>
523 inline std::string
what(std::exception_ptr ep) {
524 try {std::rethrow_exception(ep);}
525 catch (
const std::exception& ex) {
528 return std::string();
537 typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type
548 new (
reinterpret_cast<T*
>(&storage)) T(value);
552 maybe(
const maybe& other)
556 new (
reinterpret_cast<T*
>(&storage)) T(other.get());
564 new (
reinterpret_cast<T*
>(&storage)) T(std::move(other.get()));
575 typedef T value_type;
577 typedef const T* const_iterator;
583 std::size_t size()
const {
584 return is_set ? 1 : 0;
588 return reinterpret_cast<T*
>(&storage);
590 const_iterator begin()
const {
591 return reinterpret_cast<T*
>(&storage);
595 return reinterpret_cast<T*
>(&storage) + size();
597 const_iterator end()
const {
598 return reinterpret_cast<T*
>(&storage) + size();
602 if (!is_set) std::terminate();
603 return reinterpret_cast<T*
>(&storage);
605 const T* operator->()
const {
606 if (!is_set) std::terminate();
607 return reinterpret_cast<T*
>(&storage);
611 if (!is_set) std::terminate();
612 return *
reinterpret_cast<T*
>(&storage);
614 const T& operator*()
const {
615 if (!is_set) std::terminate();
616 return *
reinterpret_cast<T*
>(&storage);
620 if (!is_set) std::terminate();
621 return *
reinterpret_cast<T*
>(&storage);
623 const T&
get()
const {
624 if (!is_set) std::terminate();
625 return *
reinterpret_cast<const T*
>(&storage);
632 reinterpret_cast<T*
>(&storage)->~T();
638 void reset(U&& value) {
640 new (
reinterpret_cast<T*
>(&storage)) T(std::forward<U>(value));
644 maybe& operator=(
const T& other) {
648 maybe& operator=(
const maybe& other) {
649 if (!other.empty()) {
665 auto operator()(T... t)
666 -> decltype(std::make_tuple(t.get()...)) {
667 return std::make_tuple(t.get()...);
670 auto operator()(T... t)
const 671 -> decltype(std::make_tuple(t.get()...)) {
672 return std::make_tuple(t.get()...);
678 inline auto surely(
const std::tuple<T...>& tpl)
685 template<
typename Function>
701 explicit unwinder(Function* functionArg)
702 :
function(functionArg)
713 unwinder(
const unwinder&);
714 unwinder& operator=(
const unwinder&);
721 #if !defined(RXCPP_THREAD_LOCAL) 723 class thread_local_storage
729 thread_local_storage()
731 pthread_key_create(&key, NULL);
734 ~thread_local_storage()
736 pthread_key_delete(key);
739 thread_local_storage& operator =(T* p)
741 pthread_setspecific(key, p);
747 return pthread_getspecific(key) == NULL;
752 return static_cast<T*
>(pthread_getspecific(key));
757 return static_cast<T*
>(pthread_getspecific(key));
762 template<
typename,
typename C = types_checked>
766 template <
typename T>
769 typename T::value_type,
770 typename T::traits_type,
771 typename T::allocator_type>::type>
774 typename T::value_type,
775 typename T::traits_type,
776 typename T::allocator_type>, T> {
781 template <
class T,
class = types_checked>
785 struct is_duration<T, types_checked_t<T, typename T::rep, typename T::period>>
786 : std::is_convertible<T*, std::chrono::duration<typename T::rep, typename T::period>*> {};
790 template <
class T,
class Decayed = decay_t<T>>
797 struct not_value : std::conditional<T::value, std::false_type, std::true_type>::type {
815 template <
class T,
typename =
void>
820 struct filtered_hash<T, typename std::enable_if<std::is_enum<T>::value>::type> : std::hash<T> {
822 #elif RXCPP_HASH_ENUM_UNDERLYING 824 struct filtered_hash<T, typename std::enable_if<std::is_enum<T>::value>::type> : std::hash<typename std::underlying_type<T>::type> {
829 struct filtered_hash<T, typename std::enable_if<std::is_integral<T>::value>::type> : std::hash<T> {
832 struct filtered_hash<T, typename std::enable_if<std::is_pointer<T>::value>::type> : std::hash<T> {
835 struct filtered_hash<T, typename std::enable_if<rxu::is_string<T>::value>::type> : std::hash<T> {
838 struct filtered_hash<T, typename std::enable_if<std::is_convertible<T, std::chrono::duration<typename T::rep, typename T::period>>::value>::type> {
844 return std::hash<typename argument_type::rep>{}(dur.count());
848 struct filtered_hash<T, typename std::enable_if<std::is_convertible<T, std::chrono::time_point<typename T::clock, typename T::duration>>::value>::type> {
854 return std::hash<typename argument_type::rep>{}(tp.time_since_epoch().count());
858 template<
typename,
typename C = rxu::types_checked>
860 : std::false_type {};
864 typename rxu::types_checked_from<
865 typename filtered_hash<T>::result_type,
866 typename filtered_hash<T>::argument_type,
867 typename std::result_of<filtered_hash<T>(T)>::type>::type>
872 #define RXCPP_UNWIND(Name, Function) \ 873 RXCPP_UNWIND_EXPLICIT(uwfunc_ ## Name, Name, Function) 875 #define RXCPP_UNWIND_AUTO(Function) \ 876 RXCPP_UNWIND_EXPLICIT(RXCPP_MAKE_IDENTIFIER(uwfunc_), RXCPP_MAKE_IDENTIFIER(unwind_), Function) 878 #define RXCPP_UNWIND_EXPLICIT(FunctionName, UnwinderName, Function) \ 879 auto FunctionName = (Function); \ 880 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:97
Definition: rx-util.hpp:791
bool operator()(Value0 v0) const
Definition: rx-util.hpp:136
Definition: rx-util.hpp:161
Definition: rx-util.hpp:100
bool operator()(Value0 v0, ValueN...vn) const
Definition: rx-util.hpp:141
bool operator()(Value0 v0, ValueN...vn) const
Definition: rx-util.hpp:126
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:513
Definition: rx-util.hpp:179
Definition: rx-util.hpp:328
Definition: rx-util.hpp:359
Definition: rx-all.hpp:26
Definition: rx-util.hpp:307
Definition: rx-util.hpp:168
int operator()(int cnt, T &&) const
Definition: rx-util.hpp:407
typename std::decay< T >::type::value_type value_type_t
Definition: rx-util.hpp:35
Definition: rx-util.hpp:345
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:312
R type
Definition: rx-util.hpp:328
auto println(OStream &os) -> decltype(detail::print_followed_with(os, endline(os)))
Definition: rx-util.hpp:508
Definition: rx-util.hpp:859
typename std::decay< T >::type decay_t
Definition: rx-util.hpp:36
auto pack() -> detail::pack
Definition: rx-util.hpp:273
Definition: rx-util.hpp:342
bool operator()(Value0 v0) const
Definition: rx-util.hpp:121
tag_type::type type
Definition: rx-util.hpp:337
result_type operator()(argument_type const &dur) const
Definition: rx-util.hpp:842
typename expand_value_types< types< TN... >>::type value_types_t
Definition: rx-util.hpp:175
Definition: rx-util.hpp:816
Definition: rx-util.hpp:404
result_type operator()(argument_type const &tp) const
Definition: rx-util.hpp:852
auto operator()(LHS &&lhs, RHS &&rhs) const -> decltype(std::forward< LHS >(lhs)+std::forward< RHS >(rhs))
Definition: rx-util.hpp:399
Definition: rx-util.hpp:362
Definition: rx-util.hpp:154
defer_seed_type< Deferred, AN... >::type type
Definition: rx-util.hpp:393
auto apply_to(F f) -> detail::apply_to< F >
Definition: rx-util.hpp:250
auto operator()(LHS &&lhs, RHS &&rhs) const -> decltype(std::forward< LHS >(lhs)==std::forward< RHS >(rhs))
Definition: rx-util.hpp:429
Definition: rx-util.hpp:396
typename std::enable_if< all_true_type< BN... >::value >::type enable_if_all_true_type_t
Definition: rx-util.hpp:114
T const & as_const(T &t)
Definition: rx-util.hpp:57
Definition: rx-util.hpp:147
D type
Definition: rx-util.hpp:378
Definition: rx-util.hpp:325
T argument_type
Definition: rx-util.hpp:839
std::size_t result_type
Definition: rx-util.hpp:850
auto operator()(LHS &&lhs, RHS &&rhs) const -> decltype(std::forward< LHS >(lhs)< std::forward< RHS >(rhs))
Definition: rx-util.hpp:414
defer_type< Deferred, AN... >::type type
Definition: rx-util.hpp:383
Definition: rx-util.hpp:363
auto endline(OStream &os) -> detail::endline< OStream >
Definition: rx-util.hpp:502
Deferred< typename resolve_type< AN >::type... > resolved_type
Definition: rx-util.hpp:347
Deferred< typename resolve_type< AN >::type... > resolved_type
Definition: rx-util.hpp:364
auto surely(const std::tuple< T... > &tpl) -> decltype(apply(tpl, detail::surely()))
Definition: rx-util.hpp:678
void type
Definition: rx-util.hpp:329
auto take_at() -> detail::take_at< Index >
Definition: rx-util.hpp:298
T argument_type
Definition: rx-util.hpp:849
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:206
Definition: rx-util.hpp:83
std::size_t result_type
Definition: rx-util.hpp:840
Definition: rx-util.hpp:329
Definition: rx-util.hpp:411
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:518
Definition: rx-util.hpp:304
typename types_checked_from< TN... >::type types_checked_t
Definition: rx-util.hpp:164
detail::types_checked_from< TN... >::type type
Definition: rx-util.hpp:161
values_from< T, Remaining-1, Step, Cursor+Step, ValueN..., Cursor >::type type
Definition: rx-util.hpp:79
values< T, ValueN... > type
Definition: rx-util.hpp:73
Definition: rx-util.hpp:310
Deferred< typename resolve_type< AN >::type... > resolved_type
Definition: rx-util.hpp:330
bool operator()(const T &lhs, const T &rhs) const
Definition: rx-util.hpp:422
Definition: rx-util.hpp:65
Definition: rx-util.hpp:311
Definition: rx-util.hpp:420
Definition: rx-util.hpp:131
std::string what(std::exception_ptr ep)
Definition: rx-util.hpp:523
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:218
Definition: rx-util.hpp:346
typename std::result_of< TN... >::type result_of_t
Definition: rx-util.hpp:37
defer_value_type< Deferred, AN... >::type type
Definition: rx-util.hpp:388
Definition: rx-util.hpp:802
Definition: rx-util.hpp:116
types_checked type
Definition: rx-util.hpp:179
value_type_t< T > type
Definition: rx-util.hpp:183
std::vector< T > to_vector(const T(&arr)[size])
Definition: rx-util.hpp:40
Definition: rx-util.hpp:763
Definition: rx-util.hpp:68
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:212