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) {
54 template<
class T, T... ValueN>
57 template<
class T,
int Remaining, T Step = 1, T Cursor = 0, T... ValueN>
60 template<
class T, T Step, T Cursor, T... ValueN>
66 template<
class T,
int Remaining, T Step, T Cursor, T... ValueN>
78 static const bool value = B;
80 template<
bool B,
bool... BN>
83 static const bool value = B &&
all_true<BN...>::value;
95 static const bool value = B::value;
97 template<
class B,
class... BN>
103 template<
class... BN>
107 template<
class... ValueN>
110 template<
class Value0>
115 template<
class Value0,
class... ValueN>
122 template<
class... ValueN>
125 template<
class Value0>
130 template<
class Value0,
class... ValueN>
136 template<
class... TN>
150 template<
class... TN>
153 template<
class... TN>
157 template<
class Types,
class =types_checked>
159 template<
class... TN>
164 template<
class... TN>
168 template<
class T,
class C = types_checked>
176 template<
class F,
class... ParamN,
int... IndexN>
178 -> decltype(f(std::forward<ParamN>(std::get<IndexN>(p))...)) {
179 return f(std::forward<ParamN>(std::get<IndexN>(p))...);
182 template<
class F_inner,
class F_outer,
class... ParamN,
int... IndexN>
183 auto apply_to_each(std::tuple<ParamN...>& p, values<int, IndexN...>, F_inner& f_inner, F_outer& f_outer)
184 -> decltype(f_outer(std::move(f_inner(std::get<IndexN>(p)))...)) {
185 return f_outer(std::move(f_inner(std::get<IndexN>(p)))...);
188 template<
class F_inner,
class F_outer,
class... ParamN,
int... IndexN>
189 auto apply_to_each(std::tuple<ParamN...>& p, values<int, IndexN...>,
const F_inner& f_inner,
const F_outer& f_outer)
190 -> decltype(f_outer(std::move(f_inner(std::get<IndexN>(p)))...)) {
191 return f_outer(std::move(f_inner(std::get<IndexN>(p)))...);
195 template<
class F,
class... ParamN>
196 auto apply(std::tuple<ParamN...> p, F&& f)
197 -> decltype(
detail::apply(std::move(p),
typename values_from<
int,
sizeof...(ParamN)>::type(), std::forward<F>(f))) {
201 template<
class F_inner,
class F_outer,
class... ParamN>
202 auto apply_to_each(std::tuple<ParamN...>& p, F_inner& f_inner, F_outer& f_outer)
207 template<
class F_inner,
class F_outer,
class... ParamN>
208 auto apply_to_each(std::tuple<ParamN...>& p,
const F_inner& f_inner,
const F_outer& f_outer)
225 template<
class... ParamN>
226 auto operator()(std::tuple<ParamN...> p)
230 template<
class... ParamN>
231 auto operator()(std::tuple<ParamN...> p)
const 241 -> detail::apply_to<F> {
242 return detail::apply_to<F>(std::move(f));
249 template<
class... ParamN>
250 auto operator()(ParamN... pn)
251 -> decltype(std::make_tuple(std::move(pn)...)) {
252 return std::make_tuple(std::move(pn)...);
254 template<
class... ParamN>
255 auto operator()(ParamN... pn)
const 256 -> decltype(std::make_tuple(std::move(pn)...)) {
257 return std::make_tuple(std::move(pn)...);
273 template<
class... ParamN>
274 auto operator()(ParamN... pn)
275 ->
typename std::tuple_element<Index, std::tuple<decay_t<ParamN>...>>::type {
276 return std::get<Index>(std::make_tuple(std::move(pn)...));
278 template<
class... ParamN>
279 auto operator()(ParamN... pn)
const 280 ->
typename std::tuple_element<Index, std::tuple<decay_t<ParamN>...>>::type {
281 return std::get<Index>(std::make_tuple(std::move(pn)...));
289 -> detail::take_at<Index> {
290 return detail::take_at<Index>();
296 template <
template<
class... TN>
class Deferred, class...
AN>
300 struct tag_valid {
static const bool valid =
true;
static const bool value = R;};
301 struct tag_not_valid {
static const bool valid =
false;
static const bool value =
false;};
303 template<
class... CN>
305 template<
class... CN>
308 typedef decltype(check<AN...>(0)) tag_type;
309 static const
bool valid = tag_type::valid;
310 static const
bool value = tag_type::value;
311 static const
bool not_value = valid && !value;
314 template <template<class... TN> class Deferred, class...
AN>
321 template<
class... CN>
323 template<
class... CN>
326 typedef decltype(check<AN...>(0)) tag_type;
328 static const
bool value = tag_type::value;
331 template <template<class... TN> class Deferred, class...
AN>
338 template<
class... CN>
340 template<
class... CN>
343 typedef decltype(check<AN...>(0)) tag_type;
345 static const
bool value = tag_type::value;
348 template <template<class... TN> class Deferred, class...
AN>
355 template<
class... CN>
357 template<
class... CN>
360 typedef decltype(check<AN...>(0)) tag_type;
362 static const
bool value = tag_type::value;
370 template <
template<
class... TN>
class Deferred, class...
AN>
375 template <
template<
class... TN>
class Deferred, class...
AN>
380 template <
template<
class... TN>
class Deferred, class...
AN>
388 template <
class LHS,
class RHS>
390 -> decltype(std::forward<LHS>(lhs) + std::forward<RHS>(rhs))
391 {
return std::forward<LHS>(lhs) + std::forward<RHS>(rhs); }
403 template <
class LHS,
class RHS>
405 -> decltype(std::forward<LHS>(lhs) < std::forward<RHS>(rhs))
406 {
return std::forward<LHS>(lhs) < std::forward<RHS>(rhs); }
409 template<
class T =
void>
412 bool operator()(
const T& lhs,
const T& rhs)
const {
return lhs == rhs; }
418 template<
class LHS,
class RHS>
420 -> decltype(std::forward<LHS>(lhs) == std::forward<RHS>(rhs))
421 {
return std::forward<LHS>(lhs) == std::forward<RHS>(rhs); }
425 template<
class OStream,
class Delimit>
426 struct print_function
430 print_function(OStream& os, Delimit d) : os(os), delimit(std::move(d)) {}
432 template<
class... TN>
433 void operator()(
const TN&... tn)
const {
434 bool inserts[] = {(os << tn,
true)...};
435 inserts[0] = *reinterpret_cast<bool*>(inserts);
439 template<
class... TN>
440 void operator()(
const std::tuple<TN...>& tpl)
const {
445 template<
class OStream>
449 endline(OStream& os) : os(os) {}
450 void operator()()
const {
457 template<
class OStream,
class ValueType>
462 insert_value(OStream& os, ValueType v) : os(os), value(std::move(v)) {}
463 void operator()()
const {
467 insert_value& operator=(
const insert_value&) RXCPP_DELETE;
470 template<
class OStream,
class Function>
471 struct insert_function
475 insert_function(OStream& os, Function f) : os(os), call(std::move(f)) {}
476 void operator()()
const {
480 insert_function& operator=(
const insert_function&) RXCPP_DELETE;
483 template<
class OStream,
class Delimit>
485 -> detail::print_function<OStream, Delimit> {
486 return detail::print_function<OStream, Delimit>(os, std::move(d));
491 template<
class OStream>
493 -> detail::endline<OStream> {
494 return detail::endline<OStream>(os);
497 template<
class OStream>
502 template<
class OStream,
class Delimit>
507 template<
class OStream,
class DelimitValue>
513 inline std::string
what(std::exception_ptr ep) {
514 try {std::rethrow_exception(ep);}
515 catch (
const std::exception& ex) {
518 return std::string();
527 typename std::aligned_storage<
sizeof(T), std::alignment_of<T>::value>::type
538 new (reinterpret_cast<T*>(&storage)) T(value);
542 maybe(
const maybe& other)
546 new (reinterpret_cast<T*>(&storage)) T(other.get());
554 new (reinterpret_cast<T*>(&storage)) T(std::move(other.get()));
565 typedef T value_type;
567 typedef const T* const_iterator;
573 std::size_t size()
const {
574 return is_set ? 1 : 0;
578 return reinterpret_cast<T*>(&storage);
580 const_iterator begin()
const {
581 return reinterpret_cast<T*>(&storage);
585 return reinterpret_cast<T*>(&storage) + size();
587 const_iterator end()
const {
588 return reinterpret_cast<T*>(&storage) + size();
592 if (!is_set) std::terminate();
593 return reinterpret_cast<T*>(&storage);
595 const T* operator->()
const {
596 if (!is_set) std::terminate();
597 return reinterpret_cast<T*>(&storage);
601 if (!is_set) std::terminate();
602 return *reinterpret_cast<T*>(&storage);
604 const T& operator*()
const {
605 if (!is_set) std::terminate();
606 return *reinterpret_cast<T*>(&storage);
610 if (!is_set) std::terminate();
611 return *reinterpret_cast<T*>(&storage);
613 const T& get()
const {
614 if (!is_set) std::terminate();
615 return *reinterpret_cast<const T*>(&storage);
622 reinterpret_cast<T*>(&storage)->~T();
628 void reset(U&& value) {
630 new (reinterpret_cast<T*>(&storage)) T(std::forward<U>(value));
634 maybe& operator=(
const T& other) {
638 maybe& operator=(
const maybe& other) {
639 if (!other.empty()) {
655 auto operator()(T... t)
656 -> decltype(std::make_tuple(t.get()...)) {
657 return std::make_tuple(t.get()...);
660 auto operator()(T... t)
const 661 -> decltype(std::make_tuple(t.get()...)) {
662 return std::make_tuple(t.get()...);
668 inline auto surely(
const std::tuple<T...>& tpl)
675 template<
typename Function>
691 explicit unwinder(Function* functionArg)
692 : function(functionArg)
703 unwinder(
const unwinder&);
704 unwinder& operator=(
const unwinder&);
711 #if !defined(RXCPP_THREAD_LOCAL) 713 class thread_local_storage
719 thread_local_storage()
721 pthread_key_create(&key, NULL);
724 ~thread_local_storage()
726 pthread_key_delete(key);
729 thread_local_storage& operator =(T* p)
731 pthread_setspecific(key, p);
737 return pthread_getspecific(key) == NULL;
742 return static_cast<T*>(pthread_getspecific(key));
747 return static_cast<T*>(pthread_getspecific(key));
752 template<
typename,
typename C = types_checked>
756 template <
typename T>
759 typename T::value_type,
760 typename T::traits_type,
761 typename T::allocator_type>::type>
764 typename T::value_type,
765 typename T::traits_type,
766 typename T::allocator_type>, T> {
771 template <
class T,
class = types_checked>
775 struct is_duration<T,
types_checked_t<T, typename T::rep, typename T::period>>
776 : std::is_convertible<T*, std::chrono::duration<typename T::rep, typename T::period>*> {};
780 template <
class T,
class Decayed = decay_t<T>>
787 struct not_value : std::conditional<T::value, std::false_type, std::true_type>::type {
805 template <
class T,
typename =
void>
810 struct filtered_hash<T, typename std::enable_if<std::is_enum<T>::value>::type> : std::hash<T> {
812 #elif RXCPP_HASH_ENUM_UNDERLYING 814 struct filtered_hash<T, typename std::enable_if<std::is_enum<T>::value>::type> : std::hash<typename std::underlying_type<T>::type> {
819 struct filtered_hash<T, typename std::enable_if<std::is_integral<T>::value>::type> : std::hash<T> {
822 struct filtered_hash<T, typename std::enable_if<std::is_pointer<T>::value>::type> : std::hash<T> {
825 struct filtered_hash<T, typename std::enable_if<rxu::is_string<T>::value>::type> : std::hash<T> {
828 struct filtered_hash<T, typename std::enable_if<std::is_convertible<T, std::chrono::duration<typename T::rep, typename T::period>>::value>::type> {
834 return std::hash<typename argument_type::rep>{}(dur.count());
838 struct filtered_hash<T, typename std::enable_if<std::is_convertible<T, std::chrono::time_point<typename T::clock, typename T::duration>>::value>::type> {
844 return std::hash<typename argument_type::rep>{}(tp.time_since_epoch().count());
848 template<
typename,
typename C = rxu::types_checked>
850 : std::false_type {};
854 typename rxu::types_checked_from<
855 typename filtered_hash<T>::result_type,
856 typename filtered_hash<T>::argument_type,
857 typename std::result_of<filtered_hash<T>(T)>::type>::type>
862 #define RXCPP_UNWIND(Name, Function) \ 863 RXCPP_UNWIND_EXPLICIT(uwfunc_ ## Name, Name, Function) 865 #define RXCPP_UNWIND_AUTO(Function) \ 866 RXCPP_UNWIND_EXPLICIT(RXCPP_MAKE_IDENTIFIER(uwfunc_), RXCPP_MAKE_IDENTIFIER(unwind_), Function) 868 #define RXCPP_UNWIND_EXPLICIT(FunctionName, UnwinderName, Function) \ 869 auto FunctionName = (Function); \ 870 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:87
void type
Definition: rx-util.hpp:336
Definition: rx-util.hpp:781
Definition: rx-util.hpp:151
Definition: rx-util.hpp:90
bool operator()(Value0 v0) const
Definition: rx-util.hpp:111
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:503
Definition: rx-util.hpp:169
tag_type::type type
Definition: rx-util.hpp:361
Definition: rx-util.hpp:318
Definition: rx-util.hpp:349
Definition: rx-all.hpp:26
Definition: rx-util.hpp:297
Definition: rx-util.hpp:158
typename std::decay< T >::type::value_type value_type_t
Definition: rx-util.hpp:35
std::vector< T > to_vector(const T(&arr) [size])
Definition: rx-util.hpp:40
Definition: rx-util.hpp:335
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:302
R type
Definition: rx-util.hpp:318
R type
Definition: rx-util.hpp:335
auto println(OStream &os) -> decltype(detail::print_followed_with(os, endline(os)))
Definition: rx-util.hpp:498
Definition: rx-util.hpp:849
typename std::decay< T >::type decay_t
Definition: rx-util.hpp:36
bool operator()(Value0 v0) const
Definition: rx-util.hpp:126
auto pack() -> detail::pack
Definition: rx-util.hpp:263
Definition: rx-util.hpp:332
tag_type::type type
Definition: rx-util.hpp:327
Definition: rx-util.hpp:806
Definition: rx-util.hpp:394
auto operator()(LHS &&lhs, RHS &&rhs) const -> decltype(std::forward< LHS >(lhs)==std::forward< RHS >(rhs))
Definition: rx-util.hpp:419
Definition: rx-util.hpp:352
Definition: rx-util.hpp:144
defer_seed_type< Deferred, AN... >::type type
Definition: rx-util.hpp:383
auto apply_to(F f) -> detail::apply_to< F >
Definition: rx-util.hpp:240
Definition: rx-util.hpp:386
typename std::enable_if< all_true_type< BN... >::value >::type enable_if_all_true_type_t
Definition: rx-util.hpp:104
Definition: rx-util.hpp:137
D type
Definition: rx-util.hpp:368
Definition: rx-util.hpp:315
T argument_type
Definition: rx-util.hpp:829
result_type operator()(argument_type const &dur) const
Definition: rx-util.hpp:832
std::size_t result_type
Definition: rx-util.hpp:840
defer_type< Deferred, AN... >::type type
Definition: rx-util.hpp:373
Definition: rx-util.hpp:353
auto endline(OStream &os) -> detail::endline< OStream >
Definition: rx-util.hpp:492
Deferred< typename resolve_type< AN >::type... > resolved_type
Definition: rx-util.hpp:337
Deferred< typename resolve_type< AN >::type... > resolved_type
Definition: rx-util.hpp:354
auto surely(const std::tuple< T... > &tpl) -> decltype(apply(tpl, detail::surely()))
Definition: rx-util.hpp:668
void type
Definition: rx-util.hpp:319
bool operator()(Value0 v0, ValueN... vn) const
Definition: rx-util.hpp:131
int operator()(int cnt, T &&) const
Definition: rx-util.hpp:397
auto take_at() -> detail::take_at< Index >
Definition: rx-util.hpp:288
T argument_type
Definition: rx-util.hpp:839
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:196
Definition: rx-util.hpp:73
bool operator()(ValueN... vn) const
std::size_t result_type
Definition: rx-util.hpp:830
bool operator()(ValueN... vn) const
bool operator()(Value0 v0, ValueN... vn) const
Definition: rx-util.hpp:116
Definition: rx-util.hpp:319
Definition: rx-util.hpp:401
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:508
Definition: rx-util.hpp:294
typename types_checked_from< TN... >::type types_checked_t
Definition: rx-util.hpp:154
typename expand_value_types< types< TN... > >::type value_types_t
Definition: rx-util.hpp:165
bool operator()(const T &lhs, const T &rhs) const
Definition: rx-util.hpp:412
detail::types_checked_from< TN... >::type type
Definition: rx-util.hpp:151
values_from< T, Remaining - 1, Step, Cursor+Step, ValueN..., Cursor >::type type
Definition: rx-util.hpp:69
auto operator()(LHS &&lhs, RHS &&rhs) const -> decltype(std::forward< LHS >(lhs)+std::forward< RHS >(rhs))
Definition: rx-util.hpp:389
values< T, ValueN... > type
Definition: rx-util.hpp:63
tag_type::type type
Definition: rx-util.hpp:344
Definition: rx-util.hpp:300
Deferred< typename resolve_type< AN >::type... > resolved_type
Definition: rx-util.hpp:320
Definition: rx-util.hpp:55
result_type operator()(argument_type const &tp) const
Definition: rx-util.hpp:842
Definition: rx-util.hpp:301
Definition: rx-util.hpp:410
Definition: rx-util.hpp:121
R type
Definition: rx-util.hpp:352
void type
Definition: rx-util.hpp:353
std::string what(std::exception_ptr ep)
Definition: rx-util.hpp:513
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:208
Definition: rx-util.hpp:336
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:378
Definition: rx-util.hpp:792
Definition: rx-util.hpp:106
auto operator()(LHS &&lhs, RHS &&rhs) const -> decltype(std::forward< LHS >(lhs)< std::forward< RHS >(rhs))
Definition: rx-util.hpp:404
types_checked type
Definition: rx-util.hpp:169
value_type_t< T > type
Definition: rx-util.hpp:173
Definition: rx-util.hpp:753
Definition: rx-util.hpp:58
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:202