]> git.sesse.net Git - casparcg/commitdiff
* Added RxCpp library for LINQ api, replacing Boost.Range based iterations where...
authorHelge Norberg <helge.norberg@svt.se>
Mon, 9 Mar 2015 10:20:33 +0000 (11:20 +0100)
committerHelge Norberg <helge.norberg@svt.se>
Mon, 9 Mar 2015 10:20:33 +0000 (11:20 +0100)
119 files changed:
accelerator/accelerator.vcxproj
accelerator/cpu/image/image_mixer.cpp
accelerator/ogl/image/image_mixer.cpp
common/common.vcxproj
common/common.vcxproj.filters
common/diagnostics/graph.cpp
common/enum_class.h
common/linq.h [new file with mode: 0644]
common/polling_filesystem_monitor.cpp
common/tweener.cpp
common/tweener.h
core/consumer/output.cpp
core/core.vcxproj
core/frame/frame.h
core/mixer/audio/audio_mixer.cpp
core/mixer/image/image_mixer.h
core/mixer/mixer.cpp
core/producer/stage.cpp
core/thumbnail_generator.cpp
dependencies64/RxCpp/AUTHORS.txt [new file with mode: 0644]
dependencies64/RxCpp/README.md [new file with mode: 0644]
dependencies64/RxCpp/Readme.html [new file with mode: 0644]
dependencies64/RxCpp/include/cpplinq/linq.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/cpplinq/linq_cursor.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/cpplinq/linq_groupby.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/cpplinq/linq_iterators.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/cpplinq/linq_last.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/cpplinq/linq_select.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/cpplinq/linq_selectmany.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/cpplinq/linq_skip.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/cpplinq/linq_take.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/cpplinq/linq_where.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/cpplinq/util.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/operators/rx-buffer_count.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/operators/rx-combine_latest.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/operators/rx-concat.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/operators/rx-concat_map.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/operators/rx-connect_forever.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/operators/rx-distinct_until_changed.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/operators/rx-filter.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/operators/rx-finally.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/operators/rx-flat_map.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/operators/rx-group_by.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/operators/rx-lift.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/operators/rx-map.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/operators/rx-merge.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/operators/rx-multicast.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/operators/rx-observe_on.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/operators/rx-publish.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/operators/rx-reduce.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/operators/rx-ref_count.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/operators/rx-repeat.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/operators/rx-retry.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/operators/rx-scan.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/operators/rx-skip.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/operators/rx-skip_until.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/operators/rx-start_with.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/operators/rx-subscribe.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/operators/rx-subscribe_on.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/operators/rx-switch_on_next.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/operators/rx-take.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/operators/rx-take_until.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/operators/rx-window.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/rx-connectable_observable.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/rx-coordination.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/rx-grouped_observable.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/rx-includes.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/rx-notification.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/rx-observable.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/rx-observer.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/rx-operators.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/rx-predef.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/rx-scheduler.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/rx-sources.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/rx-subjects.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/rx-subscriber.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/rx-subscription.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/rx-test.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/rx-trace.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/rx-util.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/rx.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/schedulers/rx-currentthread.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/schedulers/rx-eventloop.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/schedulers/rx-immediate.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/schedulers/rx-newthread.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/schedulers/rx-sameworker.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/schedulers/rx-test.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/schedulers/rx-virtualtime.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/sources/rx-create.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/sources/rx-defer.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/sources/rx-error.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/sources/rx-interval.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/sources/rx-iterate.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/sources/rx-never.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/sources/rx-range.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/sources/rx-scope.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/subjects/rx-behavior.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/subjects/rx-subject.hpp [new file with mode: 0644]
dependencies64/RxCpp/include/rxcpp/subjects/rx-synchronize.hpp [new file with mode: 0644]
dependencies64/RxCpp/license.txt [new file with mode: 0644]
modules/bluefish/bluefish.vcxproj
modules/decklink/decklink.vcxproj
modules/ffmpeg/ffmpeg.vcxproj
modules/ffmpeg/producer/ffmpeg_producer.cpp
modules/ffmpeg/producer/filter/filter.cpp
modules/ffmpeg/producer/input/input.cpp
modules/ffmpeg/producer/util/util.cpp
modules/ffmpeg/producer/video/video_decoder.cpp
modules/flash/flash.vcxproj
modules/image/image.vcxproj
modules/oal/oal.vcxproj
modules/psd/psd.vcxproj
modules/reroute/producer/reroute_producer.cpp
modules/reroute/reroute.vcxproj
modules/screen/screen.vcxproj
protocol/protocol.vcxproj
shell/shell.vcxproj
test/psd-test/psd-test.vcxproj
unit-test/unit-test.vcxproj

index f0122661672f926032cd0f787deca4194811a7fe..b82e04714b3fa6c5743f2839a0f87c3e4bd690d6 100644 (file)
@@ -46,8 +46,8 @@
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)tmp\$(Configuration)\</IntDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)tmp\$(Configuration)\</IntDir>\r
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\;..\dependencies64\boost\;..\dependencies64\tbb\include\;..\dependencies64\sfml\include\;..\dependencies64\glew\include\;..\dependencies64\asmlib\;..\dependencies64\ffmpeg\include\;$(IncludePath)</IncludePath>\r
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\;..\dependencies64\boost\;..\dependencies64\tbb\include\;..\dependencies64\sfml\include\;..\dependencies64\glew\include\;..\dependencies64\asmlib\;..\dependencies64\ffmpeg\include\;$(IncludePath)</IncludePath>\r
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\dependencies64\RxCpp\include\;..\;..\dependencies64\boost\;..\dependencies64\tbb\include\;..\dependencies64\sfml\include\;..\dependencies64\glew\include\;..\dependencies64\asmlib\;..\dependencies64\ffmpeg\include\;$(IncludePath)</IncludePath>\r
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\dependencies64\RxCpp\include\;..\;..\dependencies64\boost\;..\dependencies64\tbb\include\;..\dependencies64\sfml\include\;..\dependencies64\glew\include\;..\dependencies64\asmlib\;..\dependencies64\ffmpeg\include\;$(IncludePath)</IncludePath>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)bin\$(Configuration)\</OutDir>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)bin\$(Configuration)\</OutDir>\r
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectName)</TargetName>\r
index 7862cf64533e50594632dc8575ebb211d2950c78..093e266c4d98dcb5dd253ea34606aef4ba83b017 100644 (file)
@@ -45,7 +45,6 @@
 #include <tbb/parallel_for_each.h>
 #include <tbb/concurrent_queue.h>
 
-#include <boost/range.hpp>
 #include <boost/range/algorithm_ext/erase.hpp>
 #include <boost/thread/future.hpp>
 
index d0296e5cee77f208bc3f41a59a2554946d126d0e..8ead24bfb107799a54d14475906e867846a681f2 100644 (file)
@@ -31,6 +31,7 @@
 #include <common/gl/gl_check.h>
 #include <common/future.h>
 #include <common/array.h>
+#include <common/linq.h>
 
 #include <core/frame/frame.h>
 #include <core/frame/frame_transform.h>
@@ -43,7 +44,6 @@
 #include <gl/glew.h>
 
 #include <boost/range/algorithm_ext/erase.hpp>
-#include <boost/range/algorithm/max_element.hpp>
 #include <boost/thread/future.hpp>
 
 #include <algorithm>
@@ -80,13 +80,9 @@ struct layer
 
 std::size_t get_max_video_format_size()
 {
-       return *boost::range::max_element(
-               iterate_enum<core::video_format>()
-               | boost::adaptors::transformed(
-                               [] (core::video_format format)
-                               {
-                                       return core::video_format_desc(format).size;
-                               }));
+       return cpplinq::from(enum_constants<core::video_format>())
+               .select([](core::video_format format) { return core::video_format_desc(format).size; })
+               .max();
 }
 
 class image_renderer
index 87660101f58ad29315267f9aaecead9a508d591c..2db7d6d4324a73b7be8a4fac2bd912a6a92cd0ea 100644 (file)
@@ -43,8 +43,8 @@
   <PropertyGroup>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)tmp\$(Configuration)\</IntDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)tmp\$(Configuration)\</IntDir>\r
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\dependencies64\bluefish\include\;..\dependencies64\boost\;..\dependencies64\tbb\include\;..\dependencies64\sfml\include\;..\dependencies64\glew\include\;$(IncludePath);..\..\dependencies64\ffmpeg\include\;..\dependencies64\asmlib\</IncludePath>\r
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\dependencies64\bluefish\include\;..\dependencies64\boost\;..\dependencies64\tbb\include\;..\dependencies64\sfml\include\;..\dependencies64\glew\include\;$(IncludePath);..\..\dependencies64\ffmpeg\include\;..\dependencies64\asmlib\</IncludePath>\r
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\dependencies64\RxCpp\include\;..\dependencies64\bluefish\include\;..\dependencies64\boost\;..\dependencies64\tbb\include\;..\dependencies64\sfml\include\;..\dependencies64\glew\include\;$(IncludePath);..\..\dependencies64\ffmpeg\include\;..\dependencies64\asmlib\</IncludePath>\r
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\dependencies64\RxCpp\include\;..\dependencies64\bluefish\include\;..\dependencies64\boost\;..\dependencies64\tbb\include\;..\dependencies64\sfml\include\;..\dependencies64\glew\include\;$(IncludePath);..\..\dependencies64\ffmpeg\include\;..\dependencies64\asmlib\</IncludePath>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)bin\$(Configuration)\</OutDir>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)bin\$(Configuration)\</OutDir>\r
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectName)</TargetName>\r
     <ClInclude Include="future.h" />\r
     <ClInclude Include="future_fwd.h" />\r
     <ClInclude Include="gl\gl_check.h" />\r
+    <ClInclude Include="linq.h" />\r
     <ClInclude Include="lock.h" />\r
     <ClInclude Include="log.h" />\r
     <ClInclude Include="memory.h" />\r
index 7d5d85df6ebe0902ecd8783c01e5ba97ca753f5a..22eaab77f0811a2ea775b0a26f08679cdaf639f9 100644 (file)
     <ClInclude Include="cache_aligned_vector.h">\r
       <Filter>source</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="linq.h">\r
+      <Filter>source</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
 </Project>
\ No newline at end of file
index aba34f508a353fdc149de9eb7b4977139ce626ea..4cd3fc5829573af71d9ef2de34a4796d0aa1c0d2 100644 (file)
@@ -23,7 +23,8 @@
 
 #include "graph.h"
 
-#include <boost/range/adaptor/transformed.hpp>
+#include "../linq.h"
+
 #include <boost/thread.hpp>
 
 #include <tbb/spin_mutex.h>
@@ -58,8 +59,10 @@ static sink_factories_t g_sink_factories;
 std::vector<spl::shared_ptr<spi::graph_sink>> create_sinks()
 {
        boost::lock_guard<boost::mutex> lock(g_sink_factories_mutex);
-       auto sinks = g_sink_factories | boost::adaptors::transformed([](const spi::sink_factory_t& s){ return s(); });
-       return std::vector<spl::shared_ptr<spi::graph_sink>>(std::begin(sinks), std::end(sinks));
+
+       return cpplinq::from(g_sink_factories)
+               .select([](const spi::sink_factory_t& s){ return s(); })
+               .to_vector();
 }
 
 struct graph::impl
index 91b2555bca7dd85be41f64e66bade015aa0affc8..76db19b1feccbe9e1e21917dd50708d295dfcb9c 100644 (file)
@@ -2,9 +2,10 @@
 
 #include <type_traits>
 
-#include <boost/range/adaptor/transformed.hpp>
 #include <boost/range/irange.hpp>
 
+#include "linq.h"
+
 // Macro that defines & and &= for an enum class. Add more when needed.
 
 #define ENUM_ENABLE_BITWISE(enum_class) \
 
 namespace caspar {
 
-template<typename E>
-struct enum_from_int
-{
-       typedef E result_type;
-
-       E operator()(typename std::underlying_type<E>::type i) const
-       {
-               return static_cast<E>(i);
-       }
-};
-
 // For enum classes starting at 0 and without any gaps with a terminating count constant.
 template <typename E>
-boost::transformed_range<enum_from_int<E>, const boost::integer_range<typename std::underlying_type<E>::type>> iterate_enum()
+const std::vector<E>& enum_constants()
 {
        typedef typename std::underlying_type<E>::type integer;
-       return boost::irange(static_cast<integer>(0), static_cast<integer>(E::count)) | boost::adaptors::transformed(enum_from_int<E>());
+
+       static const auto ints = boost::irange(static_cast<integer>(0), static_cast<integer>(E::count));
+       static const auto result = cpplinq::from(ints.begin(), ints.end())
+               .cast<E>()
+               .to_vector();
+
+       return result;
 }
 
 }
\ No newline at end of file
diff --git a/common/linq.h b/common/linq.h
new file mode 100644 (file)
index 0000000..81b5032
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+* Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>
+*
+* This file is part of CasparCG (www.casparcg.com).
+*
+* CasparCG is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* CasparCG is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with CasparCG. If not, see <http://www.gnu.org/licenses/>.
+*
+* Author: Helge Norberg, helge.norberg@svt.se
+*/
+
+#pragma once
+
+#include <cpplinq/linq.hpp>
+
+#include <utility>
+#include <numeric>
+
+namespace caspar {
+
+struct keys
+{
+       template <typename Pair>
+       const typename Pair::first_type& operator()(const Pair& p) const
+       {
+               return p.first;
+       }
+};
+
+struct values
+{
+       template <typename Pair>
+       const typename Pair::second_type& operator()(const Pair& p) const
+       {
+               return p.second;
+       }
+};
+
+struct minmax
+{
+       template <typename T>
+       std::pair<T, T> operator()(std::pair<T, T> initial, T value) const
+       {
+               return std::make_pair(std::min(initial.first, value), std::max(initial.second, value));
+       }
+
+       template <typename T>
+       static std::pair<T, T> initial_value()
+       {
+               return std::make_pair(std::numeric_limits<T>::max(), std::numeric_limits<T>::min());
+       }
+};
+
+}
index 249c1285bededc13c6f5ecc3ecbe5805ab44671d..e9c2f59a9729047843df1d979287ce85b2cdc905 100644 (file)
@@ -29,8 +29,6 @@
 #include <cstdint>
 
 #include <boost/thread.hpp>
-#include <boost/range/adaptor/map.hpp>
-#include <boost/range/algorithm/copy.hpp>
 #include <boost/filesystem/fstream.hpp>
 #include <boost/filesystem/convenience.hpp>
 
@@ -38,6 +36,7 @@
 #include <tbb/concurrent_queue.h>
 
 #include "executor.h"
+#include "linq.h"
 
 namespace caspar {
 
@@ -121,11 +120,8 @@ public:
                bool interested_in_created = static_cast<int>(events_mask_ & filesystem_event::CREATED) > 0;
                bool interested_in_modified = static_cast<int>(events_mask_ & filesystem_event::MODIFIED) > 0;
 
-               std::set<wpath> removed_files;
-               boost::copy(
-                               files_ | boost::adaptors::map_keys,
-                               std::insert_iterator<decltype(removed_files)>(removed_files, removed_files.end()));
-
+               auto filenames = cpplinq::from(files_).select(keys());
+               std::set<wpath> removed_files(filenames.begin(), filenames.end());
                std::set<wpath> initial_files;
 
                for (boost::filesystem::wrecursive_directory_iterator iter(folder_); iter != boost::filesystem::wrecursive_directory_iterator(); ++iter)
index d19ba7f0435a95d9a21748ef035a6b8451bcbff3..cadeec4733ed0ff72a599e3fd8a656f9ed7f3b23 100644 (file)
 #include "tweener.h"
 
 #include "except.h"
+#include "linq.h"
 
 #include <boost/regex.hpp>
 #include <boost/lexical_cast.hpp>
-#include <boost/range/adaptor/map.hpp>
 
 #include <unordered_map>
 #include <string>
@@ -481,13 +481,11 @@ double tweener::operator()(double t, double b , double c, double d) const
        return func_(t, b, c, d);
 }
 
-const std::vector<std::wstring>& tweener::names()
+const std::vector<const std::wstring>& tweener::names()
 {
-       using namespace boost::adaptors;
-
-       static const std::vector<std::wstring> names(
-               (get_tweens() | map_keys).begin(),
-               (get_tweens() | map_keys).end());
+       static const auto names = cpplinq::from(get_tweens())
+               .select(keys())
+               .to_vector();
 
        return names;
 }
index 765163013d3107e9dd8595657e957cc8b66d7bed..3747cfce719aae0ef8398672e9854575b645d720 100644 (file)
@@ -53,7 +53,7 @@ public:
         * @return The possible tween function names. Some of them may also support
         *                 additional parameters appended to the name.
         */
-       static const std::vector<std::wstring>& names();
+       static const std::vector<const std::wstring>& names();
 
        /**
         * Calculate a tweened value given a timepoint within the total duration
index 95259ab3cf83c04ab23a67f64ea4527cbaef7d21..62a848a707f1fc62a844bfe3d3da9d30ffb6aa93 100644 (file)
 #include <common/prec_timer.h>
 #include <common/memshfl.h>
 #include <common/env.h>
+#include <common/linq.h>
 
 #include <boost/circular_buffer.hpp>
 #include <boost/lexical_cast.hpp>
 #include <boost/property_tree/ptree.hpp>
-#include <boost/range/algorithm.hpp>
-#include <boost/range/adaptors.hpp>
 #include <boost/timer.hpp>
 
+#include <functional>
+
 namespace caspar { namespace core {
 
 struct output::impl
@@ -134,19 +135,19 @@ public:
        {               
                if(ports_.empty())
                        return std::make_pair(0, 0);
-               
-               auto buffer_depths = ports_ | 
-                                                        boost::adaptors::map_values |
-                                                        boost::adaptors::transformed([](const port& p){return p.buffer_depth();}); 
-               
 
-               return std::make_pair(*boost::range::min_element(buffer_depths), *boost::range::max_element(buffer_depths));
+               return cpplinq::from(ports_)
+                       .select(values())
+                       .select(std::mem_fn(&port::buffer_depth))
+                       .aggregate(minmax::initial_value<int>(), minmax());
        }
 
        bool has_synchronization_clock() const
        {
-               return boost::range::count_if(ports_ | boost::adaptors::map_values,
-                                                                         [](const port& p){return p.has_synchronization_clock();}) > 0;
+               return cpplinq::from(ports_)
+                       .select(values())
+                       .where(std::mem_fn(&port::has_synchronization_clock))
+                       .any();
        }
                
        void operator()(const_frame input_frame, const core::video_format_desc& format_desc)
index af2de85fe0aa0ec465cb38ebb763b81714db3967..28b9434090789e6c37f2f56eaccf4a269e79224c 100644 (file)
@@ -46,8 +46,8 @@
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)tmp\$(Configuration)\</IntDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)tmp\$(Configuration)\</IntDir>\r
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\;..\dependencies64\boost\;..\dependencies64\tbb\include\;..\dependencies64\sfml\include\;..\dependencies64\glew\include\;..\dependencies64\asmlib\;..\dependencies64\freetype\include;..\dependencies64\freeimage\include\;$(IncludePath)</IncludePath>\r
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\;..\dependencies64\boost\;..\dependencies64\tbb\include\;..\dependencies64\sfml\include\;..\dependencies64\glew\include\;..\dependencies64\asmlib\;..\dependencies64\freetype\include;..\dependencies64\freeimage\include\;$(IncludePath)</IncludePath>\r
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\dependencies64\RxCpp\include\;..\;..\dependencies64\boost\;..\dependencies64\tbb\include\;..\dependencies64\sfml\include\;..\dependencies64\glew\include\;..\dependencies64\asmlib\;..\dependencies64\freetype\include;..\dependencies64\freeimage\include\;$(IncludePath)</IncludePath>\r
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\dependencies64\RxCpp\include\;..\;..\dependencies64\boost\;..\dependencies64\tbb\include\;..\dependencies64\sfml\include\;..\dependencies64\glew\include\;..\dependencies64\asmlib\;..\dependencies64\freetype\include;..\dependencies64\freeimage\include\;$(IncludePath)</IncludePath>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)bin\$(Configuration)\</OutDir>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)bin\$(Configuration)\</OutDir>\r
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectName)</TargetName>\r
index 240c03f5328416ba2089d044b0cd4ee775696257..4667c0a2a1402470ef5138e3502fc8f9e189e713 100644 (file)
@@ -11,9 +11,6 @@
 #include <common/future_fwd.h>
 #include <common/cache_aligned_vector.h>
 
-#include <boost/range.hpp>
-#include <boost/any.hpp>
-
 #include <cstddef>
 #include <cstdint>
 
index a746375ca9b9b4006eadf0197263410fa5907e6b..4636d8466e22531789666638f3589a826a9b2e56 100644 (file)
@@ -26,6 +26,7 @@
 #include <core/frame/frame.h>
 #include <core/frame/frame_transform.h>
 #include <common/diagnostics/graph.h>
+#include <common/linq.h>
 
 #include <boost/range/adaptors.hpp>
 #include <boost/range/distance.hpp>
@@ -178,10 +179,10 @@ public:
 
                { // sanity check
 
-                       auto nb_invalid_streams = boost::count_if(audio_streams_ | boost::adaptors::map_values, [&](const audio_stream& x)
-                       {
-                               return x.audio_data.size() < audio_size(audio_cadence_.front());
-                       });
+                       auto nb_invalid_streams = cpplinq::from(audio_streams_)
+                               .select(values())
+                               .where([&](const audio_stream& x) { return x.audio_data.size() < audio_size(audio_cadence_.front()); })
+                               .count();
 
                        if(nb_invalid_streams > 0)              
                                CASPAR_LOG(trace) << "[audio_mixer] Incorrect frame audio cadence detected.";                   
index 53a5bbd19d3734e74efb2239dc2a045b465556a9..f382e11ce3816e6976f7a793e5def24f03e04f41 100644 (file)
@@ -32,8 +32,6 @@
 #include <core/frame/frame_factory.h>
 #include <core/frame/frame.h>
 
-#include <boost/range.hpp>
-
 #include <cstdint>
 
 FORWARD2(caspar, core, struct pixel_format_desc);
index 9008921bf49d47e10e890aceb5f065fcfb378a8a..6a322e85aa184bd7e259a999efa13c03ca26e847 100644 (file)
@@ -43,7 +43,6 @@
 
 #include <boost/timer.hpp>
 #include <boost/property_tree/ptree.hpp>
-#include <boost/range/algorithm_ext.hpp>
 
 #include <tbb/concurrent_queue.h>
 #include <tbb/spin_mutex.h>
index e619eb3c0bf9915a786f4b1816875edce938bb8c..ae0b926518d8ff1c5620bae899f58c07c6ca554a 100644 (file)
@@ -37,7 +37,6 @@
 
 #include <boost/timer.hpp>
 #include <boost/property_tree/ptree.hpp>
-#include <boost/range/algorithm_ext.hpp>
 
 #include <tbb/parallel_for_each.h>
 
index 61cce95fc4eba00de88c8d3781e9d49e2407be2c..f855a7006073c2d5f1d459d3f8fb4e352604568e 100644 (file)
@@ -29,7 +29,6 @@
 #include <future>
 
 #include <boost/thread.hpp>
-#include <boost/range/algorithm/transform.hpp>
 #include <boost/algorithm/string/predicate.hpp>
 #include <boost/filesystem.hpp>
 
diff --git a/dependencies64/RxCpp/AUTHORS.txt b/dependencies64/RxCpp/AUTHORS.txt
new file mode 100644 (file)
index 0000000..7da61e0
--- /dev/null
@@ -0,0 +1,41 @@
+List of contributors to the Rx libraries
+
+Rx and Ix.NET:
+Wes Dyer
+Jeffrey van Gogh
+Matthew Podwysocki
+Bart de Smet
+Danny van Velzen
+Erik Meijer
+Brian Beckman
+Aaron Lahman
+Georgi Chkodrov
+Arthur Watson
+Gert Drapers
+Mark Shields
+
+Rx.js and Ix.js:
+Matthew Podwysocki
+Jeffrey van Gogh
+Bart de Smet
+Brian Beckman
+Wes Dyer
+Erik Meijer
+
+Tx:
+Georgi Chkodrov
+Bart de Smet
+Aaron Lahman
+Erik Meijer
+Brian Grunkemeyer
+Beysim Sezgin
+Tiho Tarnavski
+Collin Meek
+Sajay Anthony
+Karen Albrecht
+John Allen
+Zach Kramer
+
+Rx++ and Ix++:
+Aaron Lahman
+Kirk Shoop
diff --git a/dependencies64/RxCpp/README.md b/dependencies64/RxCpp/README.md
new file mode 100644 (file)
index 0000000..ffa1b1e
--- /dev/null
@@ -0,0 +1,148 @@
+[![Build Status](https://travis-ci.org/Reactive-Extensions/RxCpp.png)](https://travis-ci.org/Reactive-Extensions/RxCpp)
+
+# Reactive Extensions:
+
+* Rx.NET: The Reactive Extensions (Rx) is a library for composing asynchronous and event-based programs using observable sequences and LINQ-style query operators.
+* RxJS: The Reactive Extensions for JavaScript (RxJS) is a library for composing asynchronous and event-based programs using observable sequences and LINQ-style query operators in JavaScript which can target both the browser and Node.js.
+* RxCpp: The Reactive Extensions for Native (RxC) is a library for composing asynchronous and event-based programs using observable sequences and LINQ-style query operators in both C and C++.
+
+# Interactive Extensions
+* Ix: The Interactive Extensions (Ix) is a .NET library which extends LINQ to Objects to provide many of the operators available in Rx but targeted for IEnumerable<T>.
+* IxJS: An implementation of LINQ to Objects and the Interactive Extensions (Ix) in JavaScript.
+* Ix++: An implantation of LINQ for Native Developers in C++
+
+# Applications:
+* Tx: a set of code samples showing how to use LINQ to events, such as real-time standing queries and queries on past history from trace and log files, which targets ETW, Windows Event Logs and SQL Server Extended Events.
+* LINQ2Charts: an example for Rx bindings.  Similar to existing APIs like LINQ to XML, it allows developers to use LINQ to create/change/update charts in an easy way and avoid having to deal with XML or other underneath data structures. We would love to see more Rx bindings like this one.
+
+#Building RxCpp
+
+* RxCpp is regularly tested on OSX and Windows.
+* RxCpp is regularly built with Clang and VC
+* RxCpp depends on the latest compiler releases.
+* RxCpp has an experimental build with gcc.
+
+RxCpp uses CMake to create build files for several platforms and IDE's
+
+###Ide builds
+####XCode
+```
+mkdir projects/build
+cd projects/build
+cmake -G"Xcode" ../CMake -B.
+```
+
+####Visual Studio 13
+```
+mkdir projects\build
+cd projects\build
+cmake -G"Visual Studio 12" ..\CMake -B.
+```
+* Note: open in VC2013 and upgrade to the 2013 toolset
+
+###makefile builds
+
+####OSX
+```
+mkdir projects/build
+cd projects/build
+cmake -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=RelWithDebInfo -B. ../CMake
+make
+```
+
+####Linux --- Clang
+```
+mkdir projects/build
+cd projects/build
+cmake -G"Unix Makefiles" -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=RelWithDebInfo -B. ../CMake
+make
+```
+
+####Linux --- GCC
+```
+mkdir projects/build
+cd projects/build
+cmake -G"Unix Makefiles" -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE=RelWithDebInfo -B. ../CMake
+make
+```
+
+####Windows
+```
+mkdir projects\build
+cd projects\build
+cmake -G"NMake Makefiles" -DCMAKE_BUILD_TYPE=RelWithDebInfo -B. ..\CMake
+nmake
+```
+
+The build only produces a test binary.
+
+#Running tests
+
+* You can use the CMake test runner ```ctest```
+* You can run the test binary directly ```rxcppv2_test```
+* Tests can be selected by name or tag
+Example of by-tag
+
+```rxcppv2_test [perf]```
+
+#Using RxCpp
+Add ```Rx/v2/src``` to the include paths
+
+```
+#include "rxcpp/rx.hpp"
+// create alias' to simplify code
+// these are owned by the user so that
+// conflicts can be managed by the user.
+namespace rx=rxcpp;
+namespace rxu=rxcpp::util;
+namespace rxsc=rxcpp::schedulers;
+namespace rxsub=rxcpp::subjects;
+
+// At this time, RxCpp will fail to compile if the contents
+// of the std namespace are merged into the global namespace
+// DO NOT USE: 'using namespace std;'
+
+#ifdef UNICODE
+int wmain(int argc, wchar_t** argv)
+#else
+int main(int argc, char** argv)
+#endif
+{
+    int c = 0;
+
+    auto triples =
+        rx::observable<>::range(1)
+            .concat_map(
+                [&c](int z){
+                    return rx::observable<>::range(1, z)
+                        .concat_map(
+                            [=, &c](int x){
+                                return rx::observable<>::range(x, z)
+                                    .filter([=, &c](int y){++c; return x*x + y*y == z*z;})
+                                    .map([=](int y){return std::make_tuple(x, y, z);})
+                                    // forget type to workaround lambda deduction bug on msvc 2013
+                                    .as_dynamic();},
+                            [](int x, std::tuple<int,int,int> triplet){return triplet;})
+                        // forget type to workaround lambda deduction bug on msvc 2013
+                        .as_dynamic();},
+                [](int z, std::tuple<int,int,int> triplet){return triplet;});
+
+    int ct = 0;
+
+    triples
+        .take(100)
+        .subscribe(rxu::apply_to([&ct](int x,int y,int z){
+            ++ct;
+        }));
+
+    std::cout << "concat_map pythagorian range : " << c << " filtered to, " << ct << " triplets" << std::endl;
+
+    return 0;
+}
+```
+
+#Contributing Code
+
+Before submitting a feature or substantial code contribution please  discuss it with the team and ensure it follows the product roadmap. Note that all code submissions will be rigorously reviewed and tested by the Rx Team, and only those that meet an extremely high bar for both quality and design/roadmap appropriateness will be merged into the source.
+
+You will need to submit a  Contributor License Agreement form before submitting your pull request. This needs to only be done once for any Microsoft OSS project. Fill in the [Contributor License Agreement](https://cla.msopentech.com/) (CLA).
diff --git a/dependencies64/RxCpp/Readme.html b/dependencies64/RxCpp/Readme.html
new file mode 100644 (file)
index 0000000..0ffeade
--- /dev/null
@@ -0,0 +1,303 @@
+<h1>Reactive Extensions</h1>
+
+<p>Reactive Extensions (Rx) is a library for composing asynchronous and event-based programs using observable sequences and LINQ-style query operators.</p>
+<p>Data sequences can take many forms, such as a stream of data from a file or web service, web services requests, system notifications, or a series of events such as user input. </p>
+<p>Reactive Extensions represents all these data sequences as observable sequences. An application can subscribe to these observable sequences to receive asynchronous notifications as new data arrives. The Rx library is available for application development in C++, .NET, Ruby, Python, Silverlight, Windows Phone 7 and JavaScript. For more information on these different platforms, see Differences Between Versions of Rx topic.</p>
+<h2>Pulling vs. Pushing Data</h2>
+<p>In interactive programming, the application actively polls a data source for more information by pulling data from a sequence that represents the source. The iterator allows us to get the current item by returning the current property, and determines whether there are more items to iterate (by calling some on_next method). </p>
+<p>The application is active in the data retrieval process, controlling the pace of the retrieval by calling on_next at its own convenience. This pattern is synchronous, which means that the application might be blocked while polling the data source. Such pulling pattern is similar to visiting your library and checking out a book. After you are done with the book, you pay another visit to check out another one.</p>
+<p>On the other hand, in reactive programming, the application is offered more information by subscribing to a data stream (called observable sequence in Rx), and any update is handed to it from the source. The application is passive in the data retrieval process: apart from subscribing to the observable source, it does not actively poll the source, but merely reacts to the data being pushed to it. When the stream has no more data to offer, or when it errs, the source will send a notice to the subscriber. In this way, the application will not be blocked by waiting for the source to update. </p>
+<p>This is the push pattern employed by Reactive Extensions. It is similar to joining a book club in which you register your interest in a particular genre, and books that match your interest are automatically sent to you as they are published. You do not need to stand in line to acquire something that you want. Employing a push pattern is helpful in many scenarios, especially in a UI-heavy environment in which the UI thread cannot be blocked while the application is waiting for some events. In summary, by using Rx, you can make your application more responsive.</p>
+<p>The push model implemented by Rx is represented by the observable pattern of Rx.Observable/Observer. The Rx.Observable will notify all the observers automatically of any state changes. To register an interest through a subscription, you use the subscribe method of Rx.Observable, which takes on an Observer and returns a disposable. This gives you the ability to track and dispose of the subscription. In addition, Rx\92s LINQ implementation over observable sequences allows developers to compose complex event processing queries over push-based sequences such as events, APM-based (\93AsyncResult\94) computations, Task-based computations, and asynchronous workflows. For more information on the Observable/Observer classes, see Exploring The Major Classes in Rx. For tutorials on using the different features in Rx, see Using Rx.</p>
+<h1>Getting Started with Rx</h1>
+<p>This section describes in general what Reactive Extensions (Rx) is, and how it can benefit programmers who are creating asynchronous applications.</p>
+<h3>In This Section</h3>
+<p>1.  When Will You Use Rx<br />
+2.     Installing Rx<br />
+3.     Differences Between Versions of Rx</p>
+<h3>Related Sections</h3>
+<p>Using Rx<br />
+Reactive Extensions on MSDN Developer Center</p>
+<h1>When Will You Use Rx</h1>
+<p>This topic describes the advantage of using Rx for users who are currently using the .NET event model for asynchronous programming.</p>
+<h2>Advantages of using Rx</h2>
+<p>Whether you are authoring a traditional desktop or web-based application, you have to deal with asynchronous programming from time to time. Desktop applications have I/O or UI threads that might take a long time to complete and potentially block all other active threads. However, a user of the modern asynchronous programming model has to manage exceptions and cancellation of events manually. To compose or filter events, he has to write custom code that is hard to decipher and maintain.</p>
+<p>In addition, if your application interacts with multiple sources of data, the conventional way to manage all of these interactions is to implement separate methods as event handlers for each of these data streams. For example, as soon as a user types a character, a keydown event is pushed to your keydown event handler method. Inside this keydown event handler, you have to provide code to react to this event, or to coordinate between all of the different data streams and process this data into a useable form.</p>
+<p>Using Rx, you can represent multiple asynchronous data streams (that come from diverse sources, e.g., stock quote, tweets, computer events, web service requests, etc.), and subscribe to the event stream using the Observer class. The Observable class maintains a list of dependent Observer threads and notifies them automatically of any state changes. You can query observable sequences using standard LINQ query operators implemented by the Rx.Observable type. Thus you can filter, aggregate, and compose on multiple events easily by using these LINQ operators. Cancellation and exceptions can also be handled gracefully by using extension methods provided by Rx.</p>
+<p>The following example shows how easy it is to implement an observable in C++.</p>
+ <code>
+//Declare an observable<br />
+auto values1 = rxcpp::Range(1, 10);<br />
+        rxcpp::from(values1)<br />
+                .for_each(<br />
+            [](int p) {<br />
+                cout << p << endl;<br />
+            });
+</code>
+<p>You can also use schedulers to control when the subscription starts, and when notifications are pushed to subscribers. For more information on this, see Using Schedulers for Concurrency Control.</p>
+<h2>Filtering</h2>
+<p>One drawback of the C++ event model is that your event handler is always called every time an event is raised, and events arrive exactly as they were sent out by the source. To filter out events that you are not interested in, or transform data before your handler is called, you have to add custom filter logic to your handler.</p>
+<p>Take an application that detects mouse-down as an example. In the current event programming model, the application can react to the event raised by displaying a message. In Rx, such mouse-down events are treated as a stream of information about clicks. Whenever you click the mouse, information (e.g., cursor position) about this click appears in a stream, ready to be processed. In this paradigm, events (or event streams) are very similar to lists or other collections. This means that we can use techniques for working with collections to process events.  For example, you can filter out those clicks that appear outside a specific area, and only display a message when the user clicks inside an area. Or you can wait a specific period of time, and inform the user the number of \93valid\94 clicks during this period. Similarly, you can capture a stream of stock ticks and only respond to those ticks that have changed for a specific range during a particular time window. All these can be done easily by using LINQ-query style operators provided by Rx. </p>
+<p>In this way, a function can take an event, process it, and then pass out the processed stream to an application. This gives you flexibility that is not available in the current programming model. Moreover, as Rx is performing all the plumbing work at the background for filtering, synchronizing, and transforming the data, your handler can just react to the data it receives and do something with it. This results in cleaner code that is easier to read and maintain. For more information on filtering, see Querying Observable Collections using LINQ Operators.</p>
+<h2>Manipulating Events</h2>
+<p>Rx represents events as a collection of objects: e.g., a OnMouseMove event contains a collection of Point values. Due to the first-class object nature of observables, they can be passed around as function parameters and returns, or stored in a variable.</p> 
+<h1>Installing Rx</h1>
+<p>This topic describes where you can download the Reactive Extensions (Rx) SDK.</p>
+<h2>To download Rx</h2>
+<p>Reactive Extensions is available for different platforms such as C++, Javascript, .NET Framework 3.5, 4.0, 4.5, Silverlight 3 and 4, as well as Windows Phone 7 & 8. You can download the libraries, as well as learn about their prerequisites at the <a href="http://msdn.microsoft.com/en-us/data/gg577609" target="_blank">Rx MSDN Developer Center.</a></p> 
+<h1>Differences Between Versions of Rx</h1>
+<p>The following topic describes the various platforms for which you can develop solutions using Reactive Extensions.</p>
+<p>To get the latest release of Rx, as well as learn about its prerequisites, please visit the <a href="http://msdn.microsoft.com/en-us/data/gg577609" target="_blank">Rx MSDN Developer Center</a>. </p>
+<h2>C++</h2>
+<p>The Reactive Extensions for C++ (RxCpp) is a library for composing asynchronous and event-based programs using observable sequences and LINQ-style query operators in C++.</p>
+<h2>Javascript</h2>
+<p>Rx for Javascript (RxJS) allows you to use LINQ operators in JavaScript. It provides easy-to-use conversions from existing DOM, XmlHttpRequest (AJAX), and jQuery events to push-based observable collections, allowing users to seamlessly integrate Rx into their existing JavaScript-based websites. </p>
+<p>RxJS brings similar capabilities to client script and integrates with jQuery events (Rx.Observable.FromJQueryEvent). It also supports Script#.</p>
+<h2>Ruby</h2>
+<p>Rx for Ruby (Rx.rb) allows you to use Linq operators to create push-based observable collections in Ruby.</p>
+<h2>Python</h2>
+<p>RX for Python (Rx.py) allows you to use Linq operators in Python. Rx.py allows you to implement push-based observable collections, allowing users to seamlessly integrate Rx into their existing Python applications.</p>
+<h2>.NET Framework</h2>
+<p>The core Rx interfaces, IObservable<T> and IObserver<T>, ship as part of .NET Framework 4. If you are running on .NET Framework 3.5 SP1, or if you want to take advantage of the LINQ operators implemented in Observable type, as well as many other features such as schedulers, you can download the Rx header-only library in the <a href="http://msdn.microsoft.com/en-us/data/gg577609" target="_blank">Rx MSDN Developer Center</a>.</p>
+<h2>Silverlight </h2>
+<p>Silverlight disallows you from making cross-threading calls, thus you cannot use a background thread to update the UI. Instead of writing verbose code using the Dispatcher.BeginInvoke call to explicitly execute code on the main UI thread, you can use the factory Observable.Start method provided by the Rx header-only library to invoke an action asynchronously. Cross-threading is taken care of transparently by Rx under the hood.</p>
+<p>You can also use the various Observable operator overloads that take in a Scheduler, and specify the System.Reactive.Concurrency.DispatcherScheduler to be used.</p>
+<h2>Windows Phone</h2> 
+<p>Windows Phone 7 ships with a version of the Reactive Extensions baked into the ROM of the device. For more information, see <a href="http://msdn.microsoft.com/en-us/library/ff431792(VS.92).aspx">Reactive Extensions for .NET Overview for Windows Phone</a>. Documentation for this version of the Reactive Extensions can be found in Windows Phone API library at <a href="http://msdn.microsoft.com/en-us/library/ff707857(v=VS.92).aspx">Microsoft.Phone.Reactive Namespace</a>. </p>
+<p>The <a href="http://msdn.microsoft.com/en-us/data/gg577609" target="_blank">Rx MSDN Developer Center</a> also contains an updated version of Rx for WP7, which has new definitions in the System.Reactive.Linq namespace. Note that the new APIs will not clash with the library built in to the phone (nor do they replace the version in the ROM). For more information on the differences of these 2 versions, see this <a href="http://blogs.msdn.com/b/rxteam/archive/2010/10/28/rx-for-windows-phone-7.aspx">Rx team blog post</a>.</p>
+<p>Rx is available for Windows Phone 8 as well as Windows Phone 7. A .NET portable library is available using Nuget that is useful for developing libraries that work on Windows Phone, Windows Store apps, and in classic Windows desktop or server applications.</p>
+<h1>Using Rx</h1>
+<p>This section includes topics that explain how you use Rx to create and subscribe to sequences, bridge existing events and existing asynchronous patterns, as well as using schedulers. It also describes more advanced tasks such as implementing your own operators.</p>
+<h3>In This Section</h3>
+<p>1.  Exploring The Major Interfaces in Rx<br />
+2.     Creating and Querying Event Streams<br />
+3.     Subjects<br />
+6.     Implementing your own operators for IObservable<br />
+7.     Using Observable Providers</p>
+<h1>Exploring The Major Interfaces in Rx</h1>
+<p>This topic describes the major Reactive Extensions (Rx) interfaces used to represent observable sequences and subscribe to them. </p>
+<h2>Observable/Observer</h2>
+<p>Rx exposes asynchronous and event-based data sources as push-based, observable sequences. This Observable class represents a data source that can be observed, meaning that it can send data to anyone who is interested. It maintains a list of dependent Observer implementations representing such interested listeners, and notifies them automatically of any state changes.</p>
+<p>As described in What is Rx, the other half of the push model is represented by the Observer class, which represents an observer who registers an interest through a subscription. Items are subsequently handed to the observer from the observable sequence to which it subscribes. </p>
+<p>In order to receive notifications from an observable collection, you use the subscribe method of Observable to hand it an Observer object. In return for this observer, the subscribe method returns a disposable object that acts as a handle for the subscription. This allows you to clean up the subscription after you are done. Calling dispose on this object detaches the observer from the source so that notifications are no longer delivered. As you can infer, in Rx you do not need to explicitly unsubscribe from an event. </p>
+<p>Observers support three publication events, reflected by the interface\92s methods. OnNext can be called zero or more times, when the observable data source has data available. For example, an observable data source used for mouse move events can send out a Point object every time the mouse has moved. The other two methods are used to indicate completion or errors.</p>
+<p>The following lists the Observable/Observer definitions.</p>
+<code>
+namespace rxcpp {<br />
+    template <class T><br />
+    struct Observer<br />
+    {<br />
+        virtual void OnNext(const T&) {};<br />
+        virtual void OnCompleted() {};<br />
+        virtual void OnError(const std::exception_ptr&) {};<br /><br />
+
+        virtual ~Observer() {}<br />
+    };<br />
+
+    template <class T><br />
+    struct Observable<br />
+    {<br />
+        virtual Disposable Subscribe(std::shared_ptr<Observer<T>> observer) = 0; <br />
+        virtual ~Observable() {}<br />
+    };<br />
+}
+</code>
+<p>Note that the OnError event returns an exception_ptr type. The example above shows passing the error to a handler function.</p>
+<p>You can treat the observable sequence (such as a sequence of mouse-over events) as if it were a normal collection. Thus you can write LINQ queries over the collection to do things like filtering, grouping, composing, etc. To make observable sequences more useful, the Rx header-only library provides many factory LINQ operators so that you do not need to implement any of these on your own. This will be covered in the Querying Observable Collections using LINQ Operators topic.</p>
+<h3>See Also</h3>
+Creating and Subscribing to Simple Observable Sequences
+Querying Observable Collections using LINQ Operators
+<h1>Creating and Querying Observable Sequences</h1>
+<p>This section describes how you can create and subscribe to an observable sequence, convert an existing C++ event into a sequence and query it. </p>
+<h3>In This Section</h3>
+<p>Creating and Subscribing to Simple Observable Sequences<br />
+Querying Observable Collections using LINQ Operators</p>
+<h1>Creating and Subscribing to Simple Observable Sequences</h1>
+<p>You do not need to implement the Observable interface manually to create an observable sequences. Similarly, you do not need to implement Observer either to subscribe to a sequence. By installing the Reactive Extension header-only library, you can take advantage of the Observable type which provides many LINQ operators for you to create a simple sequence with zero, one or more elements. In addition, Rx provides Subscribe methods that take various combinations of OnNext, OnError and OnCompleted handlers in terms of delegates.</p>
+<h2>Creating and subscribing to a simple sequence</h2>
+<p>The following sample uses the range operator of the Observable type to create a simple observable collection of numbers. The observer subscribes to this collection using the Subscribe method of the Observable class, and provides actions that are delegates which handle OnNext, OnCompleted and OnError. </p>
+<p>The range operator has several overloads. In our example, it creates a sequence of integers that starts with x and produces y sequential numbers afterwards.  </p>
+<p>As soon as the subscription happens, the values are sent to the observer. The OnNext delegate then prints out the values.</p>
+<code>
+auto values1 = rxcpp::Range(1, 10);<br />
+        rxcpp::from(values1)<br />
+                .for_each(<br />
+            [](int p) {<br />
+                cout << p << endl;<br />
+            });
+</code>
+<p>When an observer subscribes to an observable sequence, the thread calling the subscribe method can be different from the thread in which the sequence runs till completion. Therefore, the subscribe call is asynchronous in that the caller is not blocked until the observation of the sequence completes. This will be covered in more details in the Using Schedulers topic.</p>
+<p>Notice that the subscribe method returns a Disposable, so that you can unsubscribe to a sequence and dispose of it easily. When you invoke the Dispose method on the observable sequence, the observer will stop listening to the observable for data. Normally, you do not need to explicitly call Dispose unless you need to unsubscribe early, or when the source observable sequence has a longer life span than the observer. Subscriptions in Rx are designed for fire-and-forget scenarios without the usage of a finalizer. When the Disposable instance is collected by the garbage collector, Rx does not automatically dispose of the subscription. However, note that the default behavior of the Observable operators is to dispose of the subscription as soon as possible (i.e, when an OnCompleted or OnError messages is published). </p>
+<p>In addition to creating an observable sequence from scratch, you can convert existing enumerators, C++ events and asynchronous patterns into observable sequences. The other topics in this section will show you how to do this. </p>
+<p>Notice that this topic only shows you a few operators that can create an observable sequence from scratch. To learn more about other LINQ operators, see Query Observable Collections using LINQ Operators.</p>
+<h2>Converting an Enumerable Collection to an Observable Sequence</h2>
+<p>Using the Iterate operator, you can convert an array colection to an observable sequence and subscribe to it. </p>
+<code>
+       std::array< int, 3 > a={1, 2, 3};<br />
+       auto values1 = rxcpp::Iterate(a);<br /><br />
+        rxcpp::from(values1)<br />
+                .for_each(<br />
+            [](int p) {<br />
+                cout << p << endl;<br />
+            });
+</code>
+<h3>See Also</h3>
+Query Observable Collections using LINQ Operators
+<h1>Querying Observable Sequences using LINQ Operators</h1>
+<p>We have converted existing C++ events into observable sequences to subscribe to them. In this topic, we will look at the first-class nature of observable sequences as Observable objects, in which generic LINQ operators are supplied by the Rx header-only library to manipulate these objects. Most operators take an observable sequence and perform some logic on it and output another observable sequence. In addition, as you can see from our code samples, you can even chain multiple operators on a source sequence to tweak the resulting sequence to your exact requirement. </p>
+<h2>Using Different Operators</h2>
+<p>We have already used the Create and Generate operators in previous topics to create and return simple sequences. In this topic, we will use other LINQ operators of the Observable type so that you can filter, group and transform data. Such operators take observable sequence(s) as input, and produce observable sequence(s) as output.</p>
+<h2>Combining different sequences</h2>
+<p>In this section, we will examine some of the operators that combine various observable sequences into a single observable sequence. Notice that data are not transformed when we combine sequences. </p>
+<p>In the following sample, we use the concat operator to combine two sequences into a single sequence and subscribe to it. </p>
+<code>
+auto input1 = std::make_shared&lt;rxcpp::EventLoopScheduler>();<br />
+    auto input2 = std::make_shared&lt;rxcpp::EventLoopScheduler>();<br />
+    auto output = std::make_shared&lt;rxcpp::EventLoopScheduler>();<br /><br />
+    auto values1 = rxcpp::Range(1); // infinite (until overflow) stream of integers<br />
+    auto s1 = rxcpp::from(values1)<br />
+        .subscribe_on(input1)<br />
+        .select([](int prime) -> std::tuple&lt;const char *, int> { return std::make_tuple("1:", prime);})<br />
+        .take(3);<br /><br />
+    auto values2 = rxcpp::Range(1); // infinite (until overflow) stream of integers<br />
+    auto s2 = rxcpp::from(values2)<br />
+        .subscribe_on(input2)<br />
+        .select([](int prime) -> std::tuple&lt;const char *, int> { return std::make_tuple("2:", prime);})<br />
+        .take(3);<br /><br />
+    rxcpp::from(s1)<br />
+        .concat(s2)<br />
+        .observe_on(output)<br />
+        .for_each(rxcpp::MakeTupleDispatch(<br />
+            [](const char* s, int p) {<br />
+                cout  << p << endl;<br />
+            }));
+</code>
+<p>Notice that the resultant sequence is 1,2,3,1,2,3. This is because when you use the concat operator, the 2nd sequence (source2) will not be active until after the 1st sequence (source1) has finished pushing all its values. It is only after source1 has completed, then source2 will start to push values to the resultant sequence. The subscriber will then get all the values from the resultant sequence. </p>
+<p>Compare this with the merge operator. If you run the following sample code, you will get 1,1,2,2,3,3. This is because the two sequences are active at the same time and values are pushed out as they occur in the sources. The resultant sequence only completes when the last source sequence has finished pushing values. </p>
+<p>Notice that for Merge to work, all the source observable sequences need to be of the same type of Observable. The resultant sequence will be of the type Observable. If source1 produces an OnError in the middle of the sequence, then the resultant sequence will complete immediately.</p>
+<code>
+auto input1 = std::make_shared&lt;rxcpp::EventLoopScheduler>();<br />
+    auto input2 = std::make_shared&lt;rxcpp::EventLoopScheduler>();<br />
+    auto output = std::make_shared&lt;rxcpp::EventLoopScheduler>();<br /><br />
+    auto values1 = rxcpp::Range(1); // infinite (until overflow) stream of integers<br />
+    auto s1 = rxcpp::from(values1)<br />
+        .subscribe_on(input1)<br />
+        .select([](int data) -> std::tuple&lt;const char *, int> { return std::make_tuple("1: ", data);});<br /><br />
+    auto values2 = rxcpp::Range(1); // infinite (until overflow) stream of integers<br />
+       rxcpp::from(values2)<br />
+        .subscribe_on(input1)<br />
+        .select([](int data) -> std::tuple&lt;const char *, int> { return std::make_tuple("2: ", data);})<br />
+        .merge(s1)<br />
+        .take(6)<br />
+        .observe_on(output)<br />
+        .for_each(rxcpp::MakeTupleDispatch(<br />
+            [](const char* s, int p) {<br />
+                cout << s << p << endl;<br />
+            }));
+</code>
+<p>Notice that for these combination operators to work, all the observable sequences need to be of the same type. </p>
+<h1>Subjects</h1>
+<p>This section describes the Subject type implemented by Reactive Extensions. It also describes various implementations of Subject which serves different purposes. </p>
+<h3>In This Section</h3>
+<p>1.  Using Subjects</p>
+<h1>Using Subjects</h1>
+<p>The Subject type implements both Observable and Observer, in the sense that it is both an observer and an observable. You can use a subject to subscribe all the observers, and then subscribe the subject to a backend data source. In this way, the subject can act as a proxy for a group of subscribers and a source. You can use subjects to implement a custom observable with caching, buffering and time shifting. In addition, you can use subjects to broadcast data to multiple subscribers. </p>
+<p>By default, subjects do not perform any synchronization across threads. They do not take a scheduler but rather assume that all serialization and grammatical correctness are handled by the caller of the subject.  A subject simply broadcasts to all subscribed observers in the thread-safe list of subscribers. Doing so has the advantage of reducing overhead and improving performance. If, however, you want to synchronize outgoing calls to observers using a scheduler, you can use the Synchronize method to do so.</p>
+<h2>Different types of Subjects</h2>
+<p>The Subject type in the Rx library is a basic implementation of the Subject interface (you can also implement the Subject interface to create your own subject types). There are other implementations of Subject that offer different functionalities. All of these types store some (or all of) values pushed to them via OnNext, and broadcast it back to its observers. This means that if you subscribe to any of these more than once (i.e. subscribe -> unsubscribe -> subscribe again), you will see at least one of the same value again. </p>
+<h1>Scheduling and Concurrency</h1>
+<p>This section describes how you can use a scheduler to control when to start a sequence or subscribe to an event. </p>
+<h1>Scheduler Types</h1>
+<p>The various Scheduler types provided by Rx are:</p>
+<p>ImmediateScheduler: Default scheduler, pushes notifications as they are recieved.</p>
+<p>EventLoopScheduler: Used when creating a separate thread for Rx sequences.</p>
+<h1>Using Schedulers</h1>
+<p>A scheduler controls when a subscription starts and when notifications are published. It consists of three components. It is first a data structure. When you schedule for tasks to be completed, they are put into the scheduler for queueing based on priority or other criteria. It also offers an execution context which denotes where the task is executed (e.g., in the thread pool, current thread, or in another app domain). Lastly, it has a clock which provides a notion of time for itself (by accessing the Now property of a scheduler). Tasks being scheduled on a particular scheduler will adhere to the time denoted by that clock only.</p>
+<h2>Using Schedulers</h2>
+<p>You may have already used schedulers in your Rx code without explicitly stating the type of schedulers to be used. This is because all Observable operators that deal with concurrency have multiple overloads. If you do not use the overload which takes a scheduler as an argument, Rx will pick a default scheduler by using the principle of least concurrency. This means that the scheduler which introduces the least amount of concurrency that satisfies the needs of the operator is chosen.  For example, for operators returning an observable with a finite and small number of messages, Rx calls ImmediateScheduler.  For operators returning a potentially large or infinite number of messages, CurrentThread is called.</p>
+<p>In the following example, the source observable sequences are each running in their own threads using EventLoopScheduler.</p>
+<code>
+auto input1 = std::make_shared&lt;rxcpp::EventLoopScheduler>();<br />
+    auto input2 = std::make_shared&lt;rxcpp::EventLoopScheduler>();<br />
+    auto output = std::make_shared&lt;rxcpp::EventLoopScheduler>();<br /><br />
+    auto values1 = rxcpp::Range(1); // infinite (until overflow) stream of integers<br />
+    auto s1 = rxcpp::from(values1)<br />
+        .subscribe_on(input1)<br />
+        .select([](int data) -> std::tuple&lt;const char *, int> { return std::make_tuple("1:", data);})<br />
+        .take(3);<br /><br />
+    auto values2 = rxcpp::Range(1); // infinite (until overflow) stream of integers<br />
+    auto s2 = rxcpp::from(values2)<br />
+        .subscribe_on(input2)<br />
+        .select([](int data) -> std::tuple&lt;const char *, int> { return std::make_tuple("2:", data);})<br />
+        .take(3);<br /><br />
+    rxcpp::from(s1)<br />
+        .concat(s2)<br />
+        .observe_on(output)<br />
+        .for_each(rxcpp::MakeTupleDispatch(<br />
+            [](const char* s, int p) {<br />
+                cout  << p << endl;<br />
+            }));
+</code>
+<p>This will queue up on the observer quickly. We can improve this code by using the observe_on operator, which allows you to specify the context that you want to use to send pushed notifications (OnNext) to observers. By default, the observe_on operator ensures that OnNext will be called as many times as possible on the current thread. You can use its overloads and redirect the OnNext outputs to a different context. In addition, you can use the subscribe_on operator to return a proxy observable that delegates actions to a specific scheduler. For example, for a UI-intensive application, you can delegate all background operations to be performed on a scheduler running in the background by using subscribe_on and passing to it a Concurrency.EventLoopScheduler. </p>
+<p>You should also note that by using the observe_on operator, an action is scheduled for each message that comes through the original observable sequence. This potentially changes timing information as well as puts additional stress on the system. If you have a query that composes various observable sequences running on many different execution contexts, and you are doing filtering in the query, it is best to place observe_on later in the query. This is because a query will potentially filter out a lot of messages, and placing the observe_on operator earlier in the query would do extra work on messages that would be filtered out anyway. Calling the observe_on operator at the end of the query will create the least performance impact.</p>
+<h1>Implementing Your Own Operators for Observable</h1>
+<p>You can extend Rx by adding new operators for operations that are not provided by the LINQ library, or by creating your own implementation of standard query operators to improve readability and performance. Writing a customized version of a standard LINQ operator is useful when you want to operate with in-memory objects and when the intended customization does not require a comprehensive view of the query.</p>
+<h2>Creating New Operators</h2>
+<p>LINQ offers a full set of operators that cover most of the possible operations on a set of entities. However, you might need an operator to add a particular semantic meaning to your query\97especially if you can reuse that same operator several times in your code. </p>
+<p>By reusing existing LINQ operators when you build a new one, you can take advantage of the existing performance or exception handling capabilities implemented in the Rx libraries.</p>
+<p>When writing a custom operator, it is good practice not to leave any disposables unused; otherwise, you may find that resources could actually be leaked and cancellation may not work correctly.</p>
+<h2>Customizing Existing Operators</h2>
+<p>Adding new operators to LINQ is a way to extend its capabilities. However, you can also improve code readability by wrapping existing operators into more specialized and meaningful ones.</p>
diff --git a/dependencies64/RxCpp/include/cpplinq/linq.hpp b/dependencies64/RxCpp/include/cpplinq/linq.hpp
new file mode 100644 (file)
index 0000000..5f08588
--- /dev/null
@@ -0,0 +1,554 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+/// 
+/// namespace cpplinq
+/// -----------------
+///
+/// Defines a number of range-based composable operators for enumerating and modifying collections
+///
+/// The general design philosophy is to 
+///   (1) emulate the composable query patterns introduced in C# Linq
+///   (2) preserve iterator category and writability where possible
+/// For instance, like C# Linq we have a select operator to project one sequence into a new one.
+/// Unlike Linq, invoking Select on a random access sequence will yield you a _random_ access sequence.
+///
+/// The general workflow begins with 'from()' which normally only takes a reference
+/// the the collection in question. However, from that point on, all operators function 
+/// by value, so that the range can store any necessary state, rather than duplicating it 
+/// onto iterator pairs.
+/// 
+/// In subsequent documentation, "powers" lists which powers that the operator attempts to preserve if
+/// available on on the input sequence. Some iterator powers may be skipped - in such a case, round down
+/// to the next supported power (e.g. if 'fwd' and 'rnd', an input of 'bidi' will round down to a 'fwd' result). 
+/// 
+///  
+///
+/// class linq_query
+/// ----------------
+/// 
+/// from(container&)
+/// ================
+/// -   Result: Query
+/// 
+/// Construct a new query, from an lvalue reference to a collection. Does not copy the collection
+/// 
+/// 
+/// 
+/// from(iter, iter)
+/// ================
+/// -   Result: Query
+/// 
+/// Construct a new query, from an iterator pair.
+/// 
+/// 
+/// 
+/// query.select(map)
+/// ==========================
+/// -   Result: Query 
+/// -   Powers: input, forward, bidirectional, random access
+/// 
+/// For each element `x` in the input sequences, computes `map(x)` for the result sequence.
+/// 
+/// 
+/// 
+/// query.where(pred) -> query
+/// ==========================
+/// -   Result: Query
+/// -   Powers: input, forward, bidirectional
+/// 
+/// Each element `x` in the input appears in the output if `pred(x)` is true.
+/// 
+/// The expression `pred(x)` is evaluated only when moving iterators (op++, op--). 
+/// Dereferencing (op*) does not invoke the predicate.
+/// 
+/// 
+/// 
+/// query.groupby(keymap [, keyequal])
+/// ====================================
+/// Result: Query of groups. Each group has a 'key' field, and is a query of elements from the input.
+/// Powers: forward
+/// 
+/// 
+/// 
+/// query.any([pred])
+/// =================
+/// -   Result: bool
+/// 
+/// (No argument) Returns true if sequence is non-empty. Equivalent to `query.begin()!=query.end()`
+/// 
+/// (One argument) Returns true if the sequence contains any elements for which `pred(element)` is true.
+/// Equivalent to `query.where(pred).any()`.
+/// 
+/// 
+/// 
+/// query.all(pred)
+/// ===============
+/// -   Result: bool
+/// 
+/// Returns true if `pred` holds for all elements in the sequence. Equivalent to `!query.any(std::not1(pred))`
+/// 
+/// 
+/// 
+/// query.take(n)
+/// =============
+/// -   Result: query
+/// -   Powers: input, forward, random access (not bidirectional)
+/// 
+/// Returns a sequence that contains up to `n` items from the original sequence. 
+/// 
+/// 
+/// 
+/// query.skip(n)
+/// =============
+/// -   Result: query
+/// -   Powers: input, forward, random access (not bidirectional)
+/// 
+/// Returns a sequence that skips the first `n` items from the original sequence, or an empty sequence if 
+/// fewer than `n` were available on input.
+/// 
+/// Note: begin() takes O(n) time when input iteration power is weaker than random access.
+/// 
+/// 
+/// 
+/// query.count([pred])
+/// ===================
+/// -   Result: size_t
+/// 
+/// _TODO: should use inner container's iterator distance type instead._
+/// 
+/// (Zero-argument) Returns the number of elements in the range. 
+/// Equivalent to `std::distance(query.begin(), query.end())`
+/// 
+/// (One-argument) Returns the number of elements for whicht `pred(element)` is true.
+/// Equivalent to `query.where(pred).count()`
+/// 
+
+
+#if !defined(CPPLINQ_LINQ_HPP)
+#define CPPLINQ_LINQ_HPP
+#pragma once
+
+#pragma push_macro("min")
+#pragma push_macro("max")
+#undef min
+#undef max
+
+#include <functional>
+#include <iterator>
+#include <algorithm>
+#include <numeric>
+#include <list>
+#include <map>
+#include <memory>
+#include <utility>
+#include <type_traits>
+#include <vector>
+
+
+
+// some configuration macros
+#if _MSC_VER > 1600 || __cplusplus > 199711L
+#define LINQ_USE_RVALUEREF 1
+#endif
+
+#if (defined(_MSC_VER) && _CPPRTTI) || !defined(_MSC_VER)
+#define LINQ_USE_RTTI 1
+#endif
+
+#if defined(__clang__)
+#if __has_feature(cxx_rvalue_references)
+#define LINQ_USE_RVALUEREF 1
+#endif
+#if __has_feature(cxx_rtti)
+#define LINQ_USE_RTTI 1
+#endif
+#endif
+
+
+// individual features 
+#include "util.hpp"
+#include "linq_cursor.hpp"
+#include "linq_iterators.hpp"
+#include "linq_select.hpp"
+#include "linq_take.hpp"
+#include "linq_skip.hpp"
+#include "linq_groupby.hpp"
+#include "linq_where.hpp"
+#include "linq_last.hpp"
+#include "linq_selectmany.hpp"
+
+
+
+
+namespace cpplinq 
+{
+
+namespace detail
+{
+    template<class Pred>
+    struct not1_{
+        Pred pred;
+        not1_(Pred p) : pred(p) 
+        {}
+        template<class T>
+        bool operator()(const T& value)
+        {
+            return !pred(value);
+        }
+    };
+    // note: VC2010's std::not1 doesn't support lambda expressions. provide our own.
+    template<class Pred>
+    not1_<Pred> not1(Pred p) { return not1_<Pred>(p); }
+}
+
+namespace detail {
+    template <class U>
+    struct cast_to {
+        template <class T>
+        U operator()(const T& value) const {
+            return static_cast<U>(value);
+        }
+    };
+}
+
+template <class Collection>
+class linq_driver
+{
+    typedef typename Collection::cursor::element_type
+        element_type;
+    typedef typename Collection::cursor::reference_type
+        reference_type;
+public:
+    typedef cursor_iterator<typename Collection::cursor>
+        iterator;
+
+    linq_driver(Collection c) : c(c) {}
+
+
+    // -------------------- linq core methods --------------------
+
+    template <class KeyFn>
+    linq_driver< linq_groupby<Collection, KeyFn> > groupby(KeyFn fn)
+    {
+        return linq_groupby<Collection, KeyFn>(c, std::move(fn) );
+    }
+
+    // TODO: groupby(keyfn, eq)
+
+    // TODO: join...
+
+    template <class Selector>
+    linq_driver< linq_select<Collection, Selector> > select(Selector sel) const {
+        return linq_select<Collection, Selector>(c, std::move(sel) );
+    }
+
+    template <class Fn>
+    linq_driver< linq_select_many<Collection, Fn, detail::default_select_many_selector> > 
+        select_many(Fn fn) const 
+    {
+        return linq_select_many<Collection, Fn, detail::default_select_many_selector>(c, fn, detail::default_select_many_selector());
+    }
+
+    template <class Fn, class Fn2>
+    linq_driver< linq_select_many<Collection, Fn, Fn2> > select_many(Fn fn, Fn2 fn2) const 
+    {
+        return linq_select_many<Collection, Fn, Fn2>(c, fn, fn2);
+    }
+
+    template <class Predicate>
+    linq_driver< linq_where<Collection, Predicate> > where(Predicate p) const {
+        return linq_where<Collection, Predicate>(c, std::move(p) );
+    }
+    
+
+    // -------------------- linq peripheral methods --------------------
+
+    template <class Fn>
+    element_type aggregate(Fn fn) const
+    {
+        auto it = begin();
+        if (it == end()) {
+            return element_type();
+        }
+        
+        reference_type first = *it;
+        return std::accumulate(++it, end(), first, fn);
+    }
+
+    template <class T, class Fn>
+    T aggregate(T initialValue, Fn fn) const
+    {
+        return std::accumulate(begin(), end(), initialValue, fn);
+    }
+
+    bool any() const { auto cur = c.get_cursor(); return !cur.empty(); }
+
+    template <class Predicate>
+    bool any(Predicate p) const {
+        auto it = std::find_if(begin(), end(), p);
+        return it != end();
+    }
+
+    template <class Predicate>
+    bool all(Predicate p) const {
+        auto it = std::find_if(begin(), end(), detail::not1(p));
+        return it == end();
+    }
+
+    // TODO: average
+
+#if !defined(__clang__)
+    // Clang complains that linq_driver is not complete until the closing brace 
+    // so (linq_driver*)->select() cannot be resolved.
+    template <class U>
+    auto cast() 
+    -> decltype(static_cast<linq_driver*>(0)->select(detail::cast_to<U>())) 
+    {
+        return this->select(detail::cast_to<U>());
+    }
+#endif
+
+    // TODO: concat
+
+    bool contains(const typename Collection::cursor::element_type& value) const {
+        return std::find(begin(), end(), value) != end();
+    }
+
+    typename std::iterator_traits<iterator>::difference_type count() const {
+        return std::distance(begin(), end());
+    }
+
+    template <class Predicate>
+    typename std::iterator_traits<iterator>::difference_type count(Predicate p) const {
+        auto filtered = this->where(p);
+        return std::distance(begin(filtered), end(filtered));
+    }
+
+    // TODO: default_if_empty
+    
+    // TODO: distinct()
+    // TODO: distinct(cmp)
+
+    reference_type element_at(size_t ix) const {
+        auto cur = c.get_cursor();
+        while(ix && !cur.empty()) {
+            cur.inc();
+            --ix;
+        }
+        if (cur.empty()) { throw std::logic_error("index out of bounds"); }
+        else             { return cur.get(); }
+    }
+
+    element_type element_at_or_default(size_t ix) const {
+        auto cur = c.get_cursor();
+        while(ix && !cur.empty()) {
+            cur.inc();
+            -- ix;
+        }
+        if (cur.empty()) { return element_type(); }
+        else             { return cur.get(); }
+    }
+
+    bool empty() const {
+        return !this->any();
+    }
+
+    // TODO: except(second)
+    // TODO: except(second, eq)
+
+    reference_type first() const {
+        auto cur = c.get_cursor();
+        if (cur.empty()) { throw std::logic_error("index out of bounds"); }
+        else             { return cur.get(); }
+    }
+
+    template <class Predicate>
+    reference_type first(Predicate pred) const {
+        auto cur = c.get_cursor();
+        while (!cur.empty() && !pred(cur.get())) {
+            cur.inc();
+        }
+        if (cur.empty()) { throw std::logic_error("index out of bounds"); }
+        else             { return cur.get(); }
+    }
+
+    element_type first_or_default() const {
+        auto cur = c.get_cursor();
+        if (cur.empty()) { return element_type(); }
+        else             { return cur.get(); }
+    }
+
+    template <class Predicate>
+    element_type first_or_default(Predicate pred) const {
+        auto cur = c.get_cursor();
+        while (!cur.empty() && !pred(cur.get())) {
+            cur.inc();
+        }
+        if (cur.empty()) { return element_type(); }
+        else             { return cur.get(); }
+    }
+    
+    // TODO: intersect(second)
+    // TODO: intersect(second, eq)
+
+    // note: forward cursors and beyond can provide a clone, so we can refer to the element directly
+    typename std::conditional< 
+        std::is_convertible<
+            typename Collection::cursor::cursor_category,
+            forward_cursor_tag>::value,
+        reference_type,
+        element_type>::type
+    last() const 
+    {
+        return linq_last_(c.get_cursor(), typename Collection::cursor::cursor_category());
+    }
+
+    template <class Predicate>
+    reference_type last(Predicate pred) const 
+    {
+        auto cur = c.where(pred).get_cursor();
+        return linq_last_(cur, typename decltype(cur)::cursor_category());
+    }
+
+    element_type last_or_default() const 
+    {
+        return linq_last_or_default_(c.get_cursor(), typename Collection::cursor::cursor_category());
+    }
+
+    template <class Predicate>
+    element_type last_or_default(Predicate pred) const 
+    {
+        auto cur = c.where(pred).get_cursor();
+        return linq_last_or_default_(cur, typename decltype(cur)::cursor_category());
+    }
+
+    reference_type max() const
+    {
+        return max(std::less<element_type>());
+    }
+
+    template <class Compare>
+    reference_type max(Compare less) const
+    {
+        auto it = std::max_element(begin(), end(), less);
+        if (it == end()) 
+            throw std::logic_error("max performed on empty range");
+
+        return *it;
+    }
+
+    reference_type min() const
+    {
+        return min(std::less<element_type>());
+    }
+
+    template <class Compare>
+    reference_type min(Compare less) const
+    {
+        auto it = std::min_element(begin(), end(), less);
+        if (it == end()) 
+            throw std::logic_error("max performed on empty range");
+
+        return *it;
+    }
+
+    // TODO: order_by(sel)
+    // TODO: order_by(sel, less)
+    // TODO: order_by_descending(sel)
+    // TODO: order_by_descending(sel, less)
+
+    // TODO: sequence_equal(second)
+    // TODO: sequence_equal(second, eq)
+
+    // TODO: single / single_or_default
+
+    linq_driver<linq_skip<Collection>> skip(size_t n) const {
+        return linq_skip<Collection>(c, n);
+    }
+
+    // TODO: skip_while(pred)
+
+    // TODO: sum
+
+    linq_driver<linq_take<Collection>> take(size_t n) const {
+        return linq_take<Collection>(c, n);
+    }
+
+    // TODO: take_while
+
+    // TODO: then_by / then_by_descending ?
+
+    // TODO: to_...
+
+    // TODO: union(second)
+    // TODO: union(eq)
+
+    // TODO: zip
+    
+    // -------------------- conversion methods --------------------
+
+    std::vector<typename Collection::cursor::element_type> to_vector() const 
+    {
+        return std::vector<typename Collection::cursor::element_type>(begin(), end());
+    }
+
+    // -------------------- container/range methods --------------------
+
+    iterator begin() const  { auto cur = c.get_cursor(); return !cur.empty() ? iterator(cur) : iterator(); }
+    iterator end() const    { return iterator(); }
+    linq_driver& operator=(const linq_driver& other) { c = other.c; return *this; }
+    template <class TC2> 
+    linq_driver& operator=(const linq_driver<TC2>& other) { c = other.c; return *this; }
+
+    typename std::iterator_traits<iterator>::reference
+        operator[](size_t ix) const {
+        return *(begin()+=ix);
+    }
+
+    // -------------------- collection methods (leaky abstraction) --------------------
+
+    typedef typename Collection::cursor cursor;
+    cursor get_cursor() { return c.get_cursor(); }
+
+    linq_driver< dynamic_collection<typename Collection::cursor::reference_type> >
+        late_bind() const
+    {
+        return dynamic_collection<typename Collection::cursor::reference_type>(c);
+    }
+
+private: 
+    Collection c;
+};
+// TODO: should probably use reference-wrapper instead? 
+template <class TContainer>
+linq_driver<iter_cursor<typename util::container_traits<TContainer>::iterator>> from(TContainer& c)
+{ 
+    auto cur = iter_cursor<typename util::container_traits<TContainer>::iterator>(begin(c), end(c));
+    return std::move(cur);
+}
+template <class T>
+const linq_driver<T>& from(const linq_driver<T>& c) 
+{ 
+    return c; 
+}
+template <class Iter>
+linq_driver<iter_cursor<Iter>> from(Iter start, Iter finish)
+{
+    return iter_cursor<Iter>(start, finish);
+}
+
+template <class TContainer>
+linq_driver<TContainer> from_value(const TContainer& c)
+{ 
+    return linq_driver<TContainer>(c);
+}
+
+}
+
+#pragma pop_macro("min")
+#pragma pop_macro("max")
+
+#endif // defined(CPPLINQ_LINQ_HPP)
+
diff --git a/dependencies64/RxCpp/include/cpplinq/linq_cursor.hpp b/dependencies64/RxCpp/include/cpplinq/linq_cursor.hpp
new file mode 100644 (file)
index 0000000..8c95371
--- /dev/null
@@ -0,0 +1,340 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !defined(CPPLINQ_LINQ_CURSOR_HPP)
+#define CPPLINQ_LINQ_CURSOR_HPP
+#pragma once
+
+/// cursors
+/// ----------
+/// It should be noted that CppLinq uses a slightly different iterator concept, one where iterators
+/// know their extents. This sacrificed some generality, but it adds convenience and improves
+/// some performance in some cases. Notably, captures need only be stored once instead of twice in 
+/// most use cases.
+/// 
+/// Cursors and Ranges are always classes.
+/// 
+/// To get a cursor from a range:
+/// 
+///    get_cursor(range) -> cur
+/// 
+/// Unlike boost ranges, CppLinq cursors are mutated directly, and may "shed state" as they are
+/// mutated. For example, a GroupBy range will drop references to earlier groups, possibly 
+/// permitting freeing them.
+/// 
+/// Onepass cursor
+/// ===========
+/// -   empty(cur) -> bool  : at end of sequence
+/// -   inc(cur) 
+/// -   get(cur) -> T 
+/// -   copy ctor           : duplicate reference to seek position
+/// 
+/// Forward cursor
+/// =============
+/// -   copy ctor           : true duplicate of seek position
+/// 
+/// Bidirectional cursor
+/// ====================
+/// -   forget()            : notes the current element as the new 'begin' point
+/// -   atbegin(cur) -> bool
+/// -   dec(cur)
+/// 
+/// Random access cursor
+/// ====================
+/// -   skip(cur, n)
+/// -   position(cur) -> n
+/// -   size(cur)     -> n
+/// -   truncate(n)         : keep only n more elements
+/// 
+/// As well, cursors must define the appropriate type/typedefs:
+/// -   cursor_category  :: { onepass_cursor_tag, forward_cursor_tag, bidirectional_cursor_tag, random_access_cursor_tag }
+/// -   element_type
+/// -   reference_type   : if writable, element_type& or such. else, == element_type
+/// -   
+
+
+
+namespace cpplinq { 
+
+    // used to identify cursor-based collections
+    struct collection_tag {};
+
+    struct onepass_cursor_tag {};
+    struct forward_cursor_tag : onepass_cursor_tag  {};
+    struct bidirectional_cursor_tag : forward_cursor_tag {}; 
+    struct random_access_cursor_tag : bidirectional_cursor_tag {};
+
+    struct noread_cursor_tag {}; // TODO: remove if not used
+    struct readonly_cursor_tag : noread_cursor_tag {};
+    struct readwrite_cursor_tag : readonly_cursor_tag {};
+
+
+
+    // standard cursor adaptors
+
+    namespace util 
+    {
+        namespace detail 
+        {
+            template <size_t n> struct type_to_size { char value[n]; };
+
+            type_to_size<1> get_category_from_iterator(std::input_iterator_tag);
+            type_to_size<2> get_category_from_iterator(std::forward_iterator_tag);
+            type_to_size<3> get_category_from_iterator(std::bidirectional_iterator_tag);
+            type_to_size<4> get_category_from_iterator(std::random_access_iterator_tag);
+        }
+
+        template <size_t>
+        struct iter_to_cursor_category_;
+
+        template <class Iter>
+        struct iter_to_cursor_category
+        {
+            static const size_t catIx = sizeof(detail::get_category_from_iterator(typename std::iterator_traits<Iter>::iterator_category()) /*.value*/  );
+            typedef typename iter_to_cursor_category_<catIx>::type type;
+        };
+
+        template <> struct iter_to_cursor_category_<1> { typedef onepass_cursor_tag type; };
+        template <> struct iter_to_cursor_category_<2> { typedef forward_cursor_tag type; };
+        template <> struct iter_to_cursor_category_<3> { typedef bidirectional_cursor_tag type; };
+        template <> struct iter_to_cursor_category_<4> { typedef random_access_cursor_tag type; };
+
+
+        // Note: returns false if no partial order exists between two 
+        // particular iterator categories, such as with some of the boost categories
+        template <class Cat1, class Cat2>
+        struct less_or_equal_cursor_category
+        {
+        private:
+            typedef char yes;
+            typedef struct { char c1,c2; } no;
+            static yes invoke(Cat1);
+            static no invoke(...);
+        public:
+            enum { value = (sizeof(invoke(Cat2())) == sizeof(yes)) };
+        };
+
+        // Return the weaker of the two iterator categories. Make sure 
+        //   a non-standard category is in the second argument position, as 
+        //   this metafunction will default to the first value if the order is undefined
+        template <class Cat1, class Cat2, class Cat3 = void>
+        struct min_cursor_category : min_cursor_category<typename min_cursor_category<Cat1, Cat2>::type, Cat3>
+        {
+        };
+
+        template <class Cat1, class Cat2>
+        struct min_cursor_category<Cat1, Cat2>
+            : std::conditional<
+                less_or_equal_cursor_category<Cat2, Cat1>::value,
+                Cat2,
+                Cat1>
+        {
+        };
+
+        template <class Collection>
+        struct cursor_type {
+            typedef decltype(cursor(*static_cast<Collection*>(0))) type;
+        };
+    }
+    
+    // simultaniously models a cursor and a cursor-collection
+    template <class Iterator>
+    class iter_cursor : collection_tag {
+    public:
+
+        typedef iter_cursor cursor;
+
+        typedef typename std::remove_reference<typename std::iterator_traits<Iterator>::value_type>::type
+            element_type;
+        typedef typename std::iterator_traits<Iterator>::reference
+            reference_type;
+        typedef typename util::iter_to_cursor_category<Iterator>::type
+            cursor_category;
+
+        void forget() { start = current; }
+        bool empty() const { return current == fin; }
+        void inc() { 
+            if (current == fin)
+                throw std::logic_error("inc past end");
+            ++current; 
+        }
+        typename std::iterator_traits<Iterator>::reference get() const { return *current; }
+
+        bool atbegin() const { return current == start; }
+        void dec() { 
+            if (current == start) 
+                throw std::logic_error("dec past begin");
+            --current; 
+        }
+        
+        void skip(ptrdiff_t n) { current += n; }
+        size_t size() { return fin-start; }
+        void position() { return current-start; }
+        void truncate(size_t n) {
+            if (n > fin-current) {
+                fin = current + n;
+            }
+        }
+
+
+        iter_cursor(Iterator start, Iterator fin)
+        : current(start)
+        , start(start)
+        , fin(std::move(fin))
+        {
+        }
+
+        iter_cursor(Iterator start, Iterator fin, Iterator current)
+        : current(std::move(current))
+        , start(std::move(start))
+        , fin(std::move(fin))
+        {
+        }
+
+        iter_cursor get_cursor() const { return *this; }
+
+    private:
+        Iterator current;
+        Iterator start, fin;
+    };
+
+
+    template <class T>
+    struct cursor_interface
+    {
+        virtual bool empty() const = 0;
+        virtual void inc() = 0;
+        virtual cursor_interface* copy() const = 0;
+
+        virtual T get() const = 0;
+
+        virtual ~cursor_interface() {}
+    };
+
+    template <class T>
+    class dynamic_cursor : collection_tag
+    {
+        template <class Cur>
+        struct instance : cursor_interface<T>
+        {
+            Cur innerCursor;
+
+            instance(Cur cursor) : innerCursor(std::move(cursor))
+            {
+            }
+            virtual bool empty() const
+            {
+                return innerCursor.empty();
+            }
+            virtual void inc()
+            {
+                innerCursor.inc();
+            }
+            virtual T get() const 
+            {
+                return innerCursor.get();
+            }
+            virtual cursor_interface<T>* copy() const 
+            {
+                return new instance(*this);
+            }
+        };
+
+        std::unique_ptr<cursor_interface<T>> myCur;
+
+    public:
+        typedef forward_cursor_tag cursor_category; // TODO: not strictly true!
+        typedef typename std::remove_reference<T>::type element_type;
+        typedef T reference_type;
+
+        dynamic_cursor() {}
+
+        dynamic_cursor(const dynamic_cursor& other)
+        : myCur(other.myCur ? other.myCur->copy() : nullptr)
+        {
+        }
+
+        dynamic_cursor(dynamic_cursor&& other)
+        : myCur(other.myCur.release())
+        {
+        }
+
+        template <class Cursor>
+        dynamic_cursor(Cursor cursor) 
+        : myCur(new instance<Cursor>(std::move(cursor)))
+        { 
+        }
+
+        template <class Iterator>
+        dynamic_cursor(Iterator start, Iterator end)
+        {
+            *this = iter_cursor<Iterator>(start, end);
+        }
+
+        bool empty() const { return !myCur || myCur->empty(); }
+        void inc() { myCur->inc(); }
+        T get() const { return myCur->get(); }
+
+        dynamic_cursor& operator=(dynamic_cursor other)
+        {
+            std::swap(myCur, other.myCur);
+            return *this;
+        }
+    };
+
+    template <class T>
+    struct container_interface
+    {
+        virtual dynamic_cursor<T> get_cursor() const = 0;
+    };
+
+    template <class T>
+    class dynamic_collection
+    {
+        std::shared_ptr< container_interface<T> > container;
+
+        template <class Container>
+        struct instance : container_interface<T>
+        {
+            Container c;
+
+            instance(Container c) : c(c)
+            {
+            }
+
+            dynamic_cursor<T> get_cursor() const
+            {
+                return c.get_cursor();
+            }
+        };
+
+    public:
+        typedef dynamic_cursor<T> cursor;
+        
+        dynamic_collection() {}
+
+        dynamic_collection(const dynamic_collection& other) 
+        : container(other.container) 
+        {
+        }
+
+        // container or query
+        template <class Container>
+        dynamic_collection(Container c) 
+        : container(new instance<Container>(c))
+        {
+        }
+
+        // container or query
+        template <class Iterator>
+        dynamic_collection(Iterator begin, Iterator end) 
+        : container(new instance< iter_cursor<Iterator> >(iter_cursor<Iterator>(begin, end)))
+        {
+        }
+        
+        dynamic_cursor<T> get_cursor() const {
+            return container ? container->get_cursor() : dynamic_cursor<T>();
+        }
+    };
+}
+
+#endif // !defined(CPPLINQ_LINQ_CURSOR_HPP
diff --git a/dependencies64/RxCpp/include/cpplinq/linq_groupby.hpp b/dependencies64/RxCpp/include/cpplinq/linq_groupby.hpp
new file mode 100644 (file)
index 0000000..c521e5e
--- /dev/null
@@ -0,0 +1,195 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !defined(CPPLINQ_LINQ_GROUPBY_HPP)
+#define CPPLINQ_LINQ_GROUPBY_HPP
+#pragma once
+
+namespace cpplinq 
+{
+
+template <class Iter, class Key>
+struct group
+{
+    Key key;
+    Iter start;
+    Iter fin;
+
+    typedef Iter iterator;
+    typedef Iter const_iterator;
+
+    group(){}
+
+    group(const Key& key) : key(key)
+    {
+    }
+
+    Iter begin() const { return start; }
+    Iter end() const { return fin; }
+};
+
+struct default_equality
+{
+    template <class T>
+    bool operator()(const T& a, const T& b) const {
+        return a == b;
+    }
+};
+struct default_less
+{
+    template<class T>
+    bool operator()(const T& a, const T& b) const {
+        return a < b;
+    }
+};
+
+// progressively constructs grouping as user iterates over groups and elements
+//   within each group. Performs this task by building a std::list of element 
+//   iterators with equal elements within each group.
+// 
+// invariants:
+//   - relative order of groups corresponds to relative order of each group's first 
+//     element, as they appeared in the input sequence.
+//   - relative order of elements within a group correspond to relative order
+//     as they appeared in the input sequence.
+// 
+// requires:
+//   Iter must be a forward iterator.
+template <class Collection, class KeyFn, class Compare = default_less>
+class linq_groupby
+{
+    typedef typename Collection::cursor 
+        inner_cursor;
+
+    typedef typename util::result_of<KeyFn(typename inner_cursor::element_type)>::type
+        key_type;
+
+    typedef std::list<typename inner_cursor::element_type>
+        element_list_type;
+
+    typedef group<typename element_list_type::iterator, key_type> 
+        group_type;
+
+    typedef std::list<group_type>
+        group_list_type;
+
+private:
+    struct impl_t
+    {
+        // TODO: would be faster to use a chunked list, where
+        //   pointers are invalidated but iterators are not. Need 
+        //   benchmarks first
+
+        element_list_type                           elements;
+        std::list<group_type>                       groups;
+        std::map<key_type, group_type*, Compare>    groupIndex;
+
+
+
+        KeyFn keySelector;
+        Compare comp;
+        
+        impl_t(inner_cursor cur,
+               KeyFn keySelector,
+               Compare comp = Compare()) 
+        : keySelector(keySelector)
+        , groupIndex(comp)
+        {
+            // TODO: make lazy
+            insert_all(std::move(cur));
+        }
+
+        void insert_all(inner_cursor cur)
+        {
+            while(!cur.empty()) {
+                insert(cur.get());
+                cur.inc();
+            }
+        }
+        void insert(typename inner_cursor::reference_type element)
+        {
+            key_type key = keySelector(element);
+            auto groupPos = groupIndex.find(key);
+            if(groupPos == groupIndex.end()) {
+                // new group
+                bool firstGroup = groups.empty();
+
+                elements.push_back(element);
+                if(!firstGroup) {
+                    // pop new element out of previous group
+                    --groups.back().fin; 
+                }
+
+                // build new group
+                groups.push_back(group_type(key));
+                group_type& newGroup = groups.back();
+
+                groupIndex.insert( std::make_pair(key, &newGroup) );
+
+                newGroup.fin = elements.end();
+                --(newGroup.start = newGroup.fin);
+            } else {
+                // add to existing group at end
+                elements.insert(groupPos->second->end(), element);
+            }
+        }
+    };
+
+public:
+    struct cursor {
+        typedef group_type
+            element_type;
+
+        typedef element_type
+            reference_type;
+
+        typedef forward_cursor_tag
+            cursor_category;
+
+        cursor(inner_cursor   cur, 
+               KeyFn          keyFn,
+               Compare        comp = Compare()) 
+        {
+            impl.reset(new impl_t(cur, keyFn, comp));
+            inner   = impl->groups.begin();
+            fin     = impl->groups.end();
+        }
+
+        void forget() { } // nop on forward-only cursors
+        bool empty() const {
+            return inner == fin;
+        }
+        void inc() {
+            if (inner == fin) {
+                throw std::logic_error("attempt to iterate past end of range");
+            }
+            ++inner;
+        }
+        reference_type get() const {
+            return *inner;
+        }
+        
+    private:
+        std::shared_ptr<impl_t> impl;
+        typename std::list<group_type>::iterator inner;
+        typename std::list<group_type>::iterator fin;
+    };
+
+    linq_groupby(Collection     c, 
+                 KeyFn          keyFn,
+                 Compare        comp = Compare()) 
+    : c(c), keyFn(keyFn), comp(comp)
+    {
+    }
+
+    cursor get_cursor() const { return cursor(c.get_cursor(), keyFn, comp); }
+
+private:
+    Collection c;
+    KeyFn keyFn;
+    Compare comp;
+};
+
+}
+
+#endif // !defined(CPPLINQ_LINQ_GROUPBY_HPP)
+
diff --git a/dependencies64/RxCpp/include/cpplinq/linq_iterators.hpp b/dependencies64/RxCpp/include/cpplinq/linq_iterators.hpp
new file mode 100644 (file)
index 0000000..a04b217
--- /dev/null
@@ -0,0 +1,194 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !defined(CPPLINQ_LINQ_ITERATORS_HPP)
+#define CPPLINQ_LINQ_ITERATORS_HPP
+#pragma once
+
+namespace cpplinq {
+
+    // if a member, provides the straightforward implementation of various redundant operators. For example,
+    //   providing -> for any iterator providing *, and so forth.
+    struct use_default_iterator_operators {};
+
+    #define CPPLINQ_USE_DEFAULT_ITERATOR_OPERATORS \
+    operator ::cpplinq::use_default_iterator_operators() const { return ::cpplinq::use_default_iterator_operators(); }
+
+    template <class Iter>
+    typename std::enable_if<
+        std::is_convertible<Iter, use_default_iterator_operators>::value,
+        Iter
+        >::type
+    operator+(const Iter& it, typename std::iterator_traits<Iter>::distance_type n) {
+        return it += n;
+    }
+    template <class Iter>
+    typename std::enable_if<
+        std::is_convertible<Iter, use_default_iterator_operators>::value,
+        Iter
+        >::type
+    operator-(const Iter& it, typename std::iterator_traits<Iter>::distance_type n) {
+        return it -= n;
+    }
+    template <class Iter>
+    typename std::enable_if<
+        std::is_convertible<Iter, use_default_iterator_operators>::value,
+        Iter
+        >::type
+    operator-=(const Iter& it, typename std::iterator_traits<Iter>::distance_type n) {
+        return it += (-n);
+    }
+
+    template <class Iter>
+    typename std::enable_if<
+        std::is_convertible<Iter, use_default_iterator_operators>::value,
+        bool
+        >::type
+    operator!=(const Iter& it, const Iter& it2) {
+        return !(it == it2);
+    }
+    template <class Iter>
+    typename std::enable_if<
+        std::is_convertible<Iter, use_default_iterator_operators>::value,
+        bool
+        >::type
+    operator>(const Iter& it, const Iter& it2) {
+        return it2 < it;
+    }
+    template <class Iter>
+    typename std::enable_if<
+        std::is_convertible<Iter, use_default_iterator_operators>::value,
+        bool
+        >::type
+    operator<=(const Iter& it, const Iter& it2) {
+        return !(it2 < it);
+    }
+    template <class Iter>
+    typename std::enable_if<
+        std::is_convertible<Iter, use_default_iterator_operators>::value,
+        bool
+        >::type
+    operator>=(const Iter& it, const Iter& it2) {
+        return !(it < it2);
+    }   
+    
+    namespace util {
+        template <class Iter, class T>
+        typename std::iterator_traits<Iter>::pointer deref_iterator(const Iter& it) {
+            return deref_iterator(it, util::identity<typename std::iterator_traits<Iter>::reference>());
+        }
+
+        template <class Iter, class T>
+        T* deref_iterator(const Iter& it, util::identity<T&>) {
+            return &*it;
+        }
+
+        template <class Iter, class T>
+        util::value_ptr<T> deref_iterator(const Iter& it, util::identity<T>) {
+            return util::value_ptr<T>(*it);
+        }
+    } 
+    
+    
+    template <class Iter>
+    class iter_range
+    {
+        Iter start, finish;
+    public:
+
+        CPPLINQ_USE_DEFAULT_ITERATOR_OPERATORS
+
+        typedef Iter iterator;
+        typedef typename iterator::value_type value_type;
+
+        explicit iter_range(Iter start, Iter finish) : start(start), finish(finish) {}
+        iterator begin() const { return start; }
+        iterator end() const { return finish; }
+    };
+    template <class Iter>
+    iter_range<Iter> make_range(Iter start, Iter finish) {
+        return iter_range<Iter>(start, finish);
+    }
+
+    // decays into a onepass/forward iterator
+    template <class Cursor>
+    class cursor_iterator 
+        : public std::iterator<std::forward_iterator_tag, 
+                typename Cursor::element_type,
+                ptrdiff_t,
+                typename std::conditional<std::is_reference<typename Cursor::reference_type>::value,
+                                          typename std::add_pointer<typename Cursor::element_type>::type,
+                                          util::value_ptr<typename Cursor::element_type>>::type,
+                typename Cursor::reference_type>
+    {
+    public:
+        CPPLINQ_USE_DEFAULT_ITERATOR_OPERATORS;
+
+        cursor_iterator(Cursor cur) : cur(cur) {
+        }
+
+        cursor_iterator() : cur() {
+        }
+
+        bool operator==(const cursor_iterator& other) const {
+            return !cur && !other.cur;
+        }
+
+        typename Cursor::reference_type operator*() const {
+            return cur->get();
+        }
+
+        typename cursor_iterator::pointer operator->() const {
+            auto& v = **this;
+            return &v;
+        }
+        
+        cursor_iterator& operator++() {
+            cur->inc();
+
+            if (cur->empty()) { cur.reset(); }
+            return *this;
+        }
+
+        cursor_iterator& operator+=(ptrdiff_t n) {
+            cur->skip(n);
+
+            if (cur->empty()) { cur.reset(); }
+            return *this;
+        }
+
+
+        
+    private:
+        bool empty() const {
+            !cur || cur->empty();
+        }
+
+        util::maybe<Cursor> cur;
+    };
+
+    template <class Container>
+    class container_range
+    {
+        Container c;
+
+    public:
+        typedef cursor_iterator<typename Container::cursor> iterator;
+
+        container_range(Container c) : c(c) 
+        {
+        }
+
+        iterator begin() const
+        {
+            return iterator(c.get_cursor());
+        }
+
+        iterator end() const
+        {
+            return iterator();
+        }
+    };
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/cpplinq/linq_last.hpp b/dependencies64/RxCpp/include/cpplinq/linq_last.hpp
new file mode 100644 (file)
index 0000000..fd08823
--- /dev/null
@@ -0,0 +1,85 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !defined(CPPLINQ_LINQ_LAST_HPP)
+#define CPPLINQ_LINQ_LAST_HPP
+#pragma once
+
+namespace cpplinq { 
+
+    template <class Cursor>
+    typename Cursor::element_type
+        linq_last_(Cursor c, onepass_cursor_tag)
+    {
+        if (c.empty()) { throw std::logic_error("last() out of bounds"); }
+        typename Cursor::element_type elem = c.get();
+        for(;;) {
+            c.inc();
+            if (c.empty()) break;
+            elem = c.get();
+        }
+        return std::move(elem);
+    }
+
+    // TODO: bidirectional iterator in constant time
+
+    template <class Cursor>
+    typename Cursor::reference_type
+        linq_last_(Cursor c, forward_cursor_tag)
+    {
+        if (c.empty()) { throw std::logic_error("last() out of bounds"); }
+        Cursor best = c;
+        for(;;) {
+            c.inc();
+            if (c.empty()) break;
+            best = c;
+        }
+        return best.get();
+    }
+
+    template <class Cursor>
+    typename Cursor::reference_type
+        linq_last_(Cursor c, random_access_cursor_tag)
+    {
+        if (c.empty()) { throw std::logic_error("last() out of bounds"); }
+        c.skip(c.size()-1);
+        return c.get();
+    }
+
+    template <class Cursor>
+    typename Cursor::element_type
+        linq_last_or_default_(Cursor c, onepass_cursor_tag)
+    {
+        typename Cursor::element_type elem;
+        while(!c.empty()) {
+            elem = c.get();
+            c.inc();
+        }
+        return std::move(elem);
+    }
+
+    template <class Cursor>
+    typename Cursor::element_type
+        linq_last_or_default_(Cursor c, forward_cursor_tag)
+    {
+        if (c.empty()) { throw std::logic_error("last() out of bounds"); }
+        Cursor best = c;
+        for(;;) {
+            c.inc();
+            if (c.empty()) break;
+            best = c;
+        }
+        return best.get();
+    }
+
+    template <class Cursor>
+    typename Cursor::element_type
+        linq_last_or_default_(Cursor c, random_access_cursor_tag)
+    {
+        if (c.empty()) { return typename Cursor::element_type(); }
+        c.skip(c.size()-1);
+        return c.get();
+    }
+
+}
+
+#endif // CPPLINQ_LINQ_LAST_HPP
diff --git a/dependencies64/RxCpp/include/cpplinq/linq_select.hpp b/dependencies64/RxCpp/include/cpplinq/linq_select.hpp
new file mode 100644 (file)
index 0000000..650a1dc
--- /dev/null
@@ -0,0 +1,52 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !defined(CPPLINQ_LINQ_SELECT_HPP)
+#define CPPLINQ_LINQ_SELECT_HPP
+#pragma once
+
+namespace cpplinq 
+{
+    template <class Collection, class Selector>
+    class linq_select
+    {
+        typedef typename Collection::cursor 
+            inner_cursor;
+    public:
+        struct cursor {
+            typedef typename util::result_of<Selector(typename inner_cursor::element_type)>::type
+                reference_type;
+            typedef typename std::remove_reference<reference_type>::type
+                element_type;
+            typedef typename inner_cursor::cursor_category
+                cursor_category;
+            
+            cursor(const inner_cursor& cur, Selector sel) : cur(cur), sel(std::move(sel)) {}
+
+            void forget() { cur.forget(); }
+            bool empty() const { return cur.empty(); }
+            void inc() { cur.inc(); }
+            reference_type get() const { return sel(cur.get()); }
+
+            bool atbegin() const { return cur.atbegin(); }
+            void dec() { cur.dec(); }
+
+            void skip(size_t n) { cur.skip(n); }
+            size_t position() const { return cur.position(); }
+            size_t size() const { return cur.size(); }
+        private:
+            inner_cursor    cur;
+            Selector        sel;
+        };
+
+        linq_select(const Collection& c, Selector sel) : c(c), sel(sel) {}
+
+        cursor get_cursor() const { return cursor(c.get_cursor(), sel); }
+
+    private:
+        Collection c;
+        Selector sel;
+    };
+
+}
+
+#endif // defined(CPPLINQ_LINQ_SELECT_HPP)
diff --git a/dependencies64/RxCpp/include/cpplinq/linq_selectmany.hpp b/dependencies64/RxCpp/include/cpplinq/linq_selectmany.hpp
new file mode 100644 (file)
index 0000000..45f0574
--- /dev/null
@@ -0,0 +1,107 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#include "util.hpp"
+#include "linq_cursor.hpp"
+
+namespace cpplinq 
+{
+    namespace detail 
+    {
+        struct default_select_many_selector
+        {
+            template <class T1, class T2>
+            auto operator()(T1&& t1, T2&& t2) const
+            -> decltype(std::forward<T2>(t2))
+            {
+                return std::forward<T2>(t2);
+            }
+        };
+    }
+
+    // cur<T> -> (T -> cur<element_type>) -> cur<element_type>
+    template <class Container1, class Fn, class Fn2>
+    class linq_select_many
+    {
+        template <class T> static T instance(); // for type inference
+
+        Container1      c1;
+        Fn              fn;
+        Fn2             fn2;
+
+        typedef typename Container1::cursor Cur1;
+        typedef decltype(from(instance<Fn>()(instance<Cur1>().get()))) Container2;
+        typedef typename Container2::cursor Cur2;
+
+    public:
+        class cursor
+        {
+        public:
+            typedef typename util::min_cursor_category<typename Cur1::cursor_category,
+                                                       typename Cur2::cursor_category,
+                                                       forward_cursor_tag>::type
+                cursor_category;
+            typedef typename Cur2::reference_type reference_type;
+            typedef typename Cur2::element_type element_type;
+
+        private:
+            // TODO: we need to lazy eval somehow, but this feels wrong.
+            Cur1                            cur1;
+            dynamic_cursor<reference_type>  cur2;
+            Fn                              fn;
+            Fn2                             fn2;
+
+        public:
+            cursor(Cur1 cur1, const Fn& fn, const Fn2& fn2)
+            : cur1(std::move(cur1)), fn(fn), fn2(fn2)
+            {
+                auto container2 = fn(cur1.get());
+                cur2 = from(container2).get_cursor();
+            }
+
+            bool empty() const 
+            {
+                return cur2.empty();
+            }
+
+            void inc() 
+            {
+                cur2.inc();
+                thunk();
+            }
+
+            reference_type get() const 
+            {
+                return fn2(cur1.get(), cur2.get());
+            }
+
+        private:
+            void thunk() 
+            {
+                // refill cur2
+                while (cur2.empty() && !cur1.empty()) {
+                    cur1.inc();
+                    if (cur1.empty()) 
+                        break;
+
+                    auto container2 = fn(cur1.get());
+                    cur2 = from(container2).get_cursor();
+                }
+            }
+        };
+
+        linq_select_many(Container1 c1, Fn fn, Fn2 fn2) 
+        : c1(std::move(c1)), fn(std::move(fn)), fn2(std::move(fn2))
+        {
+        }
+
+        cursor get_cursor() const
+        {
+            return cursor(c1.get_cursor(), fn, fn2);
+        }
+    };
+}
+
+
+
diff --git a/dependencies64/RxCpp/include/cpplinq/linq_skip.hpp b/dependencies64/RxCpp/include/cpplinq/linq_skip.hpp
new file mode 100644 (file)
index 0000000..422592a
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !defined(CPPLINQ_LINQ_SKIP_HPP)
+#define CPPLINQ_LINQ_SKIP_HPP
+#pragma once
+
+namespace cpplinq 
+{
+    template <class Collection>
+    struct linq_skip
+    {
+    public:
+        typedef typename Collection::cursor cursor;
+
+        linq_skip(const Collection& c, size_t n) : c(c), n(n) {}
+
+        cursor get_cursor() const {
+            size_t rem = n;
+
+            auto cur = c.get_cursor();
+            while(rem-- && !cur.empty()) {
+                cur.inc();
+            }
+            cur.forget();
+            return std::move(cur);
+        }
+
+    private:
+        Collection  c;
+        size_t      n;
+    };
+}
+#endif // !defined(CPPLINQ_LINQ_SKIP_HPP)
+
+
diff --git a/dependencies64/RxCpp/include/cpplinq/linq_take.hpp b/dependencies64/RxCpp/include/cpplinq/linq_take.hpp
new file mode 100644 (file)
index 0000000..63f7449
--- /dev/null
@@ -0,0 +1,96 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !defined(CPPLINQ_LINQ_TAKE_HPP)
+#define CPPLINQ_LINQ_TAKE_HPP
+#pragma once
+
+namespace cpplinq 
+{
+    template <class InnerCursor>
+    struct linq_take_cursor
+    {
+        typedef typename InnerCursor::element_type element_type;
+        typedef typename InnerCursor::reference_type reference_type;
+        typedef typename InnerCursor::cursor_category cursor_category;
+
+        linq_take_cursor(const InnerCursor& cur, size_t rem) : cur(cur), rem(rem) {}
+
+        void forget() { cur.forget(); }
+        bool empty() const { return cur.empty() || rem == 0; }
+        void inc() { cur.inc(); --rem; }
+        reference_type get() const { return cur.get(); }
+
+        bool atbegin() const { return cur.atbegin(); }
+        void dec() { cur.dec(); --rem; }
+
+        void skip(size_t n) { cur.skip(n); rem -= n; }
+        size_t position() const { return cur.position(); }
+        size_t size() const { return cur.size(); }
+            
+    private:
+        InnerCursor cur;
+        size_t      rem;
+    };
+
+    namespace detail {
+        template <class Collection>
+        linq_take_cursor<typename Collection::cursor> 
+            take_get_cursor_(
+                const Collection& c,
+                size_t n,
+                onepass_cursor_tag
+                )
+        {
+            return linq_take_cursor<typename Collection::cursor>(c.get_cursor(), n);
+        }
+
+        template <class Collection>
+        typename Collection::cursor
+            take_get_cursor_(
+                const Collection& c,
+                size_t n,
+                random_access_cursor_tag
+                )
+        {
+            auto cur = c.get_cursor();
+            if (cur.size() > n) {
+                cur.truncate(n);
+            }
+            return std::move(cur);
+        }
+    }
+
+    template <class Collection>
+    struct linq_take
+    {
+        typedef typename std::conditional<
+                util::less_or_equal_cursor_category<
+                    random_access_cursor_tag,
+                    typename Collection::cursor::cursor_category>::value,
+                typename Collection::cursor,
+                linq_take_cursor<typename Collection::cursor>>::type
+            cursor;
+
+        linq_take(const Collection& c, size_t n) : c(c), n(n) {}
+
+        cursor get_cursor() const {
+            return detail::take_get_cursor_(c, n, typename Collection::cursor::cursor_category());
+        }
+
+        Collection  c;
+        size_t      n;
+    };
+
+    template <class Collection>
+    auto get_cursor(
+            const linq_take<Collection>& take
+            )
+    -> decltype(get_cursor_(take, typename Collection::cursor::cursor_category()))
+    {
+        return get_cursor_(take, typename Collection::cursor::cursor_category());
+    }
+
+
+}
+#endif // !defined(CPPLINQ_LINQ_TAKE_HPP)
+
diff --git a/dependencies64/RxCpp/include/cpplinq/linq_where.hpp b/dependencies64/RxCpp/include/cpplinq/linq_where.hpp
new file mode 100644 (file)
index 0000000..9b3d936
--- /dev/null
@@ -0,0 +1,69 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !defined(CPPLINQ_LINQ_WHERE_HPP)
+#define CPPLINQ_LINQ_WHERE_HPP
+#pragma once
+
+namespace cpplinq 
+{
+    template <class Collection, class Predicate>
+    class linq_where
+    {
+        typedef typename Collection::cursor 
+            inner_cursor;
+    public:
+        struct cursor {
+            typedef typename util::min_iterator_category<
+                    bidirectional_cursor_tag,
+                    typename inner_cursor::cursor_category>::type
+                cursor_category;
+            typedef typename inner_cursor::element_type
+                element_type;
+            typedef typename inner_cursor::reference_type
+                reference_type;
+
+            cursor(const inner_cursor& cur, const Predicate& p) : cur(cur), pred(p)
+            {
+                if (!cur.empty() && !pred(cur.get())) {
+                    this->inc();
+                }
+            }
+
+            void forget() { cur.forget(); }
+            bool empty() const { return cur.empty(); }
+            void inc() { 
+                for (;;) {
+                    cur.inc();
+                    if (cur.empty() || pred(cur.get())) break;
+                }
+            }
+            reference_type get() const { 
+                return cur.get();
+            }
+
+            bool atbegin() const { return atbegin(cur); }
+            void dec() {
+                for (;;) {
+                    cur.dec();
+                    if (pred(cur.get())) break;
+                }
+            }
+        private:
+            inner_cursor cur;
+            Predicate pred;
+        };
+
+        linq_where(const Collection& c, Predicate pred) : c(c), pred(pred) {}
+
+        cursor get_cursor() const { 
+            return cursor(c.get_cursor(), pred); 
+        }
+
+    private:
+        Collection c;
+        Predicate   pred;
+    };
+}
+
+#endif // !defined(CPPLINQ_LINQ_WHERE_HPP)
+
diff --git a/dependencies64/RxCpp/include/cpplinq/util.hpp b/dependencies64/RxCpp/include/cpplinq/util.hpp
new file mode 100644 (file)
index 0000000..ee3d7eb
--- /dev/null
@@ -0,0 +1,232 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if !defined(CPPLINQ_LINQ_UTIL_HPP)
+#define CPPLINQ_LINQ_UTIL_HPP
+#pragma once
+
+namespace cpplinq { namespace util {
+
+    template <class Container>
+    struct container_traits {
+        typedef typename Container::iterator iterator;
+        typedef typename std::iterator_traits<iterator>::value_type value_type;
+        typedef typename std::iterator_traits<iterator>::iterator_category iterator_category;
+
+        // TODO: conservative definition for now. 
+        enum { is_writable_iterator = 
+                   std::is_reference<typename std::iterator_traits<iterator>::reference>::value
+                   && std::is_same<typename std::remove_cv<value_type>::type,
+                                   typename std::remove_cv<typename std::remove_reference<typename std::iterator_traits<iterator>::reference>::type>::type>::value
+        };
+    };
+
+    template <>
+    struct container_traits<int>;
+
+    template <class Container>
+    struct container_traits<Container&>
+        : container_traits<Container>
+    {};
+    template <class Container>
+    struct container_traits<const Container>
+        : container_traits<Container>
+    {
+        typedef typename Container::const_iterator iterator;
+    };
+
+    // Note: returns false if no partial order exists between two 
+    // particular iterator categories, such as with some of the boost categories
+    template <class Cat1, class Cat2>
+    struct less_or_equal_iterator_category
+    {
+    private:
+        typedef char yes;
+        typedef struct { char c1,c2; } no;
+        static yes invoke(Cat1);
+        static no invoke(...);
+    public:
+        enum { value = (sizeof(invoke(Cat2())) == sizeof(yes)) };
+    };
+
+    // Return the weaker of the two iterator categories. Make sure 
+    //   a non-standard category is in the second argument position, as 
+    //   this metafunction will default to the first value if the order is undefined
+    template <class Cat1, class Cat2>
+    struct min_iterator_category
+        : std::conditional<
+            less_or_equal_iterator_category<Cat2, Cat1>::value,
+            Cat2,
+            Cat1>
+    {
+    };
+
+#if 0
+#define CppLinq_GET_ITERATOR_TYPE(TContainer) \
+    decltype(begin(static_cast<TContainer*>(0)))
+#define CppLinq_GET_CONST_ITERATOR_TYPE(TContainer) \
+    decltype(begin(static_cast<const TContainer*>(0)))
+#else
+#define CppLinq_GET_ITERATOR_TYPE(TContainer) \
+    typename ::cpplinq::util::container_traits<TContainer>::iterator
+#define CppLinq_GET_CONST_ITERATOR_TYPE(TContainer) \
+    typename ::cpplinq::util::container_traits<TContainer>::const_iterator
+#endif
+
+    // VC10's std::tr1::result_of is busted with lambdas. use decltype instead on vc10 and later
+#if defined(_MSC_VER) && _MSC_VER >= 1600
+    namespace detail {
+        template <class T> T instance();
+    };
+    template <class Fn> struct result_of;
+    template <class Fn>
+    struct result_of<Fn()> {
+        typedef decltype(detail::instance<Fn>()()) type;
+    };
+    template <class Fn, class A0>
+    struct result_of<Fn(A0)> {
+        typedef decltype(detail::instance<Fn>()(detail::instance<A0>())) type;
+    };
+    template <class Fn, class A0, class A1>
+    struct result_of<Fn(A0,A1)> {
+        typedef decltype(detail::instance<Fn>()(detail::instance<A0>(),
+                                                detail::instance<A1>())) type;
+    };
+    template <class Fn, class A0, class A1, class A2>
+    struct result_of<Fn(A0,A1,A2)> {
+        typedef decltype(detail::instance<Fn>()(detail::instance<A0>(),
+                                                detail::instance<A1>(),
+                                                detail::instance<A2>())) type;
+    };
+    template <class Fn, class A0, class A1, class A2, class A3>
+    struct result_of<Fn(A0,A1,A2,A3)> {
+        typedef decltype(detail::instance<Fn>()(detail::instance<A0>(),
+                                                detail::instance<A1>(),
+                                                detail::instance<A2>(),
+                                                detail::instance<A3>())) type;
+    };
+#elif defined(_MSC_VER)
+    template <class T>
+    struct result_of<T> : std::tr1::result_of<T> {};
+#else
+    using std::result_of;
+#endif
+
+    template<class Type>
+    struct identity 
+    {
+        typedef Type type;
+        Type operator()(const Type& left) const {return left;}
+    };
+
+    // faux pointer proxy for iterators that dereference to a value rather than reference, such as selectors
+    template <class T>
+    struct value_ptr
+    {
+        T value;
+        value_ptr(const T& value) : value(value)
+        {}
+        value_ptr(const T* pvalue) : value(*pvalue)
+        {}
+        const T* operator->()
+        {
+            return &value;
+        }
+    };
+     
+
+    template <class T>
+    class maybe
+    {
+        bool is_set;
+        typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type 
+            storage;
+    public:
+        maybe()
+        : is_set(false)
+        {
+        }
+
+        maybe(T value)
+        : is_set(false)
+        {
+            new (reinterpret_cast<T*>(&storage)) T(value);
+            is_set = true;
+        }
+
+        maybe(const maybe& other)
+        : is_set(false)
+        {
+            if (other.is_set) {
+                new (reinterpret_cast<T*>(&storage)) T(*other.get());
+                is_set = true;
+            }
+        }
+        maybe(maybe&& other)
+        : is_set(false)
+        {
+            if (other.is_set) {
+                new (reinterpret_cast<T*>(&storage)) T(std::move(*other.get()));
+                is_set = true;
+                other.reset();
+            }
+        }
+
+        ~maybe()
+        {
+            reset();
+        }
+
+        void reset()
+        {
+            if (is_set) {
+                is_set = false;
+                reinterpret_cast<T*>(&storage)->~T();
+            }
+        }
+
+        T* get() {
+            return is_set ? reinterpret_cast<T*>(&storage) : 0;
+        }
+
+        const T* get() const {
+            return is_set ? reinterpret_cast<const T*>(&storage) : 0;
+        }
+
+        void set(T value) {
+            if (is_set) {
+                *reinterpret_cast<T*>(&storage) = std::move(value);
+            } else {
+                new (reinterpret_cast<T*>(&storage)) T(std::move(value));
+                is_set = true;
+            }
+        }
+
+        T& operator*() { return *get(); }
+        const T& operator*() const { return *get(); }
+        T* operator->() { return get(); }
+        const T* operator->() const { return get(); }
+
+        maybe& operator=(const T& other) {
+            set(other);
+        }
+        maybe& operator=(const maybe& other) {
+            if (const T* pother = other.get()) {
+                set(*pother);
+            } else {
+                reset();
+            }
+            return *this;
+        }
+
+        // boolean-like operators
+        operator T*() { return get(); }
+        operator const T*() const { return get(); }
+
+    private:
+        
+    };
+}}
+
+
+#endif //CPPLINQ_UTIL_HPP
+
diff --git a/dependencies64/RxCpp/include/rxcpp/operators/rx-buffer_count.hpp b/dependencies64/RxCpp/include/rxcpp/operators/rx-buffer_count.hpp
new file mode 100644 (file)
index 0000000..e3a2970
--- /dev/null
@@ -0,0 +1,128 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_OPERATORS_RX_BUFFER_COUNT_HPP)
+#define RXCPP_OPERATORS_RX_BUFFER_COUNT_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace operators {
+
+namespace detail {
+
+
+template<class T>
+struct buffer_count
+{
+    typedef typename std::decay<T>::type source_value_type;
+    struct buffer_count_values
+    {
+        buffer_count_values(int c, int s)
+            : count(c)
+            , skip(s)
+        {
+        }
+        int count;
+        int skip;
+    };
+
+    buffer_count_values initial;
+
+    buffer_count(int count, int skip)
+        : initial(count, skip)
+    {
+    }
+
+    template<class Subscriber>
+    struct buffer_count_observer : public buffer_count_values
+    {
+        typedef buffer_count_observer<Subscriber> this_type;
+        typedef std::vector<T> value_type;
+        typedef typename std::decay<Subscriber>::type dest_type;
+        typedef observer<value_type, this_type> observer_type;
+        dest_type dest;
+        mutable int cursor;
+        mutable std::deque<value_type> chunks;
+
+        buffer_count_observer(dest_type d, buffer_count_values v)
+            : buffer_count_values(v)
+            , dest(std::move(d))
+            , cursor(0)
+        {
+        }
+        void on_next(T v) const {
+            if (cursor++ % this->skip == 0) {
+                chunks.emplace_back();
+            }
+            for(auto& chunk : chunks) {
+                chunk.push_back(v);
+            }
+            while (!chunks.empty() && chunks.front().size() == this->count) {
+                dest.on_next(std::move(chunks.front()));
+                chunks.pop_front();
+            }
+        }
+        void on_error(std::exception_ptr e) const {
+            dest.on_error(e);
+        }
+        void on_completed() const {
+            auto done = on_exception(
+                [&](){
+                    while (!chunks.empty()) {
+                        dest.on_next(std::move(chunks.front()));
+                        chunks.pop_front();
+                    }
+                    return true;
+                },
+                dest);
+            if (done.empty()) {
+                return;
+            }
+            dest.on_completed();
+        }
+
+        static subscriber<T, observer<T, this_type>> make(dest_type d, buffer_count_values v) {
+            auto cs = d.get_subscription();
+            return make_subscriber<T>(std::move(cs), this_type(std::move(d), std::move(v)));
+        }
+    };
+
+    template<class Subscriber>
+    auto operator()(Subscriber dest) const
+        -> decltype(buffer_count_observer<Subscriber>::make(std::move(dest), initial)) {
+        return      buffer_count_observer<Subscriber>::make(std::move(dest), initial);
+    }
+};
+
+class buffer_count_factory
+{
+    int count;
+    int skip;
+public:
+    buffer_count_factory(int c, int s) : count(c), skip(s) {}
+    template<class Observable>
+    auto operator()(Observable&& source)
+        -> decltype(source.template lift<std::vector<typename std::decay<Observable>::type::value_type>>(buffer_count<typename std::decay<Observable>::type::value_type>(count, skip))) {
+        return      source.template lift<std::vector<typename std::decay<Observable>::type::value_type>>(buffer_count<typename std::decay<Observable>::type::value_type>(count, skip));
+    }
+};
+
+}
+
+inline auto buffer(int count)
+    ->      detail::buffer_count_factory {
+    return  detail::buffer_count_factory(count, count);
+}
+inline auto buffer(int count, int skip)
+    ->      detail::buffer_count_factory {
+    return  detail::buffer_count_factory(count, skip);
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/operators/rx-combine_latest.hpp b/dependencies64/RxCpp/include/rxcpp/operators/rx-combine_latest.hpp
new file mode 100644 (file)
index 0000000..9a0b057
--- /dev/null
@@ -0,0 +1,223 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_OPERATORS_RX_COMBINE_LATEST_HPP)
+#define RXCPP_OPERATORS_RX_COMBINE_LATEST_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace operators {
+
+namespace detail {
+
+template<class Coordination, class Selector, class... ObservableN>
+struct combine_latest_traits {
+    static_assert(rxu::all_true<is_observable<ObservableN>::value...>::value, "combine_latest requires observables");
+
+    typedef std::tuple<ObservableN...> tuple_source_type;
+    typedef std::tuple<rxu::detail::maybe<typename ObservableN::value_type>...> tuple_source_value_type;
+
+    typedef typename std::decay<Selector>::type selector_type;
+    typedef typename std::decay<Coordination>::type coordination_type;
+
+    struct tag_not_valid {};
+    template<class CS, class... CVN>
+    static auto check(int) -> decltype((*(CS*)nullptr)((*(CVN*)nullptr)...));
+    template<class CS, class... CVN>
+    static tag_not_valid check(...);
+
+    static_assert(!std::is_same<decltype(check<selector_type, typename ObservableN::value_type...>(0)), tag_not_valid>::value, "combine_latest Selector must be a function with the signature value_type(Observable::value_type...)");
+
+    typedef decltype(check<selector_type, typename ObservableN::value_type...>(0)) value_type;
+};
+
+template<class Coordination, class Selector, class... ObservableN>
+struct combine_latest : public operator_base<typename combine_latest_traits<Coordination, Selector, ObservableN...>::value_type>
+{
+    typedef combine_latest<Coordination, Selector, ObservableN...> this_type;
+
+    typedef combine_latest_traits<Coordination, Selector, ObservableN...> traits;
+
+    typedef typename traits::tuple_source_type tuple_source_type;
+    typedef typename traits::tuple_source_value_type tuple_source_value_type;
+
+    typedef typename traits::selector_type selector_type;
+
+    typedef typename traits::coordination_type coordination_type;
+    typedef typename coordination_type::coordinator_type coordinator_type;
+
+    struct values
+    {
+        values(tuple_source_type o, selector_type s, coordination_type sf)
+            : source(std::move(o))
+            , selector(std::move(s))
+            , coordination(std::move(sf))
+        {
+        }
+        tuple_source_type source;
+        selector_type selector;
+        coordination_type coordination;
+    };
+    values initial;
+
+    combine_latest(coordination_type sf, selector_type s, tuple_source_type ts)
+        : initial(std::move(ts), std::move(s), std::move(sf))
+    {
+    }
+
+    template<int Index, class State>
+    void subscribe_one(std::shared_ptr<State> state) const {
+
+        typedef typename std::tuple_element<Index, tuple_source_type>::type::value_type source_value_type;
+
+        composite_subscription innercs;
+
+        // when the out observer is unsubscribed all the
+        // inner subscriptions are unsubscribed as well
+        state->out.add(innercs);
+
+        auto source = on_exception(
+            [&](){return state->coordinator.in(std::get<Index>(state->source));},
+            state->out);
+        if (source.empty()) {
+            return;
+        }
+
+        // this subscribe does not share the observer subscription
+        // so that when it is unsubscribed the observer can be called
+        // until the inner subscriptions have finished
+        auto sink = make_subscriber<source_value_type>(
+            state->out,
+            innercs,
+        // on_next
+            [state](source_value_type st) {
+
+                auto& value = std::get<Index>(state->latest);
+
+                if (value.empty()) {
+                    ++state->valuesSet;
+                }
+
+                value.reset(st);
+
+                if (state->valuesSet == sizeof... (ObservableN)) {
+                    auto selectedResult = on_exception(
+                        [&](){
+                            return rxu::apply(rxu::surely(state->latest), state->selector);
+                        },
+                        state->out);
+                    if (selectedResult.empty()) {
+                        return;
+                    }
+                    state->out.on_next(selectedResult.get());
+                }
+            },
+        // on_error
+            [state](std::exception_ptr e) {
+                state->out.on_error(e);
+            },
+        // on_completed
+            [state]() {
+                if (--state->pendingCompletions == 0) {
+                    state->out.on_completed();
+                }
+            }
+        );
+        auto selectedSink = on_exception(
+            [&](){return state->coordinator.out(sink);},
+            state->out);
+        if (selectedSink.empty()) {
+            return;
+        }
+        source->subscribe(std::move(selectedSink.get()));
+    }
+    template<class State, int... IndexN>
+    void subscribe_all(std::shared_ptr<State> state, rxu::values<int, IndexN...>) const {
+        bool subscribed[] = {(subscribe_one<IndexN>(state), true)...};
+    }
+
+    template<class Subscriber>
+    void on_subscribe(Subscriber scbr) const {
+        static_assert(is_subscriber<Subscriber>::value, "subscribe must be passed a subscriber");
+
+        typedef Subscriber output_type;
+
+        struct combine_latest_state_type
+            : public std::enable_shared_from_this<combine_latest_state_type>
+            , public values
+        {
+            combine_latest_state_type(values i, coordinator_type coor, output_type oarg)
+                : values(std::move(i))
+                , pendingCompletions(sizeof... (ObservableN))
+                , valuesSet(0)
+                , coordinator(std::move(coor))
+                , out(std::move(oarg))
+            {
+            }
+
+            // on_completed on the output must wait until all the
+            // subscriptions have received on_completed
+            mutable int pendingCompletions;
+            mutable int valuesSet;
+            mutable tuple_source_value_type latest;
+            coordinator_type coordinator;
+            output_type out;
+        };
+
+        auto coordinator = initial.coordination.create_coordinator(scbr.get_subscription());
+
+        // take a copy of the values for each subscription
+        auto state = std::shared_ptr<combine_latest_state_type>(new combine_latest_state_type(initial, std::move(coordinator), std::move(scbr)));
+
+        subscribe_all(state, typename rxu::values_from<int, sizeof...(ObservableN)>::type());
+    }
+};
+
+template<class Coordination, class Selector, class... ObservableN>
+class combine_latest_factory
+{
+    typedef typename std::decay<Coordination>::type coordination_type;
+    typedef typename std::decay<Selector>::type selector_type;
+    typedef std::tuple<ObservableN...> tuple_source_type;
+
+    coordination_type coordination;
+    selector_type selector;
+    tuple_source_type sourcen;
+
+    template<class... YObservableN>
+    auto make(std::tuple<YObservableN...> source)
+        ->      observable<typename combine_latest<Coordination, Selector, YObservableN...>::value_type, combine_latest<Coordination, Selector, YObservableN...>> {
+        return  observable<typename combine_latest<Coordination, Selector, YObservableN...>::value_type, combine_latest<Coordination, Selector, YObservableN...>>(
+                                    combine_latest<Coordination, Selector, YObservableN...>(coordination, selector, std::move(source)));
+    }
+public:
+    combine_latest_factory(coordination_type sf, selector_type s, ObservableN... on)
+        : coordination(std::move(sf))
+        , selector(std::move(s))
+        , sourcen(std::make_tuple(std::move(on)...))
+    {
+    }
+
+    template<class Observable>
+    auto operator()(Observable source)
+        -> decltype(make(std::tuple_cat(std::make_tuple(source), *(tuple_source_type*)nullptr))) {
+        return      make(std::tuple_cat(std::make_tuple(source), sourcen));
+    }
+};
+
+}
+
+template<class Coordination, class Selector, class... ObservableN>
+auto combine_latest(Coordination sf, Selector s, ObservableN... on)
+    ->      detail::combine_latest_factory<Coordination, Selector, ObservableN...> {
+    return  detail::combine_latest_factory<Coordination, Selector, ObservableN...>(std::move(sf), std::move(s), std::move(on)...);
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/operators/rx-concat.hpp b/dependencies64/RxCpp/include/rxcpp/operators/rx-concat.hpp
new file mode 100644 (file)
index 0000000..2afe974
--- /dev/null
@@ -0,0 +1,216 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_OPERATORS_RX_CONCAT_HPP)
+#define RXCPP_OPERATORS_RX_CONCAT_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace operators {
+
+namespace detail {
+
+template<class T, class Observable, class Coordination>
+struct concat
+    : public operator_base<typename std::decay<T>::type::value_type>
+{
+    typedef concat<T, Observable, Coordination> this_type;
+
+    typedef typename std::decay<T>::type source_value_type;
+    typedef typename std::decay<Observable>::type source_type;
+    typedef typename std::decay<Coordination>::type coordination_type;
+
+    typedef typename coordination_type::coordinator_type coordinator_type;
+
+    typedef typename source_type::source_operator_type source_operator_type;
+    typedef source_value_type collection_type;
+    typedef typename collection_type::value_type value_type;
+
+    struct values
+    {
+        values(source_operator_type o, coordination_type sf)
+            : source_operator(std::move(o))
+            , coordination(std::move(sf))
+        {
+        }
+        source_operator_type source_operator;
+        coordination_type coordination;
+    };
+    values initial;
+
+    concat(const source_type& o, coordination_type sf)
+        : initial(o.source_operator, std::move(sf))
+    {
+    }
+
+    template<class Subscriber>
+    void on_subscribe(Subscriber scbr) const {
+        static_assert(is_subscriber<Subscriber>::value, "subscribe must be passed a subscriber");
+
+        typedef Subscriber output_type;
+
+        struct concat_state_type
+            : public std::enable_shared_from_this<concat_state_type>
+            , public values
+        {
+            concat_state_type(values i, coordinator_type coor, output_type oarg)
+                : values(i)
+                , source(i.source_operator)
+                , sourceLifetime(composite_subscription::empty())
+                , collectionLifetime(composite_subscription::empty())
+                , coordinator(std::move(coor))
+                , out(std::move(oarg))
+            {
+            }
+
+            void subscribe_to(collection_type st)
+            {
+                auto state = this->shared_from_this();
+
+                collectionLifetime = composite_subscription();
+
+                // when the out observer is unsubscribed all the
+                // inner subscriptions are unsubscribed as well
+                auto innercstoken = state->out.add(collectionLifetime);
+
+                collectionLifetime.add(make_subscription([state, innercstoken](){
+                    state->out.remove(innercstoken);
+                }));
+
+                auto selectedSource = on_exception(
+                    [&](){return state->coordinator.in(std::move(st));},
+                    state->out);
+                if (selectedSource.empty()) {
+                    return;
+                }
+
+                // this subscribe does not share the out subscription
+                // so that when it is unsubscribed the out will continue
+                auto sinkInner = make_subscriber<value_type>(
+                    state->out,
+                    collectionLifetime,
+                // on_next
+                    [state, st](value_type ct) {
+                        state->out.on_next(ct);
+                    },
+                // on_error
+                    [state](std::exception_ptr e) {
+                        state->out.on_error(e);
+                    },
+                //on_completed
+                    [state](){
+                        if (!state->selectedCollections.empty()) {
+                            auto value = state->selectedCollections.front();
+                            state->selectedCollections.pop_front();
+                            state->collectionLifetime.unsubscribe();
+                            state->subscribe_to(value);
+                        } else if (!state->sourceLifetime.is_subscribed()) {
+                            state->out.on_completed();
+                        }
+                    }
+                );
+                auto selectedSinkInner = on_exception(
+                    [&](){return state->coordinator.out(sinkInner);},
+                    state->out);
+                if (selectedSinkInner.empty()) {
+                    return;
+                }
+                selectedSource->subscribe(std::move(selectedSinkInner.get()));
+            }
+            observable<source_value_type, source_operator_type> source;
+            composite_subscription sourceLifetime;
+            composite_subscription collectionLifetime;
+            std::deque<collection_type> selectedCollections;
+            coordinator_type coordinator;
+            output_type out;
+        };
+
+        auto coordinator = initial.coordination.create_coordinator(scbr.get_subscription());
+
+        // take a copy of the values for each subscription
+        auto state = std::shared_ptr<concat_state_type>(new concat_state_type(initial, std::move(coordinator), std::move(scbr)));
+
+        state->sourceLifetime = composite_subscription();
+
+        // when the out observer is unsubscribed all the
+        // inner subscriptions are unsubscribed as well
+        state->out.add(state->sourceLifetime);
+
+        auto source = on_exception(
+            [&](){return state->coordinator.in(state->source);},
+            state->out);
+        if (source.empty()) {
+            return;
+        }
+
+        // this subscribe does not share the observer subscription
+        // so that when it is unsubscribed the observer can be called
+        // until the inner subscriptions have finished
+        auto sink = make_subscriber<collection_type>(
+            state->out,
+            state->sourceLifetime,
+        // on_next
+            [state](collection_type st) {
+                if (state->collectionLifetime.is_subscribed()) {
+                    state->selectedCollections.push_back(st);
+                } else if (state->selectedCollections.empty()) {
+                    state->subscribe_to(st);
+                }
+            },
+        // on_error
+            [state](std::exception_ptr e) {
+                state->out.on_error(e);
+            },
+        // on_completed
+            [state]() {
+                if (!state->collectionLifetime.is_subscribed() && state->selectedCollections.empty()) {
+                    state->out.on_completed();
+                }
+            }
+        );
+        auto selectedSink = on_exception(
+            [&](){return state->coordinator.out(sink);},
+            state->out);
+        if (selectedSink.empty()) {
+            return;
+        }
+        source->subscribe(std::move(selectedSink.get()));
+    }
+};
+
+template<class Coordination>
+class concat_factory
+{
+    typedef typename std::decay<Coordination>::type coordination_type;
+
+    coordination_type coordination;
+public:
+    concat_factory(coordination_type sf)
+        : coordination(std::move(sf))
+    {
+    }
+
+    template<class Observable>
+    auto operator()(Observable source)
+        ->      observable<typename concat<typename Observable::value_type, Observable, Coordination>::value_type,  concat<typename Observable::value_type, Observable, Coordination>> {
+        return  observable<typename concat<typename Observable::value_type, Observable, Coordination>::value_type,  concat<typename Observable::value_type, Observable, Coordination>>(
+                                                                                                                    concat<typename Observable::value_type, Observable, Coordination>(std::move(source), coordination));
+    }
+};
+
+}
+
+template<class Coordination>
+auto concat(Coordination&& sf)
+    ->      detail::concat_factory<Coordination> {
+    return  detail::concat_factory<Coordination>(std::forward<Coordination>(sf));
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/operators/rx-concat_map.hpp b/dependencies64/RxCpp/include/rxcpp/operators/rx-concat_map.hpp
new file mode 100644 (file)
index 0000000..98cec31
--- /dev/null
@@ -0,0 +1,275 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_OPERATORS_RX_CONCATMAP_HPP)
+#define RXCPP_OPERATORS_RX_CONCATMAP_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace operators {
+
+namespace detail {
+
+template<class Observable, class CollectionSelector, class ResultSelector, class Coordination>
+struct concat_traits {
+    typedef typename std::decay<Observable>::type source_type;
+    typedef typename std::decay<CollectionSelector>::type collection_selector_type;
+    typedef typename std::decay<ResultSelector>::type result_selector_type;
+    typedef typename std::decay<Coordination>::type coordination_type;
+
+    typedef typename source_type::value_type source_value_type;
+
+    struct tag_not_valid {};
+    template<class CV, class CCS>
+    static auto collection_check(int) -> decltype((*(CCS*)nullptr)(*(CV*)nullptr));
+    template<class CV, class CCS>
+    static tag_not_valid collection_check(...);
+
+    static_assert(!std::is_same<decltype(collection_check<source_value_type, collection_selector_type>(0)), tag_not_valid>::value, "concat_map CollectionSelector must be a function with the signature observable(concat_map::source_value_type)");
+
+    typedef decltype((*(collection_selector_type*)nullptr)((*(source_value_type*)nullptr))) collection_type;
+
+//#if _MSC_VER >= 1900
+    static_assert(is_observable<collection_type>::value, "concat_map CollectionSelector must return an observable");
+//#endif
+
+    typedef typename collection_type::value_type collection_value_type;
+
+    template<class CV, class CCV, class CRS>
+    static auto result_check(int) -> decltype((*(CRS*)nullptr)(*(CV*)nullptr, *(CCV*)nullptr));
+    template<class CV, class CCV, class CRS>
+    static tag_not_valid result_check(...);
+
+    static_assert(!std::is_same<decltype(result_check<source_value_type, collection_value_type, result_selector_type>(0)), tag_not_valid>::value, "concat_map ResultSelector must be a function with the signature concat_map::value_type(concat_map::source_value_type, concat_map::collection_value_type)");
+
+    typedef decltype((*(result_selector_type*)nullptr)(*(source_value_type*)nullptr, *(collection_value_type*)nullptr)) value_type;
+};
+
+template<class Observable, class CollectionSelector, class ResultSelector, class Coordination>
+struct concat_map
+    : public operator_base<typename concat_traits<Observable, CollectionSelector, ResultSelector, Coordination>::value_type>
+{
+    typedef concat_map<Observable, CollectionSelector, ResultSelector, Coordination> this_type;
+    typedef concat_traits<Observable, CollectionSelector, ResultSelector, Coordination> traits;
+
+    typedef typename traits::source_type source_type;
+    typedef typename traits::collection_selector_type collection_selector_type;
+    typedef typename traits::result_selector_type result_selector_type;
+
+    typedef typename traits::source_value_type source_value_type;
+    typedef typename traits::collection_type collection_type;
+    typedef typename traits::collection_value_type collection_value_type;
+
+    typedef typename traits::coordination_type coordination_type;
+    typedef typename coordination_type::coordinator_type coordinator_type;
+
+    struct values
+    {
+        values(source_type o, collection_selector_type s, result_selector_type rs, coordination_type sf)
+            : source(std::move(o))
+            , selectCollection(std::move(s))
+            , selectResult(std::move(rs))
+            , coordination(std::move(sf))
+        {
+        }
+        source_type source;
+        collection_selector_type selectCollection;
+        result_selector_type selectResult;
+        coordination_type coordination;
+    };
+    values initial;
+
+    concat_map(source_type o, collection_selector_type s, result_selector_type rs, coordination_type sf)
+        : initial(std::move(o), std::move(s), std::move(rs), std::move(sf))
+    {
+    }
+
+    template<class Subscriber>
+    void on_subscribe(Subscriber scbr) const {
+        static_assert(is_subscriber<Subscriber>::value, "subscribe must be passed a subscriber");
+
+        typedef Subscriber output_type;
+
+        struct concat_map_state_type
+            : public std::enable_shared_from_this<concat_map_state_type>
+            , public values
+        {
+            concat_map_state_type(values i, coordinator_type coor, output_type oarg)
+                : values(std::move(i))
+                , sourceLifetime(composite_subscription::empty())
+                , collectionLifetime(composite_subscription::empty())
+                , coordinator(std::move(coor))
+                , out(std::move(oarg))
+            {
+            }
+
+            void subscribe_to(source_value_type st)
+            {
+                auto state = this->shared_from_this();
+
+                auto selectedCollection = on_exception(
+                    [&](){return state->selectCollection(st);},
+                    state->out);
+                if (selectedCollection.empty()) {
+                    return;
+                }
+
+                collectionLifetime = composite_subscription();
+
+                // when the out observer is unsubscribed all the
+                // inner subscriptions are unsubscribed as well
+                auto innercstoken = state->out.add(collectionLifetime);
+
+                collectionLifetime.add(make_subscription([state, innercstoken](){
+                    state->out.remove(innercstoken);
+                }));
+
+                auto selectedSource = on_exception(
+                    [&](){return state->coordinator.in(selectedCollection.get());},
+                    state->out);
+                if (selectedSource.empty()) {
+                    return;
+                }
+
+                // this subscribe does not share the source subscription
+                // so that when it is unsubscribed the source will continue
+                auto sinkInner = make_subscriber<collection_value_type>(
+                    state->out,
+                    collectionLifetime,
+                // on_next
+                    [state, st](collection_value_type ct) {
+                        auto selectedResult = on_exception(
+                            [&](){return state->selectResult(st, std::move(ct));},
+                            state->out);
+                        if (selectedResult.empty()) {
+                            return;
+                        }
+                        state->out.on_next(std::move(*selectedResult));
+                    },
+                // on_error
+                    [state](std::exception_ptr e) {
+                        state->out.on_error(e);
+                    },
+                //on_completed
+                    [state](){
+                        if (!state->selectedCollections.empty()) {
+                            auto value = state->selectedCollections.front();
+                            state->selectedCollections.pop_front();
+                            state->collectionLifetime.unsubscribe();
+                            state->subscribe_to(value);
+                        } else if (!state->sourceLifetime.is_subscribed()) {
+                            state->out.on_completed();
+                        }
+                    }
+                );
+                auto selectedSinkInner = on_exception(
+                    [&](){return state->coordinator.out(sinkInner);},
+                    state->out);
+                if (selectedSinkInner.empty()) {
+                    return;
+                }
+                selectedSource->subscribe(std::move(selectedSinkInner.get()));
+            }
+            composite_subscription sourceLifetime;
+            composite_subscription collectionLifetime;
+            std::deque<source_value_type> selectedCollections;
+            coordinator_type coordinator;
+            output_type out;
+        };
+
+        auto coordinator = initial.coordination.create_coordinator(scbr.get_subscription());
+
+        // take a copy of the values for each subscription
+        auto state = std::shared_ptr<concat_map_state_type>(new concat_map_state_type(initial, std::move(coordinator), std::move(scbr)));
+
+        state->sourceLifetime = composite_subscription();
+
+        // when the out observer is unsubscribed all the
+        // inner subscriptions are unsubscribed as well
+        state->out.add(state->sourceLifetime);
+
+        auto source = on_exception(
+            [&](){return state->coordinator.in(state->source);},
+            state->out);
+        if (source.empty()) {
+            return;
+        }
+
+        // this subscribe does not share the observer subscription
+        // so that when it is unsubscribed the observer can be called
+        // until the inner subscriptions have finished
+        auto sink = make_subscriber<source_value_type>(
+            state->out,
+            state->sourceLifetime,
+        // on_next
+            [state](source_value_type st) {
+                if (state->collectionLifetime.is_subscribed()) {
+                    state->selectedCollections.push_back(st);
+                } else if (state->selectedCollections.empty()) {
+                    state->subscribe_to(st);
+                }
+            },
+        // on_error
+            [state](std::exception_ptr e) {
+                state->out.on_error(e);
+            },
+        // on_completed
+            [state]() {
+                if (!state->collectionLifetime.is_subscribed() && state->selectedCollections.empty()) {
+                    state->out.on_completed();
+                }
+            }
+        );
+        auto selectedSink = on_exception(
+            [&](){return state->coordinator.out(sink);},
+            state->out);
+        if (selectedSink.empty()) {
+            return;
+        }
+        source->subscribe(std::move(selectedSink.get()));
+
+    }
+};
+
+template<class CollectionSelector, class ResultSelector, class Coordination>
+class concat_map_factory
+{
+    typedef typename std::decay<CollectionSelector>::type collection_selector_type;
+    typedef typename std::decay<ResultSelector>::type result_selector_type;
+    typedef typename std::decay<Coordination>::type coordination_type;
+
+    collection_selector_type selectorCollection;
+    result_selector_type selectorResult;
+    coordination_type coordination;
+public:
+    concat_map_factory(collection_selector_type s, result_selector_type rs, coordination_type sf)
+        : selectorCollection(std::move(rs))
+        , selectorResult(std::move(s))
+        , coordination(std::move(sf))
+    {
+    }
+
+    template<class Observable>
+    auto operator()(Observable&& source)
+        ->      observable<typename concat_map<Observable, CollectionSelector, ResultSelector, Coordination>::value_type, concat_map<Observable, CollectionSelector, ResultSelector, Coordination>> {
+        return  observable<typename concat_map<Observable, CollectionSelector, ResultSelector, Coordination>::value_type, concat_map<Observable, CollectionSelector, ResultSelector, Coordination>>(
+                                    concat_map<Observable, CollectionSelector, ResultSelector, Coordination>(std::forward<Observable>(source), selectorCollection, selectorResult, coordination));
+    }
+};
+
+}
+
+template<class CollectionSelector, class ResultSelector, class Coordination>
+auto concat_map(CollectionSelector&& s, ResultSelector&& rs, Coordination&& sf)
+    ->      detail::concat_map_factory<CollectionSelector, ResultSelector, Coordination> {
+    return  detail::concat_map_factory<CollectionSelector, ResultSelector, Coordination>(std::forward<CollectionSelector>(s), std::forward<ResultSelector>(rs), std::forward<Coordination>(sf));
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/operators/rx-connect_forever.hpp b/dependencies64/RxCpp/include/rxcpp/operators/rx-connect_forever.hpp
new file mode 100644 (file)
index 0000000..b38aa08
--- /dev/null
@@ -0,0 +1,58 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_OPERATORS_RX_CONNECT_FOREVER_HPP)
+#define RXCPP_OPERATORS_RX_CONNECT_FOREVER_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace operators {
+
+namespace detail {
+
+template<class T, class ConnectableObservable>
+struct connect_forever : public operator_base<T>
+{
+    typedef typename std::decay<ConnectableObservable>::type source_type;
+
+    source_type source;
+
+    explicit connect_forever(source_type o)
+        : source(std::move(o))
+    {
+        source.connect();
+    }
+
+    template<class Subscriber>
+    void on_subscribe(Subscriber&& o) const {
+        source.subscribe(std::forward<Subscriber>(o));
+    }
+};
+
+class connect_forever_factory
+{
+public:
+    connect_forever_factory() {}
+    template<class Observable>
+    auto operator()(Observable&& source)
+        ->      observable<typename std::decay<Observable>::type::value_type,   connect_forever<typename std::decay<Observable>::type::value_type, Observable>> {
+        return  observable<typename std::decay<Observable>::type::value_type,   connect_forever<typename std::decay<Observable>::type::value_type, Observable>>(
+                                                                                connect_forever<typename std::decay<Observable>::type::value_type, Observable>(std::forward<Observable>(source)));
+    }
+};
+
+}
+
+inline auto connect_forever()
+    ->      detail::connect_forever_factory {
+    return  detail::connect_forever_factory();
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/operators/rx-distinct_until_changed.hpp b/dependencies64/RxCpp/include/rxcpp/operators/rx-distinct_until_changed.hpp
new file mode 100644 (file)
index 0000000..910edda
--- /dev/null
@@ -0,0 +1,81 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_OPERATORS_RX_DISTINCT_UNTIL_CHANGED_HPP)
+#define RXCPP_OPERATORS_RX_DISTINCT_UNTIL_CHANGED_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace operators {
+
+namespace detail {
+
+template<class T>
+struct distinct_until_changed
+{
+    typedef typename std::decay<T>::type source_value_type;
+
+    template<class Subscriber>
+    struct distinct_until_changed_observer
+    {
+        typedef distinct_until_changed_observer<Subscriber> this_type;
+        typedef source_value_type value_type;
+        typedef typename std::decay<Subscriber>::type dest_type;
+        typedef observer<value_type, this_type> observer_type;
+        dest_type dest;
+        mutable rxu::detail::maybe<source_value_type> remembered;
+
+        distinct_until_changed_observer(dest_type d)
+            : dest(d)
+        {
+        }
+        void on_next(source_value_type v) const {
+            if (remembered.empty() || v != remembered.get()) {
+                remembered.reset(v);
+                dest.on_next(v);
+            }
+        }
+        void on_error(std::exception_ptr e) const {
+            dest.on_error(e);
+        }
+        void on_completed() const {
+            dest.on_completed();
+        }
+
+        static subscriber<value_type, observer<value_type, this_type>> make(dest_type d) {
+            return make_subscriber<value_type>(d, this_type(d));
+        }
+    };
+
+    template<class Subscriber>
+    auto operator()(Subscriber dest) const
+        -> decltype(distinct_until_changed_observer<Subscriber>::make(std::move(dest))) {
+        return      distinct_until_changed_observer<Subscriber>::make(std::move(dest));
+    }
+};
+
+class distinct_until_changed_factory
+{
+public:
+    template<class Observable>
+    auto operator()(Observable&& source)
+        -> decltype(source.template lift<typename std::decay<Observable>::type::value_type>(distinct_until_changed<typename std::decay<Observable>::type>::value_type)) {
+        return      source.template lift<typename std::decay<Observable>::type::value_type>(distinct_until_changed<typename std::decay<Observable>::type>::value_type);
+    }
+};
+
+}
+
+inline auto distinct_until_changed()
+    ->      detail::distinct_until_changed_factory {
+    return  detail::distinct_until_changed_factory();
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/operators/rx-filter.hpp b/dependencies64/RxCpp/include/rxcpp/operators/rx-filter.hpp
new file mode 100644 (file)
index 0000000..775bc16
--- /dev/null
@@ -0,0 +1,99 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_OPERATORS_RX_FILTER_HPP)
+#define RXCPP_OPERATORS_RX_FILTER_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace operators {
+
+namespace detail {
+
+template<class T, class Predicate>
+struct filter
+{
+    typedef typename std::decay<T>::type source_value_type;
+    typedef typename std::decay<Predicate>::type test_type;
+    test_type test;
+
+    filter(test_type t)
+        : test(std::move(t))
+    {
+    }
+
+    template<class Subscriber>
+    struct filter_observer
+    {
+        typedef filter_observer<Subscriber> this_type;
+        typedef source_value_type value_type;
+        typedef typename std::decay<Subscriber>::type dest_type;
+        typedef observer<value_type, this_type> observer_type;
+        dest_type dest;
+        test_type test;
+
+        filter_observer(dest_type d, test_type t)
+            : dest(std::move(d))
+            , test(std::move(t))
+        {
+        }
+        void on_next(source_value_type v) const {
+            auto filtered = on_exception([&](){
+                return !this->test(v);},
+                dest);
+            if (filtered.empty()) {
+                return;
+            }
+            if (!filtered.get()) {
+                dest.on_next(v);
+            }
+        }
+        void on_error(std::exception_ptr e) const {
+            dest.on_error(e);
+        }
+        void on_completed() const {
+            dest.on_completed();
+        }
+
+        static subscriber<value_type, observer<value_type, this_type>> make(dest_type d, test_type t) {
+            return make_subscriber<value_type>(d, this_type(d, std::move(t)));
+        }
+    };
+
+    template<class Subscriber>
+    auto operator()(Subscriber dest) const
+        -> decltype(filter_observer<Subscriber>::make(std::move(dest), test)) {
+        return      filter_observer<Subscriber>::make(std::move(dest), test);
+    }
+};
+
+template<class Predicate>
+class filter_factory
+{
+    typedef typename std::decay<Predicate>::type test_type;
+    test_type predicate;
+public:
+    filter_factory(test_type p) : predicate(std::move(p)) {}
+    template<class Observable>
+    auto operator()(Observable&& source)
+        -> decltype(source.template lift<typename std::decay<Observable>::type::value_type>(filter<typename std::decay<Observable>::type::value_type, test_type>(predicate))) {
+        return      source.template lift<typename std::decay<Observable>::type::value_type>(filter<typename std::decay<Observable>::type::value_type, test_type>(predicate));
+    }
+};
+
+}
+
+template<class Predicate>
+auto filter(Predicate&& p)
+    ->      detail::filter_factory<Predicate> {
+    return  detail::filter_factory<Predicate>(std::forward<Predicate>(p));
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/operators/rx-finally.hpp b/dependencies64/RxCpp/include/rxcpp/operators/rx-finally.hpp
new file mode 100644 (file)
index 0000000..6e2b7ad
--- /dev/null
@@ -0,0 +1,96 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_OPERATORS_RX_FINALLY_HPP)
+#define RXCPP_OPERATORS_RX_FINALLY_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace operators {
+
+namespace detail {
+
+template<class T, class LastCall>
+struct finally
+{
+    typedef typename std::decay<T>::type source_value_type;
+    typedef typename std::decay<LastCall>::type last_call_type;
+    last_call_type last_call;
+
+    finally(last_call_type lc)
+        : last_call(std::move(lc))
+    {
+    }
+
+    template<class Subscriber>
+    struct finally_observer
+    {
+        typedef finally_observer<Subscriber> this_type;
+        typedef source_value_type value_type;
+        typedef typename std::decay<Subscriber>::type dest_type;
+        typedef observer<value_type, this_type> observer_type;
+        dest_type dest;
+
+        finally_observer(dest_type d)
+            : dest(std::move(d))
+        {
+        }
+        void on_next(source_value_type v) const {
+            dest.on_next(v);
+        }
+        void on_error(std::exception_ptr e) const {
+            dest.on_error(e);
+        }
+        void on_completed() const {
+            dest.on_completed();
+        }
+
+        static subscriber<value_type, observer<value_type, this_type>> make(dest_type d, const last_call_type& lc) {
+            auto dl = d.get_subscription();
+            composite_subscription cs;
+            dl.add(cs);
+            cs.add([=](){
+                dl.unsubscribe();
+                lc();
+            });
+            return make_subscriber<value_type>(cs, this_type(d));
+        }
+    };
+
+    template<class Subscriber>
+    auto operator()(Subscriber dest) const
+        -> decltype(finally_observer<Subscriber>::make(std::move(dest), last_call)) {
+        return      finally_observer<Subscriber>::make(std::move(dest), last_call);
+    }
+};
+
+template<class LastCall>
+class finally_factory
+{
+    typedef typename std::decay<LastCall>::type last_call_type;
+    last_call_type last_call;
+public:
+    finally_factory(last_call_type lc) : last_call(std::move(lc)) {}
+    template<class Observable>
+    auto operator()(Observable&& source)
+        -> decltype(source.template lift<typename std::decay<Observable>::type::value_type>(filter<typename std::decay<Observable>::type::value_type, last_call_type>(last_call))) {
+        return      source.template lift<typename std::decay<Observable>::type::value_type>(filter<typename std::decay<Observable>::type::value_type, last_call_type>(last_call));
+    }
+};
+
+}
+
+template<class LastCall>
+auto finally(LastCall lc)
+    ->      detail::finally_factory<LastCall> {
+    return  detail::finally_factory<LastCall>(std::move(lc));
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/operators/rx-flat_map.hpp b/dependencies64/RxCpp/include/rxcpp/operators/rx-flat_map.hpp
new file mode 100644 (file)
index 0000000..f8fd1d7
--- /dev/null
@@ -0,0 +1,262 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_OPERATORS_RX_FLATMAP_HPP)
+#define RXCPP_OPERATORS_RX_FLATMAP_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace operators {
+
+namespace detail {
+
+template<class Observable, class CollectionSelector, class ResultSelector, class Coordination>
+struct flat_map_traits {
+    typedef typename std::decay<Observable>::type source_type;
+    typedef typename std::decay<CollectionSelector>::type collection_selector_type;
+    typedef typename std::decay<ResultSelector>::type result_selector_type;
+    typedef typename std::decay<Coordination>::type coordination_type;
+
+    typedef typename source_type::value_type source_value_type;
+
+    struct tag_not_valid {};
+    template<class CV, class CCS>
+    static auto collection_check(int) -> decltype((*(CCS*)nullptr)(*(CV*)nullptr));
+    template<class CV, class CCS>
+    static tag_not_valid collection_check(...);
+
+    static_assert(!std::is_same<decltype(collection_check<source_value_type, collection_selector_type>(0)), tag_not_valid>::value, "flat_map CollectionSelector must be a function with the signature observable(flat_map::source_value_type)");
+
+    typedef decltype((*(collection_selector_type*)nullptr)((*(source_value_type*)nullptr))) collection_type;
+
+    static_assert(is_observable<collection_type>::value, "flat_map CollectionSelector must return an observable");
+
+    typedef typename collection_type::value_type collection_value_type;
+
+    template<class CV, class CCV, class CRS>
+    static auto result_check(int) -> decltype((*(CRS*)nullptr)(*(CV*)nullptr, *(CCV*)nullptr));
+    template<class CV, class CCV, class CRS>
+    static tag_not_valid result_check(...);
+
+    static_assert(!std::is_same<decltype(result_check<source_value_type, collection_value_type, result_selector_type>(0)), tag_not_valid>::value, "flat_map ResultSelector must be a function with the signature flat_map::value_type(flat_map::source_value_type, flat_map::collection_value_type)");
+
+    typedef decltype((*(result_selector_type*)nullptr)(*(source_value_type*)nullptr, *(collection_value_type*)nullptr)) value_type;
+};
+
+template<class Observable, class CollectionSelector, class ResultSelector, class Coordination>
+struct flat_map
+    : public operator_base<typename flat_map_traits<Observable, CollectionSelector, ResultSelector, Coordination>::value_type>
+{
+    typedef flat_map<Observable, CollectionSelector, ResultSelector, Coordination> this_type;
+    typedef flat_map_traits<Observable, CollectionSelector, ResultSelector, Coordination> traits;
+
+    typedef typename traits::source_type source_type;
+    typedef typename traits::collection_selector_type collection_selector_type;
+    typedef typename traits::result_selector_type result_selector_type;
+
+    typedef typename traits::source_value_type source_value_type;
+    typedef typename traits::collection_type collection_type;
+    typedef typename traits::collection_value_type collection_value_type;
+
+    typedef typename traits::coordination_type coordination_type;
+    typedef typename coordination_type::coordinator_type coordinator_type;
+
+    struct values
+    {
+        values(source_type o, collection_selector_type s, result_selector_type rs, coordination_type sf)
+            : source(std::move(o))
+            , selectCollection(std::move(s))
+            , selectResult(std::move(rs))
+            , coordination(std::move(sf))
+        {
+        }
+        source_type source;
+        collection_selector_type selectCollection;
+        result_selector_type selectResult;
+        coordination_type coordination;
+    };
+    values initial;
+
+    flat_map(source_type o, collection_selector_type s, result_selector_type rs, coordination_type sf)
+        : initial(std::move(o), std::move(s), std::move(rs), std::move(sf))
+    {
+    }
+
+    template<class Subscriber>
+    void on_subscribe(Subscriber scbr) const {
+        static_assert(is_subscriber<Subscriber>::value, "subscribe must be passed a subscriber");
+
+        typedef Subscriber output_type;
+
+        struct state_type
+            : public std::enable_shared_from_this<state_type>
+            , public values
+        {
+            state_type(values i, coordinator_type coor, output_type oarg)
+                : values(std::move(i))
+                , pendingCompletions(0)
+                , coordinator(std::move(coor))
+                , out(std::move(oarg))
+            {
+            }
+            // on_completed on the output must wait until all the
+            // subscriptions have received on_completed
+            int pendingCompletions;
+            coordinator_type coordinator;
+            output_type out;
+        };
+
+        auto coordinator = initial.coordination.create_coordinator(scbr.get_subscription());
+
+        // take a copy of the values for each subscription
+        auto state = std::shared_ptr<state_type>(new state_type(initial, std::move(coordinator), std::move(scbr)));
+
+        composite_subscription outercs;
+
+        // when the out observer is unsubscribed all the
+        // inner subscriptions are unsubscribed as well
+        state->out.add(outercs);
+
+        auto source = on_exception(
+            [&](){return state->coordinator.in(state->source);},
+            state->out);
+        if (source.empty()) {
+            return;
+        }
+
+        ++state->pendingCompletions;
+        // this subscribe does not share the observer subscription
+        // so that when it is unsubscribed the observer can be called
+        // until the inner subscriptions have finished
+        auto sink = make_subscriber<source_value_type>(
+            state->out,
+            outercs,
+        // on_next
+            [state](source_value_type st) {
+                auto selectedCollection = on_exception(
+                    [&](){return state->selectCollection(st);},
+                    state->out);
+                if (selectedCollection.empty()) {
+                    return;
+                }
+
+                composite_subscription innercs;
+
+                // when the out observer is unsubscribed all the
+                // inner subscriptions are unsubscribed as well
+                auto innercstoken = state->out.add(innercs);
+
+                innercs.add(make_subscription([state, innercstoken](){
+                    state->out.remove(innercstoken);
+                }));
+
+                auto selectedSource = on_exception(
+                    [&](){return state->coordinator.in(selectedCollection.get());},
+                    state->out);
+                if (selectedSource.empty()) {
+                    return;
+                }
+
+                ++state->pendingCompletions;
+                // this subscribe does not share the source subscription
+                // so that when it is unsubscribed the source will continue
+                auto sinkInner = make_subscriber<collection_value_type>(
+                    state->out,
+                    innercs,
+                // on_next
+                    [state, st](collection_value_type ct) {
+                        auto selectedResult = on_exception(
+                            [&](){return state->selectResult(st, std::move(ct));},
+                            state->out);
+                        if (selectedResult.empty()) {
+                            return;
+                        }
+                        state->out.on_next(std::move(*selectedResult));
+                    },
+                // on_error
+                    [state](std::exception_ptr e) {
+                        state->out.on_error(e);
+                    },
+                //on_completed
+                    [state](){
+                        if (--state->pendingCompletions == 0) {
+                            state->out.on_completed();
+                        }
+                    }
+                );
+
+                auto selectedSinkInner = on_exception(
+                    [&](){return state->coordinator.out(sinkInner);},
+                    state->out);
+                if (selectedSinkInner.empty()) {
+                    return;
+                }
+
+                selectedSource->subscribe(std::move(selectedSinkInner.get()));
+            },
+        // on_error
+            [state](std::exception_ptr e) {
+                state->out.on_error(e);
+            },
+        // on_completed
+            [state]() {
+                if (--state->pendingCompletions == 0) {
+                    state->out.on_completed();
+                }
+            }
+        );
+
+        auto selectedSink = on_exception(
+            [&](){return state->coordinator.out(sink);},
+            state->out);
+        if (selectedSink.empty()) {
+            return;
+        }
+
+        source->subscribe(std::move(selectedSink.get()));
+
+    }
+};
+
+template<class CollectionSelector, class ResultSelector, class Coordination>
+class flat_map_factory
+{
+    typedef typename std::decay<CollectionSelector>::type collection_selector_type;
+    typedef typename std::decay<ResultSelector>::type result_selector_type;
+    typedef typename std::decay<Coordination>::type coordination_type;
+
+    collection_selector_type selectorCollection;
+    result_selector_type selectorResult;
+    coordination_type coordination;
+public:
+    flat_map_factory(collection_selector_type s, result_selector_type rs, coordination_type sf)
+        : selectorCollection(std::move(rs))
+        , selectorResult(std::move(s))
+        , coordination(std::move(sf))
+    {
+    }
+
+    template<class Observable>
+    auto operator()(Observable&& source)
+        ->      observable<typename flat_map<Observable, CollectionSelector, ResultSelector, Coordination>::value_type, flat_map<Observable, CollectionSelector, ResultSelector, Coordination>> {
+        return  observable<typename flat_map<Observable, CollectionSelector, ResultSelector, Coordination>::value_type, flat_map<Observable, CollectionSelector, ResultSelector, Coordination>>(
+                                    flat_map<Observable, CollectionSelector, ResultSelector, Coordination>(std::forward<Observable>(source), selectorCollection, selectorResult, coordination));
+    }
+};
+
+}
+
+template<class CollectionSelector, class ResultSelector, class Coordination>
+auto flat_map(CollectionSelector&& s, ResultSelector&& rs, Coordination&& sf)
+    ->      detail::flat_map_factory<CollectionSelector, ResultSelector, Coordination> {
+    return  detail::flat_map_factory<CollectionSelector, ResultSelector, Coordination>(std::forward<CollectionSelector>(s), std::forward<ResultSelector>(rs), std::forward<Coordination>(sf));
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/operators/rx-group_by.hpp b/dependencies64/RxCpp/include/rxcpp/operators/rx-group_by.hpp
new file mode 100644 (file)
index 0000000..5ef609b
--- /dev/null
@@ -0,0 +1,218 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_OPERATORS_RX_GROUP_BY_HPP)
+#define RXCPP_OPERATORS_RX_GROUP_BY_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace operators {
+
+namespace detail {
+
+template<class T, class Selector>
+struct is_group_by_selector_for {
+
+    typedef typename std::decay<Selector>::type selector_type;
+    typedef T source_value_type;
+
+    struct tag_not_valid {};
+    template<class CV, class CS>
+    static auto check(int) -> decltype((*(CS*)nullptr)(*(CV*)nullptr));
+    template<class CV, class CS>
+    static tag_not_valid check(...);
+
+    typedef decltype(check<source_value_type, selector_type>(0)) type;
+    static const bool value = !std::is_same<type, tag_not_valid>::value;
+};
+
+template<class T, class Observable, class KeySelector, class MarbleSelector, class BinaryPredicate>
+struct group_by_traits
+{
+    typedef T source_value_type;
+    typedef typename std::decay<Observable>::type source_type;
+    typedef typename std::decay<KeySelector>::type key_selector_type;
+    typedef typename std::decay<MarbleSelector>::type marble_selector_type;
+    typedef typename std::decay<BinaryPredicate>::type predicate_type;
+
+    static_assert(is_group_by_selector_for<source_value_type, key_selector_type>::value, "group_by KeySelector must be a function with the signature key_type(source_value_type)");
+
+    typedef typename is_group_by_selector_for<source_value_type, key_selector_type>::type key_type;
+
+    static_assert(is_group_by_selector_for<source_value_type, marble_selector_type>::value, "group_by MarbleSelector must be a function with the signature marble_type(source_value_type)");
+
+    typedef typename is_group_by_selector_for<source_value_type, marble_selector_type>::type marble_type;
+
+    typedef rxsub::subject<marble_type> subject_type;
+
+    typedef std::map<key_type, typename subject_type::subscriber_type, predicate_type> key_subscriber_map_type;
+
+    typedef grouped_observable<key_type, source_value_type> grouped_observable_type;
+};
+
+template<class T, class Observable, class KeySelector, class MarbleSelector, class BinaryPredicate>
+struct group_by
+{
+    typedef group_by_traits<T, Observable, KeySelector, MarbleSelector, BinaryPredicate> traits_type;
+    typedef typename traits_type::key_selector_type key_selector_type;
+    typedef typename traits_type::marble_selector_type marble_selector_type;
+    typedef typename traits_type::marble_type marble_type;
+    typedef typename traits_type::predicate_type predicate_type;
+    typedef typename traits_type::subject_type subject_type;
+    typedef typename traits_type::key_type key_type;
+
+    struct group_by_values
+    {
+        group_by_values(key_selector_type ks, marble_selector_type ms, predicate_type p)
+            : keySelector(std::move(ks))
+            , marbleSelector(std::move(ms))
+            , predicate(std::move(p))
+        {
+        }
+        mutable key_selector_type keySelector;
+        mutable marble_selector_type marbleSelector;
+        mutable predicate_type predicate;
+    };
+
+    group_by_values initial;
+
+    group_by(key_selector_type ks, marble_selector_type ms, predicate_type p)
+        : initial(std::move(ks), std::move(ms), std::move(p))
+    {
+    }
+
+    struct group_by_observable : public rxs::source_base<marble_type>
+    {
+        subject_type subject;
+        key_type key;
+
+        group_by_observable(subject_type s, key_type k)
+            : subject(std::move(s))
+            , key(k)
+        {
+        }
+
+        template<class Subscriber>
+        void on_subscribe(Subscriber&& o) const {
+            subject.get_observable().subscribe(std::forward<Subscriber>(o));
+        }
+
+        key_type on_get_key() {
+            return key;
+        }
+    };
+
+    template<class Subscriber>
+    struct group_by_observer : public group_by_values
+    {
+        typedef group_by_observer<Subscriber> this_type;
+        typedef typename traits_type::grouped_observable_type value_type;
+        typedef typename std::decay<Subscriber>::type dest_type;
+        typedef observer<T, this_type> observer_type;
+        dest_type dest;
+
+        mutable typename traits_type::key_subscriber_map_type groups;
+
+        group_by_observer(dest_type d, group_by_values v)
+            : group_by_values(v)
+            , dest(std::move(d))
+            , groups(group_by_values::predicate)
+        {
+        }
+        void on_next(T v) const {
+            auto selectedKey = on_exception(
+                [&](){
+                    return this->keySelector(v);},
+                [this](std::exception_ptr e){on_error(e);});
+            if (selectedKey.empty()) {
+                return;
+            }
+            auto g = groups.find(selectedKey.get());
+            if (g == groups.end()) {
+                auto sub = subject_type();
+                g = groups.insert(std::make_pair(selectedKey.get(), sub.get_subscriber())).first;
+                dest.on_next(make_dynamic_grouped_observable<key_type, marble_type>(group_by_observable(sub, selectedKey.get())));
+            }
+            auto selectedMarble = on_exception(
+                [&](){
+                    return this->marbleSelector(v);},
+                [this](std::exception_ptr e){on_error(e);});
+            if (selectedMarble.empty()) {
+                return;
+            }
+            g->second.on_next(std::move(selectedMarble.get()));
+        }
+        void on_error(std::exception_ptr e) const {
+            for(auto& g : groups) {
+                g.second.on_error(e);
+            }
+            dest.on_error(e);
+        }
+        void on_completed() const {
+            for(auto& g : groups) {
+                g.second.on_completed();
+            }
+            dest.on_completed();
+        }
+
+        static subscriber<T, observer_type> make(dest_type d, group_by_values v) {
+            auto cs = d.get_subscription();
+            return make_subscriber<T>(std::move(cs), observer_type(this_type(std::move(d), std::move(v))));
+        }
+    };
+
+    template<class Subscriber>
+    auto operator()(Subscriber dest) const
+        -> decltype(group_by_observer<Subscriber>::make(std::move(dest), initial)) {
+        return      group_by_observer<Subscriber>::make(std::move(dest), initial);
+    }
+};
+
+template<class KeySelector, class MarbleSelector, class BinaryPredicate>
+class group_by_factory
+{
+    typedef typename std::decay<KeySelector>::type key_selector_type;
+    typedef typename std::decay<MarbleSelector>::type marble_selector_type;
+    typedef typename std::decay<BinaryPredicate>::type predicate_type;
+    key_selector_type keySelector;
+    marble_selector_type marbleSelector;
+    predicate_type predicate;
+public:
+    group_by_factory(key_selector_type ks, marble_selector_type ms, predicate_type p)
+        : keySelector(std::move(ks))
+        , marbleSelector(std::move(ms))
+        , predicate(std::move(p))
+    {
+    }
+    template<class Observable>
+    struct group_by_factory_traits
+    {
+        typedef typename Observable::value_type value_type;
+        typedef detail::group_by_traits<value_type, Observable, KeySelector, MarbleSelector, BinaryPredicate> traits_type;
+        typedef detail::group_by<value_type, Observable, KeySelector, MarbleSelector, BinaryPredicate> group_by_type;
+    };
+    template<class Observable>
+    auto operator()(Observable&& source)
+        -> decltype(source.template lift<typename group_by_factory_traits<Observable>::traits_type::grouped_observable_type>(typename group_by_factory_traits<Observable>::group_by_type(std::move(keySelector), std::move(marbleSelector), std::move(predicate)))) {
+        return      source.template lift<typename group_by_factory_traits<Observable>::traits_type::grouped_observable_type>(typename group_by_factory_traits<Observable>::group_by_type(std::move(keySelector), std::move(marbleSelector), std::move(predicate)));
+    }
+};
+
+}
+
+template<class KeySelector, class MarbleSelector, class BinaryPredicate>
+inline auto group_by(KeySelector ks, MarbleSelector ms, BinaryPredicate p)
+    ->      detail::group_by_factory<KeySelector, MarbleSelector, BinaryPredicate> {
+    return  detail::group_by_factory<KeySelector, MarbleSelector, BinaryPredicate>(std::move(ks), std::move(ms), std::move(p));
+}
+
+
+}
+
+}
+
+#endif
+
diff --git a/dependencies64/RxCpp/include/rxcpp/operators/rx-lift.hpp b/dependencies64/RxCpp/include/rxcpp/operators/rx-lift.hpp
new file mode 100644 (file)
index 0000000..08cd629
--- /dev/null
@@ -0,0 +1,96 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_OPERATORS_RX_LIFT_HPP)
+#define RXCPP_OPERATORS_RX_LIFT_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace detail {
+
+template<class V, class S, class F>
+struct is_lift_function_for {
+
+    struct tag_not_valid {};
+    template<class CS, class CF>
+    static auto check(int) -> decltype((*(CF*)nullptr)(*(CS*)nullptr));
+    template<class CS, class CF>
+    static tag_not_valid check(...);
+
+    typedef typename std::decay<S>::type for_type;
+    typedef typename std::decay<F>::type func_type;
+    typedef decltype(check<for_type, func_type>(0)) detail_result;
+    static const bool value = is_subscriber<detail_result>::value && is_subscriber<for_type>::value && std::is_convertible<V, typename detail_result::value_type>::value;
+};
+
+}
+
+namespace operators {
+
+namespace detail {
+
+template<class ResultType, class SourceOperator, class Operator>
+struct lift_traits
+{
+    typedef typename std::decay<ResultType>::type result_value_type;
+    typedef typename std::decay<SourceOperator>::type source_operator_type;
+    typedef typename std::decay<Operator>::type operator_type;
+
+    typedef typename source_operator_type::value_type source_value_type;
+
+    static_assert(rxcpp::detail::is_lift_function_for<source_value_type, subscriber<result_value_type>, operator_type>::value, "lift Operator must be a function with the signature subscriber<source_value_type, ...>(subscriber<result_value_type, ...>)");
+};
+
+template<class ResultType, class SourceOperator, class Operator>
+struct lift_operator : public operator_base<typename lift_traits<ResultType, SourceOperator, Operator>::result_value_type>
+{
+    typedef lift_traits<ResultType, SourceOperator, Operator> traits;
+    typedef typename traits::source_operator_type source_operator_type;
+    typedef typename traits::operator_type operator_type;
+    source_operator_type source;
+    operator_type chain;
+
+    lift_operator(source_operator_type s, operator_type op)
+        : source(std::move(s))
+        , chain(std::move(op))
+    {
+    }
+    template<class Subscriber>
+    void on_subscribe(Subscriber o) const {
+        auto lifted = chain(std::move(o));
+        trace_activity().lift_enter(source, chain, o, lifted);
+        source.on_subscribe(std::move(lifted));
+        trace_activity().lift_return(source, chain);
+    }
+};
+
+template<class ResultType, class Operator>
+class lift_factory
+{
+    typedef typename std::decay<Operator>::type operator_type;
+    operator_type chain;
+public:
+    lift_factory(operator_type op) : chain(std::move(op)) {}
+    template<class Observable>
+    auto operator()(Observable&& source)
+        -> decltype(source.template lift<ResultType>(chain)) {
+        return      source.template lift<ResultType>(chain);
+    }
+};
+
+}
+
+template<class ResultType, class Operator>
+auto lift(Operator&& op)
+    ->      detail::lift_factory<ResultType, Operator> {
+    return  detail::lift_factory<ResultType, Operator>(std::forward<Operator>(op));
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/operators/rx-map.hpp b/dependencies64/RxCpp/include/rxcpp/operators/rx-map.hpp
new file mode 100644 (file)
index 0000000..662cf95
--- /dev/null
@@ -0,0 +1,101 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_OPERATORS_RX_MAP_HPP)
+#define RXCPP_OPERATORS_RX_MAP_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace operators {
+
+namespace detail {
+
+
+template<class T, class Selector>
+struct map
+{
+    typedef typename std::decay<T>::type source_value_type;
+    typedef typename std::decay<Selector>::type select_type;
+    typedef decltype((*(select_type*)nullptr)(*(source_value_type*)nullptr)) value_type;
+    select_type selector;
+
+    map(select_type s)
+        : selector(std::move(s))
+    {
+    }
+
+    template<class Subscriber>
+    struct map_observer
+    {
+        typedef map_observer<Subscriber> this_type;
+        typedef decltype((*(select_type*)nullptr)(*(source_value_type*)nullptr)) value_type;
+        typedef typename std::decay<Subscriber>::type dest_type;
+        typedef observer<T, this_type> observer_type;
+        dest_type dest;
+        select_type selector;
+
+        map_observer(dest_type d, select_type s)
+            : dest(std::move(d))
+            , selector(std::move(s))
+        {
+        }
+        void on_next(source_value_type v) const {
+            auto selected = on_exception(
+                [&](){
+                    return this->selector(std::move(v));},
+                dest);
+            if (selected.empty()) {
+                return;
+            }
+            dest.on_next(std::move(selected.get()));
+        }
+        void on_error(std::exception_ptr e) const {
+            dest.on_error(e);
+        }
+        void on_completed() const {
+            dest.on_completed();
+        }
+
+        static subscriber<T, observer_type> make(dest_type d, select_type s) {
+            auto cs = d.get_subscription();
+            return make_subscriber<T>(std::move(cs), observer_type(this_type(std::move(d), std::move(s))));
+        }
+    };
+
+    template<class Subscriber>
+    auto operator()(Subscriber dest) const
+        -> decltype(map_observer<Subscriber>::make(std::move(dest), selector)) {
+        return      map_observer<Subscriber>::make(std::move(dest), selector);
+    }
+};
+
+template<class Selector>
+class map_factory
+{
+    typedef typename std::decay<Selector>::type select_type;
+    select_type selector;
+public:
+    map_factory(select_type s) : selector(std::move(s)) {}
+    template<class Observable>
+    auto operator()(Observable&& source)
+        -> decltype(source.template lift<typename map<typename std::decay<Observable>::type::value_type, select_type>::value_type>(map<typename std::decay<Observable>::type::value_type, select_type>(selector))) {
+        return      source.template lift<typename map<typename std::decay<Observable>::type::value_type, select_type>::value_type>(map<typename std::decay<Observable>::type::value_type, select_type>(selector));
+    }
+};
+
+}
+
+template<class Selector>
+auto map(Selector&& p)
+    ->      detail::map_factory<Selector> {
+    return  detail::map_factory<Selector>(std::forward<Selector>(p));
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/operators/rx-merge.hpp b/dependencies64/RxCpp/include/rxcpp/operators/rx-merge.hpp
new file mode 100644 (file)
index 0000000..9faa862
--- /dev/null
@@ -0,0 +1,204 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_OPERATORS_RX_MERGE_HPP)
+#define RXCPP_OPERATORS_RX_MERGE_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace operators {
+
+namespace detail {
+
+template<class T, class Observable, class Coordination>
+struct merge
+    : public operator_base<typename std::decay<T>::type::value_type>
+{
+    //static_assert(is_observable<Observable>::value, "merge requires an observable");
+    //static_assert(is_observable<T>::value, "merge requires an observable that contains observables");
+
+    typedef merge<T, Observable, Coordination> this_type;
+
+    typedef typename std::decay<T>::type source_value_type;
+    typedef typename std::decay<Observable>::type source_type;
+
+    typedef typename source_type::source_operator_type source_operator_type;
+    typedef typename source_value_type::value_type value_type;
+
+    typedef typename std::decay<Coordination>::type coordination_type;
+    typedef typename coordination_type::coordinator_type coordinator_type;
+
+    struct values
+    {
+        values(source_operator_type o, coordination_type sf)
+            : source_operator(std::move(o))
+            , coordination(std::move(sf))
+        {
+        }
+        source_operator_type source_operator;
+        coordination_type coordination;
+    };
+    values initial;
+
+    merge(const source_type& o, coordination_type sf)
+        : initial(o.source_operator, std::move(sf))
+    {
+    }
+
+    template<class Subscriber>
+    void on_subscribe(Subscriber scbr) const {
+        static_assert(is_subscriber<Subscriber>::value, "subscribe must be passed a subscriber");
+
+        typedef Subscriber output_type;
+
+        struct merge_state_type
+            : public std::enable_shared_from_this<merge_state_type>
+            , public values
+        {
+            merge_state_type(values i, coordinator_type coor, output_type oarg)
+                : values(i)
+                , source(i.source_operator)
+                , pendingCompletions(0)
+                , coordinator(std::move(coor))
+                , out(std::move(oarg))
+            {
+            }
+            observable<source_value_type, source_operator_type> source;
+            // on_completed on the output must wait until all the
+            // subscriptions have received on_completed
+            int pendingCompletions;
+            coordinator_type coordinator;
+            output_type out;
+        };
+
+        auto coordinator = initial.coordination.create_coordinator(scbr.get_subscription());
+
+        // take a copy of the values for each subscription
+        auto state = std::shared_ptr<merge_state_type>(new merge_state_type(initial, std::move(coordinator), std::move(scbr)));
+
+        composite_subscription outercs;
+
+        // when the out observer is unsubscribed all the
+        // inner subscriptions are unsubscribed as well
+        state->out.add(outercs);
+
+        auto source = on_exception(
+            [&](){return state->coordinator.in(state->source);},
+            state->out);
+        if (source.empty()) {
+            return;
+        }
+
+        ++state->pendingCompletions;
+        // this subscribe does not share the observer subscription
+        // so that when it is unsubscribed the observer can be called
+        // until the inner subscriptions have finished
+        auto sink = make_subscriber<source_value_type>(
+            state->out,
+            outercs,
+        // on_next
+            [state](source_value_type st) {
+
+                composite_subscription innercs;
+
+                // when the out observer is unsubscribed all the
+                // inner subscriptions are unsubscribed as well
+                auto innercstoken = state->out.add(innercs);
+
+                innercs.add(make_subscription([state, innercstoken](){
+                    state->out.remove(innercstoken);
+                }));
+
+                auto selectedSource = on_exception(
+                    [&](){return state->coordinator.in(st);},
+                    state->out);
+                if (selectedSource.empty()) {
+                    return;
+                }
+
+                ++state->pendingCompletions;
+                // this subscribe does not share the source subscription
+                // so that when it is unsubscribed the source will continue
+                auto sinkInner = make_subscriber<value_type>(
+                    state->out,
+                    innercs,
+                // on_next
+                    [state, st](value_type ct) {
+                        state->out.on_next(std::move(ct));
+                    },
+                // on_error
+                    [state](std::exception_ptr e) {
+                        state->out.on_error(e);
+                    },
+                //on_completed
+                    [state](){
+                        if (--state->pendingCompletions == 0) {
+                            state->out.on_completed();
+                        }
+                    }
+                );
+                auto selectedSinkInner = on_exception(
+                    [&](){return state->coordinator.out(sinkInner);},
+                    state->out);
+                if (selectedSinkInner.empty()) {
+                    return;
+                }
+                selectedSource->subscribe(std::move(selectedSinkInner.get()));
+            },
+        // on_error
+            [state](std::exception_ptr e) {
+                state->out.on_error(e);
+            },
+        // on_completed
+            [state]() {
+                if (--state->pendingCompletions == 0) {
+                    state->out.on_completed();
+                }
+            }
+        );
+        auto selectedSink = on_exception(
+            [&](){return state->coordinator.out(sink);},
+            state->out);
+        if (selectedSink.empty()) {
+            return;
+        }
+        source->subscribe(std::move(selectedSink.get()));
+    }
+};
+
+template<class Coordination>
+class merge_factory
+{
+    typedef typename std::decay<Coordination>::type coordination_type;
+
+    coordination_type coordination;
+public:
+    merge_factory(coordination_type sf)
+        : coordination(std::move(sf))
+    {
+    }
+
+    template<class Observable>
+    auto operator()(Observable source)
+        ->      observable<typename merge<typename Observable::value_type, Observable, Coordination>::value_type,   merge<typename Observable::value_type, Observable, Coordination>> {
+        return  observable<typename merge<typename Observable::value_type, Observable, Coordination>::value_type,   merge<typename Observable::value_type, Observable, Coordination>>(
+                                                                                                                    merge<typename Observable::value_type, Observable, Coordination>(std::move(source), coordination));
+    }
+};
+
+}
+
+template<class Coordination>
+auto merge(Coordination&& sf)
+    ->      detail::merge_factory<Coordination> {
+    return  detail::merge_factory<Coordination>(std::forward<Coordination>(sf));
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/operators/rx-multicast.hpp b/dependencies64/RxCpp/include/rxcpp/operators/rx-multicast.hpp
new file mode 100644 (file)
index 0000000..966bfa3
--- /dev/null
@@ -0,0 +1,97 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_OPERATORS_RX_MULTICAST_HPP)
+#define RXCPP_OPERATORS_RX_MULTICAST_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace operators {
+
+namespace detail {
+
+template<class T, class Observable, class Subject>
+struct multicast : public operator_base<T>
+{
+    typedef typename std::decay<Observable>::type source_type;
+    typedef typename std::decay<Subject>::type subject_type;
+
+    struct multicast_state : public std::enable_shared_from_this<multicast_state>
+    {
+        multicast_state(source_type o, subject_type sub)
+            : source(std::move(o))
+            , subject_value(std::move(sub))
+        {
+        }
+        source_type source;
+        subject_type subject_value;
+        rxu::detail::maybe<typename composite_subscription::weak_subscription> connection;
+    };
+
+    std::shared_ptr<multicast_state> state;
+
+    multicast(source_type o, subject_type sub)
+        : state(std::make_shared<multicast_state>(std::move(o), std::move(sub)))
+    {
+    }
+    template<class Subscriber>
+    void on_subscribe(Subscriber&& o) const {
+        state->subject_value.get_observable().subscribe(std::forward<Subscriber>(o));
+    }
+    void on_connect(composite_subscription cs) const {
+        if (state->connection.empty()) {
+            auto destination = state->subject_value.get_subscriber();
+
+            // the lifetime of each connect is nested in the subject lifetime
+            state->connection.reset(destination.add(cs));
+
+            auto localState = state;
+
+            // when the connection is finished it should shutdown the connection
+            cs.add(
+                [destination, localState](){
+                    if (!localState->connection.empty()) {
+                        destination.remove(localState->connection.get());
+                        localState->connection.reset();
+                    }
+                });
+
+            // use cs not destination for lifetime of subscribe.
+            state->source.subscribe(cs, destination);
+        }
+    }
+};
+
+template<class Subject>
+class multicast_factory
+{
+    Subject caster;
+public:
+    multicast_factory(Subject sub)
+        : caster(std::move(sub))
+    {
+    }
+    template<class Observable>
+    auto operator()(Observable&& source)
+        ->      connectable_observable<typename std::decay<Observable>::type::value_type,   multicast<typename std::decay<Observable>::type::value_type, Observable, Subject>> {
+        return  connectable_observable<typename std::decay<Observable>::type::value_type,   multicast<typename std::decay<Observable>::type::value_type, Observable, Subject>>(
+                                                                                            multicast<typename std::decay<Observable>::type::value_type, Observable, Subject>(std::forward<Observable>(source), caster));
+    }
+};
+
+}
+
+template<class Subject>
+inline auto multicast(Subject sub)
+    ->      detail::multicast_factory<Subject> {
+    return  detail::multicast_factory<Subject>(std::move(sub));
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/operators/rx-observe_on.hpp b/dependencies64/RxCpp/include/rxcpp/operators/rx-observe_on.hpp
new file mode 100644 (file)
index 0000000..4d89044
--- /dev/null
@@ -0,0 +1,279 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_OPERATORS_RX_OBSERVE_ON_HPP)
+#define RXCPP_OPERATORS_RX_OBSERVE_ON_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace operators {
+
+namespace detail {
+
+template<class T, class Coordination>
+struct observe_on
+{
+    typedef typename std::decay<T>::type source_value_type;
+
+    typedef typename std::decay<Coordination>::type coordination_type;
+    typedef typename coordination_type::coordinator_type coordinator_type;
+
+    coordination_type coordination;
+
+    observe_on(coordination_type cn)
+        : coordination(std::move(cn))
+    {
+    }
+
+    template<class Subscriber>
+    struct observe_on_observer
+    {
+        typedef observe_on_observer<Subscriber> this_type;
+        typedef observer_base<source_value_type> base_type;
+        typedef source_value_type value_type;
+        typedef typename std::decay<Subscriber>::type dest_type;
+        typedef observer<value_type, this_type> observer_type;
+
+        typedef rxn::notification<T> notification_type;
+        typedef typename notification_type::type base_notification_type;
+        typedef std::queue<base_notification_type> queue_type;
+
+        struct mode
+        {
+            enum type {
+                Invalid = 0,
+                Processing,
+                Empty,
+                Disposed,
+                Errored
+            };
+        };
+        struct observe_on_state : std::enable_shared_from_this<observe_on_state>
+        {
+            mutable std::mutex lock;
+            mutable queue_type queue;
+            mutable queue_type drain_queue;
+            composite_subscription lifetime;
+            rxsc::worker processor;
+            mutable typename mode::type current;
+            coordinator_type coordinator;
+            dest_type destination;
+
+            observe_on_state(dest_type d, coordinator_type coor, composite_subscription cs)
+                : lifetime(std::move(cs))
+                , current(mode::Empty)
+                , coordinator(std::move(coor))
+                , destination(std::move(d))
+            {
+            }
+
+            void ensure_processing(std::unique_lock<std::mutex>& guard) const {
+                if (!guard.owns_lock()) {
+                    abort();
+                }
+                if (current == mode::Empty) {
+                    current = mode::Processing;
+
+                    auto keepAlive = this->shared_from_this();
+
+                    auto drain = [keepAlive, this](const rxsc::schedulable& self){
+                        using std::swap;
+                        try {
+                            if (drain_queue.empty() || !destination.is_subscribed()) {
+                                std::unique_lock<std::mutex> guard(lock);
+                                if (!destination.is_subscribed() ||
+                                    (!lifetime.is_subscribed() && queue.empty() && drain_queue.empty())) {
+                                    current = mode::Disposed;
+                                    queue_type expired;
+                                    swap(expired, queue);
+                                    guard.unlock();
+                                    lifetime.unsubscribe();
+                                    destination.unsubscribe();
+                                    return;
+                                }
+                                if (drain_queue.empty()) {
+                                    if (queue.empty()) {
+                                        current = mode::Empty;
+                                        return;
+                                    }
+                                    swap(queue, drain_queue);
+                                }
+                            }
+                            auto notification = std::move(drain_queue.front());
+                            drain_queue.pop();
+                            notification->accept(destination);
+                            self();
+                        } catch(...) {
+                            destination.on_error(std::current_exception());
+                            std::unique_lock<std::mutex> guard(lock);
+                            current = mode::Errored;
+                            queue_type expired;
+                            swap(expired, queue);
+                        }
+                    };
+
+                    auto selectedDrain = on_exception(
+                        [&](){return coordinator.act(drain);},
+                        destination);
+                    if (selectedDrain.empty()) {
+                        std::unique_lock<std::mutex> guard(lock);
+                        current = mode::Errored;
+                        using std::swap;
+                        queue_type expired;
+                        swap(expired, queue);
+                        return;
+                    }
+
+                    auto processor = coordinator.get_worker();
+
+                    RXCPP_UNWIND_AUTO([&](){guard.lock();});
+                    guard.unlock();
+
+                    processor.schedule(selectedDrain.get());
+                }
+            }
+        };
+        std::shared_ptr<observe_on_state> state;
+
+        observe_on_observer(dest_type d, coordinator_type coor, composite_subscription cs)
+            : state(std::make_shared<observe_on_state>(std::move(d), std::move(coor), std::move(cs)))
+        {
+        }
+
+        void on_next(source_value_type v) const {
+            std::unique_lock<std::mutex> guard(state->lock);
+            state->queue.push(notification_type::on_next(std::move(v)));
+            state->ensure_processing(guard);
+        }
+        void on_error(std::exception_ptr e) const {
+            std::unique_lock<std::mutex> guard(state->lock);
+            state->queue.push(notification_type::on_error(e));
+            state->ensure_processing(guard);
+        }
+        void on_completed() const {
+            std::unique_lock<std::mutex> guard(state->lock);
+            state->queue.push(notification_type::on_completed());
+            state->ensure_processing(guard);
+        }
+
+        static subscriber<value_type, observer<value_type, this_type>> make(dest_type d, coordination_type cn, composite_subscription cs = composite_subscription()) {
+            auto coor = cn.create_coordinator(d.get_subscription());
+            d.add(cs);
+
+            this_type o(d, std::move(coor), cs);
+            auto keepAlive = o.state;
+            cs.add([keepAlive](){
+                std::unique_lock<std::mutex> guard(keepAlive->lock);
+                keepAlive->ensure_processing(guard);
+            });
+
+            return make_subscriber<value_type>(d, cs, make_observer<value_type>(std::move(o)));
+        }
+    };
+
+    template<class Subscriber>
+    auto operator()(Subscriber dest) const
+        -> decltype(observe_on_observer<decltype(dest.as_dynamic())>::make(dest.as_dynamic(), coordination)) {
+        return      observe_on_observer<decltype(dest.as_dynamic())>::make(dest.as_dynamic(), coordination);
+    }
+};
+
+template<class Coordination>
+class observe_on_factory
+{
+    typedef typename std::decay<Coordination>::type coordination_type;
+    coordination_type coordination;
+public:
+    observe_on_factory(coordination_type cn) : coordination(std::move(cn)) {}
+    template<class Observable>
+    auto operator()(Observable&& source)
+        -> decltype(source.template lift<typename std::decay<Observable>::type::value_type>(observe_on<typename std::decay<Observable>::type::value_type, coordination_type>(coordination))) {
+        return      source.template lift<typename std::decay<Observable>::type::value_type>(observe_on<typename std::decay<Observable>::type::value_type, coordination_type>(coordination));
+    }
+};
+
+}
+
+template<class Coordination>
+auto observe_on(Coordination cn)
+    ->      detail::observe_on_factory<Coordination> {
+    return  detail::observe_on_factory<Coordination>(std::move(cn));
+}
+
+
+}
+
+class observe_on_one_worker : public coordination_base
+{
+    rxsc::scheduler factory;
+
+    class input_type
+    {
+        rxsc::worker controller;
+        rxsc::scheduler factory;
+        identity_one_worker coordination;
+    public:
+        explicit input_type(rxsc::worker w)
+            : controller(w)
+            , factory(rxsc::make_same_worker(w))
+            , coordination(factory)
+        {
+        }
+        inline rxsc::worker get_worker() const {
+            return controller;
+        }
+        inline rxsc::scheduler get_scheduler() const {
+            return factory;
+        }
+        inline rxsc::scheduler::clock_type::time_point now() const {
+            return factory.now();
+        }
+        template<class Observable>
+        auto in(Observable o) const
+            -> decltype(o.observe_on(coordination)) {
+            return      o.observe_on(coordination);
+        }
+        template<class Subscriber>
+        auto out(Subscriber s) const
+            -> Subscriber {
+            return std::move(s);
+        }
+        template<class F>
+        auto act(F f) const
+            -> F {
+            return std::move(f);
+        }
+    };
+
+public:
+
+    explicit observe_on_one_worker(rxsc::scheduler sc) : factory(sc) {}
+
+    typedef coordinator<input_type> coordinator_type;
+
+    inline rxsc::scheduler::clock_type::time_point now() const {
+        return factory.now();
+    }
+
+    inline coordinator_type create_coordinator(composite_subscription cs = composite_subscription()) const {
+        auto w = factory.create_worker(std::move(cs));
+        return coordinator_type(input_type(std::move(w)));
+    }
+};
+
+inline observe_on_one_worker observe_on_event_loop() {
+    static observe_on_one_worker r(rxsc::make_event_loop());
+    return r;
+}
+
+inline observe_on_one_worker observe_on_new_thread() {
+    static observe_on_one_worker r(rxsc::make_new_thread());
+    return r;
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/operators/rx-publish.hpp b/dependencies64/RxCpp/include/rxcpp/operators/rx-publish.hpp
new file mode 100644 (file)
index 0000000..34de51a
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_OPERATORS_RX_PUBLISH_HPP)
+#define RXCPP_OPERATORS_RX_PUBLISH_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace operators {
+
+namespace detail {
+
+template<template<class T> class Subject>
+class publish_factory
+{
+public:
+    publish_factory() {}
+    template<class Observable>
+    auto operator()(Observable&& source)
+        ->      connectable_observable<typename std::decay<Observable>::type::value_type,   multicast<typename std::decay<Observable>::type::value_type, Observable,    Subject<typename std::decay<Observable>::type::value_type>>> {
+        return  connectable_observable<typename std::decay<Observable>::type::value_type,   multicast<typename std::decay<Observable>::type::value_type, Observable,    Subject<typename std::decay<Observable>::type::value_type>>>(
+                                                                                            multicast<typename std::decay<Observable>::type::value_type, Observable,    Subject<typename std::decay<Observable>::type::value_type>>(
+                                                                                                std::forward<Observable>(source),                                       Subject<typename std::decay<Observable>::type::value_type>()));
+    }
+};
+
+}
+
+inline auto publish()
+    ->      detail::publish_factory<rxsub::subject> {
+    return  detail::publish_factory<rxsub::subject>();
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/operators/rx-reduce.hpp b/dependencies64/RxCpp/include/rxcpp/operators/rx-reduce.hpp
new file mode 100644 (file)
index 0000000..1c721e4
--- /dev/null
@@ -0,0 +1,252 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_OPERATORS_RX_REDUCE_HPP)
+#define RXCPP_OPERATORS_RX_REDUCE_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace operators {
+
+namespace detail {
+
+template<class T, class Seed, class Accumulator>
+struct is_accumulate_function_for {
+
+    typedef typename std::decay<Accumulator>::type accumulator_type;
+    typedef typename std::decay<Seed>::type seed_type;
+    typedef T source_value_type;
+
+    struct tag_not_valid {};
+    template<class CS, class CV, class CRS>
+    static auto check(int) -> decltype((*(CRS*)nullptr)(*(CS*)nullptr, *(CV*)nullptr));
+    template<class CS, class CV, class CRS>
+    static tag_not_valid check(...);
+
+    typedef decltype(check<seed_type, source_value_type, accumulator_type>(0)) type;
+    static const bool value = std::is_same<type, seed_type>::value;
+};
+
+template<class Seed, class ResultSelector>
+struct is_result_function_for {
+
+    typedef typename std::decay<ResultSelector>::type result_selector_type;
+    typedef typename std::decay<Seed>::type seed_type;
+
+    struct tag_not_valid {};
+
+    template<class CS, class CRS>
+    static auto check(int) -> decltype((*(CRS*)nullptr)(*(CS*)nullptr));
+    template<class CS, class CRS>
+    static tag_not_valid check(...);
+
+    typedef decltype(check<seed_type, result_selector_type>(0)) type;
+    static const bool value = !std::is_same<type, tag_not_valid>::value;
+};
+
+template<class T, class SourceOperator, class Accumulator, class ResultSelector, class Seed>
+struct reduce_traits
+{
+    typedef typename std::decay<SourceOperator>::type source_type;
+    typedef typename std::decay<Accumulator>::type accumulator_type;
+    typedef typename std::decay<ResultSelector>::type result_selector_type;
+    typedef typename std::decay<Seed>::type seed_type;
+
+    typedef T source_value_type;
+
+    static_assert(is_accumulate_function_for<source_value_type, seed_type, accumulator_type>::value, "reduce Accumulator must be a function with the signature Seed(Seed, reduce::source_value_type)");
+
+    static_assert(is_result_function_for<seed_type, result_selector_type>::value, "reduce ResultSelector must be a function with the signature reduce::value_type(Seed)");
+
+    typedef typename is_result_function_for<seed_type, result_selector_type>::type value_type;
+};
+
+template<class T, class SourceOperator, class Accumulator, class ResultSelector, class Seed>
+struct reduce : public operator_base<typename reduce_traits<T, SourceOperator, Accumulator, ResultSelector, Seed>::value_type>
+{
+    typedef reduce<T, SourceOperator, Accumulator, ResultSelector, Seed> this_type;
+    typedef reduce_traits<T, SourceOperator, Accumulator, ResultSelector, Seed> traits;
+
+    typedef typename traits::source_type source_type;
+    typedef typename traits::accumulator_type accumulator_type;
+    typedef typename traits::result_selector_type result_selector_type;
+    typedef typename traits::seed_type seed_type;
+
+    typedef typename traits::source_value_type source_value_type;
+    typedef typename traits::value_type value_type;
+
+    struct reduce_initial_type
+    {
+        ~reduce_initial_type()
+        {
+        }
+        reduce_initial_type(source_type o, accumulator_type a, result_selector_type rs, seed_type s)
+            : source(std::move(o))
+            , accumulator(std::move(a))
+            , result_selector(std::move(rs))
+            , seed(std::move(s))
+        {
+        }
+        source_type source;
+        accumulator_type accumulator;
+        result_selector_type result_selector;
+        seed_type seed;
+    };
+    reduce_initial_type initial;
+
+    ~reduce()
+    {
+    }
+    reduce(source_type o, accumulator_type a, result_selector_type rs, seed_type s)
+        : initial(std::move(o), std::move(a), std::move(rs), std::move(s))
+    {
+    }
+    template<class Subscriber>
+    void on_subscribe(Subscriber o) const {
+        struct reduce_state_type
+            : public reduce_initial_type
+            , public std::enable_shared_from_this<reduce_state_type>
+        {
+            reduce_state_type(reduce_initial_type i, Subscriber scrbr)
+                : reduce_initial_type(i)
+                , source(i.source)
+                , current(reduce_initial_type::seed)
+                , out(std::move(scrbr))
+            {
+            }
+            observable<T, SourceOperator> source;
+            seed_type current;
+            Subscriber out;
+        };
+        auto state = std::make_shared<reduce_state_type>(initial, std::move(o));
+        state->source.subscribe(
+            state->out,
+        // on_next
+            [state](T t) {
+                auto next = on_exception(
+                    [&](){return state->accumulator(state->current, t);},
+                    state->out);
+                if (next.empty()) {
+                    return;
+                }
+                state->current = next.get();
+            },
+        // on_error
+            [state](std::exception_ptr e) {
+                state->out.on_error(e);
+            },
+        // on_completed
+            [state]() {
+                auto result = on_exception(
+                    [&](){return state->result_selector(state->current);},
+                    state->out);
+                if (result.empty()) {
+                    return;
+                }
+                state->out.on_next(result.get());
+                state->out.on_completed();
+            }
+        );
+    }
+};
+
+template<class Accumulator, class ResultSelector, class Seed>
+class reduce_factory
+{
+    typedef typename std::decay<Accumulator>::type accumulator_type;
+    typedef typename std::decay<ResultSelector>::type result_selector_type;
+    typedef typename std::decay<Seed>::type seed_type;
+
+    accumulator_type accumulator;
+    result_selector_type result_selector;
+    seed_type seed;
+public:
+    reduce_factory(accumulator_type a, result_selector_type rs, Seed s)
+        : accumulator(std::move(a))
+        , result_selector(std::move(rs))
+        , seed(std::move(s))
+    {
+    }
+    template<class Observable>
+    auto operator()(const Observable& source)
+        ->      observable<seed_type,   reduce<typename Observable::value_type, typename Observable::source_operator_type, Accumulator, ResultSelector, Seed>> {
+        return  observable<seed_type,   reduce<typename Observable::value_type, typename Observable::source_operator_type, Accumulator, ResultSelector, Seed>>(
+                                        reduce<typename Observable::value_type, typename Observable::source_operator_type, Accumulator, ResultSelector, Seed>(source.source_operator, accumulator, result_selector, seed));
+    }
+};
+
+template<class T>
+struct initialize_seeder {
+    typedef T seed_type;
+    seed_type seed() {
+        return seed_type{};
+    }
+};
+
+template<class T>
+struct average {
+    struct seed_type
+    {
+        seed_type()
+            : value()
+            , count(0)
+        {
+        }
+        T value;
+        int count;
+        rxu::detail::maybe<double> stage;
+    };
+    seed_type seed() {
+        return seed_type{};
+    }
+    seed_type operator()(seed_type a, T v) {
+        if (a.count != 0 &&
+            (a.count == std::numeric_limits<int>::max() ||
+            ((v > 0) && (a.value > (std::numeric_limits<T>::max() - v))) ||
+            ((v < 0) && (a.value < (std::numeric_limits<T>::min() - v))))) {
+            // would overflow, calc existing and reset for next batch
+            // this will add error to the final result, but the alternative
+            // is to fail on overflow
+            double avg = a.value / a.count;
+            a.value = v;
+            a.count = 1;
+            if (!a.stage.empty()) {
+                a.stage.reset((*a.stage + avg) / 2);
+            } else {
+                a.stage.reset(avg);
+            }
+        } else {
+            a.value += v;
+            ++a.count;
+        }
+        return a;
+    }
+    double operator()(seed_type a) {
+        if (a.count > 0) {
+            double avg = a.value / a.count;
+            if (!a.stage.empty()) {
+                avg = (*a.stage + avg) / 2;
+            }
+            return avg;
+        }
+        return a.value;
+    }
+};
+
+}
+
+template<class Seed, class Accumulator, class ResultSelector>
+auto reduce(Seed s, Accumulator a, ResultSelector rs)
+    ->      detail::reduce_factory<Accumulator, ResultSelector, Seed> {
+    return  detail::reduce_factory<Accumulator, ResultSelector, Seed>(std::move(a), std::move(rs), std::move(s));
+}
+
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/operators/rx-ref_count.hpp b/dependencies64/RxCpp/include/rxcpp/operators/rx-ref_count.hpp
new file mode 100644 (file)
index 0000000..41e4bd9
--- /dev/null
@@ -0,0 +1,85 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_OPERATORS_RX_REF_COUNT_HPP)
+#define RXCPP_OPERATORS_RX_REF_COUNT_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace operators {
+
+namespace detail {
+
+template<class T, class ConnectableObservable>
+struct ref_count : public operator_base<T>
+{
+    typedef typename std::decay<ConnectableObservable>::type source_type;
+
+    struct ref_count_state : public std::enable_shared_from_this<ref_count_state>
+    {
+        explicit ref_count_state(source_type o)
+            : source(std::move(o))
+            , subscribers(0)
+        {
+        }
+
+        source_type source;
+        std::mutex lock;
+        long subscribers;
+        composite_subscription connection;
+    };
+    std::shared_ptr<ref_count_state> state;
+
+    explicit ref_count(source_type o)
+        : state(std::make_shared<ref_count_state>(std::move(o)))
+    {
+    }
+
+    template<class Subscriber>
+    void on_subscribe(Subscriber&& o) const {
+        std::unique_lock<std::mutex> guard(state->lock);
+        auto needConnect = ++state->subscribers == 1;
+        auto keepAlive = state;
+        guard.unlock();
+        o.add(
+            [keepAlive](){
+                std::unique_lock<std::mutex> guard_unsubscribe(keepAlive->lock);
+                if (--keepAlive->subscribers == 0) {
+                    keepAlive->connection.unsubscribe();
+                    keepAlive->connection = composite_subscription();
+                }
+            });
+        keepAlive->source.subscribe(std::forward<Subscriber>(o));
+        if (needConnect) {
+            keepAlive->source.connect(keepAlive->connection);
+        }
+    }
+};
+
+class ref_count_factory
+{
+public:
+    ref_count_factory() {}
+    template<class Observable>
+    auto operator()(Observable&& source)
+        ->      observable<typename std::decay<Observable>::type::value_type,   ref_count<typename std::decay<Observable>::type::value_type, Observable>> {
+        return  observable<typename std::decay<Observable>::type::value_type,   ref_count<typename std::decay<Observable>::type::value_type, Observable>>(
+                                                                                ref_count<typename std::decay<Observable>::type::value_type, Observable>(std::forward<Observable>(source)));
+    }
+};
+
+}
+
+inline auto ref_count()
+    ->      detail::ref_count_factory {
+    return  detail::ref_count_factory();
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/operators/rx-repeat.hpp b/dependencies64/RxCpp/include/rxcpp/operators/rx-repeat.hpp
new file mode 100644 (file)
index 0000000..91f59b8
--- /dev/null
@@ -0,0 +1,122 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_OPERATORS_RX_REPEAT_HPP)
+#define RXCPP_OPERATORS_RX_REPEAT_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace operators {
+
+namespace detail {
+
+template<class T, class Observable, class Count>
+struct repeat : public operator_base<T>
+{
+    typedef typename std::decay<Observable>::type source_type;
+    typedef typename std::decay<Count>::type count_type;
+    struct values
+    {
+        values(source_type s, count_type t)
+            : source(std::move(s))
+            , remaining(std::move(t))
+            , repeat_infinitely(t == 0)
+        {
+        }
+        source_type source;
+        count_type remaining;
+        bool repeat_infinitely;
+    };
+    values initial;
+
+    repeat(source_type s, count_type t)
+        : initial(std::move(s), std::move(t))
+    {
+    }
+
+    template<class Subscriber>
+    void on_subscribe(const Subscriber& s) const {
+
+        typedef Subscriber output_type;
+        struct state_type
+            : public std::enable_shared_from_this<state_type>
+            , public values
+        {
+            state_type(const values& i, const output_type& oarg)
+                : values(i)
+                , source_lifetime(composite_subscription::empty())
+                , out(oarg)
+            {
+            }
+            composite_subscription source_lifetime;
+            output_type out;
+
+            void do_subscribe() {
+                auto state = this->shared_from_this();
+
+                state->source_lifetime = composite_subscription();
+                state->out.add(state->source_lifetime);
+
+                state->source.subscribe(
+                    state->out,
+                    state->source_lifetime,
+                // on_next
+                    [state](T t) {
+                        state->out.on_next(t);
+                    },
+                // on_error
+                    [state](std::exception_ptr e) {
+                        state->out.on_error(e);
+                    },
+                // on_completed
+                    [state]() {
+                        if (state->repeat_infinitely || (--state->remaining > 0)) {
+                            state->do_subscribe();
+                        } else {
+                            state->out.on_completed();
+                        }
+                    }
+                );
+            }
+        };
+
+        // take a copy of the values for each subscription
+        auto state = std::shared_ptr<state_type>(new state_type(initial, s));
+
+        // start the first iteration
+        state->do_subscribe();
+    }
+};
+
+template<class T>
+class repeat_factory
+{
+    typedef typename std::decay<T>::type count_type;
+    count_type count;
+public:
+    repeat_factory(count_type t) : count(std::move(t)) {}
+
+    template<class Observable>
+    auto operator()(Observable&& source)
+        ->      observable<typename std::decay<Observable>::type::value_type, repeat<typename std::decay<Observable>::type::value_type, Observable, count_type>> {
+        return  observable<typename std::decay<Observable>::type::value_type, repeat<typename std::decay<Observable>::type::value_type, Observable, count_type>>(
+                                                                              repeat<typename std::decay<Observable>::type::value_type, Observable, count_type>(std::forward<Observable>(source), count));
+    }
+};
+
+}
+
+template<class T>
+auto repeat(T&& t)
+->      detail::repeat_factory<T> {
+    return  detail::repeat_factory<T>(std::forward<T>(t));
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/operators/rx-retry.hpp b/dependencies64/RxCpp/include/rxcpp/operators/rx-retry.hpp
new file mode 100644 (file)
index 0000000..112edef
--- /dev/null
@@ -0,0 +1,118 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_OPERATORS_RX_RETRY_HPP)
+#define RXCPP_OPERATORS_RX_RETRY_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+    namespace operators {
+
+        namespace detail {
+
+            template<class T, class Observable, class Count>
+            struct retry : public operator_base<T> {
+                typedef typename std::decay<Observable>::type source_type;
+                typedef typename std::decay<Count>::type count_type;
+                struct values {
+                    values(source_type s, count_type t)
+                    : source(std::move(s))
+                    , remaining(std::move(t))
+                    , retry_infinitely(t == 0) {
+                    }
+                    source_type source;
+                    count_type remaining;
+                    bool retry_infinitely;
+                };
+                values initial;
+
+                retry(source_type s, count_type t)
+                    : initial(std::move(s), std::move(t)) {
+                }
+
+                template<class Subscriber>
+                void on_subscribe(const Subscriber& s) const {
+
+                    typedef Subscriber output_type;
+                    struct state_type
+                        : public std::enable_shared_from_this<state_type>
+                        , public values {
+                        state_type(const values& i, const output_type& oarg)
+                        : values(i)
+                        , source_lifetime(composite_subscription::empty())
+                        , out(oarg) {
+                        }
+                        composite_subscription source_lifetime;
+                        output_type out;
+
+                        void do_subscribe() {
+                            auto state = this->shared_from_this();
+
+                            state->source_lifetime = composite_subscription();
+                            state->out.add(state->source_lifetime);
+
+                            state->source.subscribe(
+                                state->out,
+                                state->source_lifetime,
+                                // on_next
+                                [state](T t) {
+                                state->out.on_next(t);
+                            },
+                                // on_error
+                                [state](std::exception_ptr e) {
+                                if (state->retry_infinitely || (--state->remaining >= 0)) {
+                                    state->do_subscribe();
+                                } else {
+                                    state->out.on_error(e);
+                                }
+                            },
+                                // on_completed
+                                [state]() {
+
+                                    // JEP: never appeears to be called?
+
+                                    state->out.on_completed();
+                            }
+                            );
+                        }
+                    };
+
+                    // take a copy of the values for each subscription
+                    auto state = std::shared_ptr<state_type>(new state_type(initial, s));
+
+                    // start the first iteration
+                    state->do_subscribe();
+                }
+            };
+
+            template<class T>
+            class retry_factory {
+                typedef typename std::decay<T>::type count_type;
+                count_type count;
+            public:
+                retry_factory(count_type t) : count(std::move(t)) {}
+
+                template<class Observable>
+                auto operator()(Observable&& source)
+                    ->      observable<typename std::decay<Observable>::type::value_type, retry<typename std::decay<Observable>::type::value_type, Observable, count_type>> {
+                    return  observable<typename std::decay<Observable>::type::value_type, retry<typename std::decay<Observable>::type::value_type, Observable, count_type>>(
+                        retry<typename std::decay<Observable>::type::value_type, Observable, count_type>(std::forward<Observable>(source), count));
+                }
+            };
+
+        }
+
+        template<class T>
+        auto retry(T&& t)
+            ->      detail::retry_factory<T> {
+            return  detail::retry_factory<T>(std::forward<T>(t));
+        }
+
+    }
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/operators/rx-scan.hpp b/dependencies64/RxCpp/include/rxcpp/operators/rx-scan.hpp
new file mode 100644 (file)
index 0000000..12c4b2f
--- /dev/null
@@ -0,0 +1,122 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_OPERATORS_RX_SCAN_HPP)
+#define RXCPP_OPERATORS_RX_SCAN_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace operators {
+
+namespace detail {
+
+template<class T, class Observable, class Accumulator, class Seed>
+struct scan : public operator_base<typename std::decay<Seed>::type>
+{
+    typedef typename std::decay<Observable>::type source_type;
+    typedef typename std::decay<Accumulator>::type accumulator_type;
+    typedef typename std::decay<Seed>::type seed_type;
+
+    struct scan_initial_type
+    {
+        scan_initial_type(source_type o, accumulator_type a, seed_type s)
+            : source(std::move(o))
+            , accumulator(std::move(a))
+            , seed(s)
+        {
+        }
+        source_type source;
+        accumulator_type accumulator;
+        seed_type seed;
+    };
+    scan_initial_type initial;
+
+    template<class CT, class CS, class CP>
+    static auto check(int) -> decltype((*(CP*)nullptr)(*(CS*)nullptr, *(CT*)nullptr));
+    template<class CT, class CS, class CP>
+    static void check(...);
+
+    scan(source_type o, accumulator_type a, seed_type s)
+        : initial(std::move(o), a, s)
+    {
+        static_assert(std::is_convertible<decltype(check<T, seed_type, accumulator_type>(0)), seed_type>::value, "scan Accumulator must be a function with the signature Seed(Seed, T)");
+    }
+    template<class Subscriber>
+    void on_subscribe(Subscriber o) {
+        struct scan_state_type
+            : public scan_initial_type
+            , public std::enable_shared_from_this<scan_state_type>
+        {
+            scan_state_type(scan_initial_type i, Subscriber scrbr)
+                : scan_initial_type(i)
+                , result(scan_initial_type::seed)
+                , out(std::move(scrbr))
+            {
+            }
+            seed_type result;
+            Subscriber out;
+        };
+        auto state = std::make_shared<scan_state_type>(initial, std::move(o));
+        state->source.subscribe(
+            state->out,
+        // on_next
+            [state](T t) {
+                auto result = on_exception(
+                    [&](){return state->accumulator(state->result, t);},
+                    state->out);
+                if (result.empty()) {
+                    return;
+                }
+                state->result = result.get();
+                state->out.on_next(state->result);
+            },
+        // on_error
+            [state](std::exception_ptr e) {
+                state->out.on_error(e);
+            },
+        // on_completed
+            [state]() {
+                state->out.on_completed();
+            }
+        );
+    }
+};
+
+template<class Accumulator, class Seed>
+class scan_factory
+{
+    typedef typename std::decay<Accumulator>::type accumulator_type;
+    typedef typename std::decay<Seed>::type seed_type;
+
+    accumulator_type accumulator;
+    seed_type seed;
+public:
+    scan_factory(accumulator_type a, Seed s)
+        : accumulator(std::move(a))
+        , seed(s)
+    {
+    }
+    template<class Observable>
+    auto operator()(Observable&& source)
+        ->      observable<typename std::decay<Seed>::type, scan<typename std::decay<Observable>::type::value_type, Observable, Accumulator, Seed>> {
+        return  observable<typename std::decay<Seed>::type, scan<typename std::decay<Observable>::type::value_type, Observable, Accumulator, Seed>>(
+                                                            scan<typename std::decay<Observable>::type::value_type, Observable, Accumulator, Seed>(std::forward<Observable>(source), accumulator, seed));
+    }
+};
+
+}
+
+template<class Seed, class Accumulator>
+auto scan(Seed s, Accumulator&& a)
+    ->      detail::scan_factory<Accumulator, Seed> {
+    return  detail::scan_factory<Accumulator, Seed>(std::forward<Accumulator>(a), s);
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/operators/rx-skip.hpp b/dependencies64/RxCpp/include/rxcpp/operators/rx-skip.hpp
new file mode 100644 (file)
index 0000000..3fa7209
--- /dev/null
@@ -0,0 +1,126 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_OPERATORS_RX_SKIP_HPP)
+#define RXCPP_OPERATORS_RX_SKIP_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace operators {
+
+namespace detail {
+
+template<class T, class Observable, class Count>
+struct skip : public operator_base<T>
+{
+    typedef typename std::decay<Observable>::type source_type;
+    typedef typename std::decay<Count>::type count_type;
+    struct values
+    {
+        values(source_type s, count_type t)
+            : source(std::move(s))
+            , count(std::move(t))
+        {
+        }
+        source_type source;
+        count_type count;
+    };
+    values initial;
+
+    skip(source_type s, count_type t)
+        : initial(std::move(s), std::move(t))
+    {
+    }
+
+    struct mode
+    {
+        enum type {
+            skipping,  // ignore messages
+            triggered, // capture messages
+            errored,   // error occured
+            stopped    // observable completed
+        };
+    };
+
+    template<class Subscriber>
+    void on_subscribe(const Subscriber& s) const {
+
+        typedef Subscriber output_type;
+        struct state_type
+            : public std::enable_shared_from_this<state_type>
+            , public values
+        {
+            state_type(const values& i, const output_type& oarg)
+                : values(i)
+                , mode_value(i.count > 0 ? mode::skipping : mode::triggered)
+                , out(oarg)
+            {
+            }
+            typename mode::type mode_value;
+            output_type out;
+        };
+        // take a copy of the values for each subscription
+        auto state = std::shared_ptr<state_type>(new state_type(initial, s));
+
+        composite_subscription source_lifetime;
+
+        s.add(source_lifetime);
+
+        state->source.subscribe(
+        // split subscription lifetime
+            source_lifetime,
+        // on_next
+            [state](T t) {
+                if (state->mode_value == mode::skipping) {
+                    if (--state->count == 0) {
+                        state->mode_value = mode::triggered;
+                    }
+                } else {
+                    state->out.on_next(t);
+                }
+            },
+        // on_error
+            [state](std::exception_ptr e) {
+                state->mode_value = mode::errored;
+                state->out.on_error(e);
+            },
+        // on_completed
+            [state]() {
+                state->mode_value = mode::stopped;
+                state->out.on_completed();
+            }
+        );
+    }
+};
+
+template<class T>
+class skip_factory
+{
+    typedef typename std::decay<T>::type count_type;
+    count_type count;
+public:
+    skip_factory(count_type t) : count(std::move(t)) {}
+    template<class Observable>
+    auto operator()(Observable&& source)
+        ->      observable<typename std::decay<Observable>::type::value_type, skip<typename std::decay<Observable>::type::value_type, Observable, count_type>> {
+        return  observable<typename std::decay<Observable>::type::value_type, skip<typename std::decay<Observable>::type::value_type, Observable, count_type>>(
+                                                                              skip<typename std::decay<Observable>::type::value_type, Observable, count_type>(std::forward<Observable>(source), count));
+    }
+};
+
+}
+
+template<class T>
+auto skip(T&& t)
+    ->      detail::skip_factory<T> {
+    return  detail::skip_factory<T>(std::forward<T>(t));
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/operators/rx-skip_until.hpp b/dependencies64/RxCpp/include/rxcpp/operators/rx-skip_until.hpp
new file mode 100644 (file)
index 0000000..49441e4
--- /dev/null
@@ -0,0 +1,198 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_OPERATORS_RX_SKIP_UNTIL_HPP)
+#define RXCPP_OPERATORS_RX_SKIP_UNTIL_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace operators {
+
+namespace detail {
+
+template<class T, class Observable, class TriggerObservable, class Coordination>
+struct skip_until : public operator_base<T>
+{
+    typedef typename std::decay<Observable>::type source_type;
+    typedef typename std::decay<TriggerObservable>::type trigger_source_type;
+    typedef typename std::decay<Coordination>::type coordination_type;
+    typedef typename coordination_type::coordinator_type coordinator_type;
+    struct values
+    {
+        values(source_type s, trigger_source_type t, coordination_type sf)
+            : source(std::move(s))
+            , trigger(std::move(t))
+            , coordination(std::move(sf))
+        {
+        }
+        source_type source;
+        trigger_source_type trigger;
+        coordination_type coordination;
+    };
+    values initial;
+
+    skip_until(source_type s, trigger_source_type t, coordination_type sf)
+        : initial(std::move(s), std::move(t), std::move(sf))
+    {
+    }
+
+    struct mode
+    {
+        enum type {
+            skipping,  // no messages from trigger
+            clear,     // trigger completed
+            triggered, // trigger sent on_next
+            errored,   // error either on trigger or on observable
+            stopped    // observable completed
+        };
+    };
+
+    template<class Subscriber>
+    void on_subscribe(Subscriber s) const {
+
+        typedef Subscriber output_type;
+        struct state_type
+            : public std::enable_shared_from_this<state_type>
+            , public values
+        {
+            state_type(const values& i, coordinator_type coor, const output_type& oarg)
+                : values(i)
+                , mode_value(mode::skipping)
+                , coordinator(std::move(coor))
+                , out(oarg)
+            {
+                out.add(trigger_lifetime);
+                out.add(source_lifetime);
+            }
+            typename mode::type mode_value;
+            composite_subscription trigger_lifetime;
+            composite_subscription source_lifetime;
+            coordinator_type coordinator;
+            output_type out;
+        };
+
+        auto coordinator = initial.coordination.create_coordinator();
+
+        // take a copy of the values for each subscription
+        auto state = std::shared_ptr<state_type>(new state_type(initial, std::move(coordinator), std::move(s)));
+
+        auto trigger = on_exception(
+            [&](){return state->coordinator.in(state->trigger);},
+            state->out);
+        if (trigger.empty()) {
+            return;
+        }
+
+        auto source = on_exception(
+            [&](){return state->coordinator.in(state->source);},
+            state->out);
+        if (source.empty()) {
+            return;
+        }
+
+        auto sinkTrigger = make_subscriber<typename trigger_source_type::value_type>(
+        // share parts of subscription
+            state->out,
+        // new lifetime
+            state->trigger_lifetime,
+        // on_next
+            [state](const typename trigger_source_type::value_type&) {
+                if (state->mode_value != mode::skipping) {
+                    return;
+                }
+                state->mode_value = mode::triggered;
+                state->trigger_lifetime.unsubscribe();
+            },
+        // on_error
+            [state](std::exception_ptr e) {
+                if (state->mode_value != mode::skipping) {
+                    return;
+                }
+                state->mode_value = mode::errored;
+                state->out.on_error(e);
+            },
+        // on_completed
+            [state]() {
+                if (state->mode_value != mode::skipping) {
+                    return;
+                }
+                state->mode_value = mode::clear;
+                state->trigger_lifetime.unsubscribe();
+            }
+        );
+        auto selectedSinkTrigger = on_exception(
+            [&](){return state->coordinator.out(sinkTrigger);},
+            state->out);
+        if (selectedSinkTrigger.empty()) {
+            return;
+        }
+        trigger->subscribe(std::move(selectedSinkTrigger.get()));
+
+        source.get().subscribe(
+        // split subscription lifetime
+            state->source_lifetime,
+        // on_next
+            [state](T t) {
+                if (state->mode_value != mode::triggered) {
+                    return;
+                }
+                state->out.on_next(t);
+            },
+        // on_error
+            [state](std::exception_ptr e) {
+                if (state->mode_value > mode::triggered) {
+                    return;
+                }
+                state->mode_value = mode::errored;
+                state->out.on_error(e);
+            },
+        // on_completed
+            [state]() {
+                if (state->mode_value != mode::triggered) {
+                    return;
+                }
+                state->mode_value = mode::stopped;
+                state->out.on_completed();
+            }
+        );
+    }
+};
+
+template<class TriggerObservable, class Coordination>
+class skip_until_factory
+{
+    typedef typename std::decay<TriggerObservable>::type trigger_source_type;
+    typedef typename std::decay<Coordination>::type coordination_type;
+
+    trigger_source_type trigger_source;
+    coordination_type coordination;
+public:
+    skip_until_factory(trigger_source_type t, coordination_type sf)
+        : trigger_source(std::move(t))
+        , coordination(std::move(sf))
+    {
+    }
+    template<class Observable>
+    auto operator()(Observable&& source)
+        ->      observable<typename std::decay<Observable>::type::value_type, skip_until<typename std::decay<Observable>::type::value_type, Observable, trigger_source_type, Coordination>> {
+        return  observable<typename std::decay<Observable>::type::value_type, skip_until<typename std::decay<Observable>::type::value_type, Observable, trigger_source_type, Coordination>>(
+                                                                              skip_until<typename std::decay<Observable>::type::value_type, Observable, trigger_source_type, Coordination>(std::forward<Observable>(source), trigger_source, coordination));
+    }
+};
+
+}
+
+template<class TriggerObservable, class Coordination>
+auto skip_until(TriggerObservable&& t, Coordination&& sf)
+    ->      detail::skip_until_factory<TriggerObservable, Coordination> {
+    return  detail::skip_until_factory<TriggerObservable, Coordination>(std::forward<TriggerObservable>(t), std::forward<Coordination>(sf));
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/operators/rx-start_with.hpp b/dependencies64/RxCpp/include/rxcpp/operators/rx-start_with.hpp
new file mode 100644 (file)
index 0000000..d605ceb
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_OPERATORS_RX_START_WITH_HPP)
+#define RXCPP_OPERATORS_RX_START_WITH_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace operators {
+
+template<class Observable, class Value0, class... ValueN>
+auto start_with(Observable o, Value0 v0, ValueN... vn)
+    -> decltype(rxs::from(typename Observable::value_type(v0), typename Observable::value_type(vn)...).concat(o)) {
+    return      rxs::from(typename Observable::value_type(v0), typename Observable::value_type(vn)...).concat(o);
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/operators/rx-subscribe.hpp b/dependencies64/RxCpp/include/rxcpp/operators/rx-subscribe.hpp
new file mode 100644 (file)
index 0000000..cc25c1d
--- /dev/null
@@ -0,0 +1,96 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_OPERATORS_RX_SUBSCRIBE_HPP)
+#define RXCPP_OPERATORS_RX_SUBSCRIBE_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace operators {
+
+namespace detail {
+
+template<class Subscriber>
+class subscribe_factory;
+
+template<class T, class I>
+class subscribe_factory<subscriber<T, I>>
+{
+    subscriber<T, I> scrbr;
+public:
+    subscribe_factory(subscriber<T, I> s)
+        : scrbr(std::move(s))
+    {}
+    template<class Observable>
+    auto operator()(Observable&& source)
+        -> decltype(std::forward<Observable>(source).subscribe(std::move(scrbr))) {
+        return      std::forward<Observable>(source).subscribe(std::move(scrbr));
+    }
+};
+
+}
+
+template<class T, class Arg0>
+auto subscribe(Arg0&& a0)
+    ->      detail::subscribe_factory<decltype  (make_subscriber<T>(std::forward<Arg0>(a0)))> {
+    return  detail::subscribe_factory<decltype  (make_subscriber<T>(std::forward<Arg0>(a0)))>
+                                        (make_subscriber<T>(std::forward<Arg0>(a0)));
+}
+template<class T, class Arg0, class Arg1>
+auto subscribe(Arg0&& a0, Arg1&& a1)
+    ->      detail::subscribe_factory<decltype  (make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1)))> {
+    return  detail::subscribe_factory<decltype  (make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1)))>
+                                        (make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1)));
+}
+template<class T, class Arg0, class Arg1, class Arg2>
+auto subscribe(Arg0&& a0, Arg1&& a1, Arg2&& a2)
+    ->      detail::subscribe_factory<decltype  (make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2)))> {
+    return  detail::subscribe_factory<decltype  (make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2)))>
+                                        (make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2)));
+}
+template<class T, class Arg0, class Arg1, class Arg2, class Arg3>
+auto subscribe(Arg0&& a0, Arg1&& a1, Arg2&& a2, Arg3&& a3)
+    ->      detail::subscribe_factory<decltype  (make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3)))> {
+    return  detail::subscribe_factory<decltype  (make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3)))>
+                                        (make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3)));
+}
+template<class T, class Arg0, class Arg1, class Arg2, class Arg3, class Arg4>
+auto subscribe(Arg0&& a0, Arg1&& a1, Arg2&& a2, Arg3&& a3, Arg4&& a4)
+    ->      detail::subscribe_factory<decltype  (make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4)))> {
+    return  detail::subscribe_factory<decltype  (make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4)))>
+                                        (make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4)));
+}
+template<class T, class Arg0, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5>
+auto subscribe(Arg0&& a0, Arg1&& a1, Arg2&& a2, Arg3&& a3, Arg4&& a4, Arg5&& a5)
+    ->      detail::subscribe_factory<decltype  (make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4), std::forward<Arg5>(a5)))> {
+    return  detail::subscribe_factory<decltype  (make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4), std::forward<Arg5>(a5)))>
+                                        (make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4), std::forward<Arg5>(a5)));
+}
+
+namespace detail {
+
+class dynamic_factory
+{
+public:
+    template<class Observable>
+    auto operator()(Observable&& source)
+        ->      observable<typename std::decay<Observable>::type::value_type> {
+        return  observable<typename std::decay<Observable>::type::value_type>(std::forward<Observable>(source));
+    }
+};
+
+}
+
+inline auto as_dynamic()
+    ->      detail::dynamic_factory {
+    return  detail::dynamic_factory();
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/operators/rx-subscribe_on.hpp b/dependencies64/RxCpp/include/rxcpp/operators/rx-subscribe_on.hpp
new file mode 100644 (file)
index 0000000..e62e8ff
--- /dev/null
@@ -0,0 +1,135 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_OPERATORS_RX_SUBSCRIBE_ON_HPP)
+#define RXCPP_OPERATORS_RX_SUBSCRIBE_ON_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace operators {
+
+namespace detail {
+
+template<class T, class Observable, class Coordination>
+struct subscribe_on : public operator_base<T>
+{
+    typedef typename std::decay<Observable>::type source_type;
+    typedef typename std::decay<Coordination>::type coordination_type;
+    typedef typename coordination_type::coordinator_type coordinator_type;
+    struct subscribe_on_values
+    {
+        ~subscribe_on_values()
+        {
+        }
+        subscribe_on_values(source_type s, coordination_type sf)
+            : source(std::move(s))
+            , coordination(std::move(sf))
+        {
+        }
+        source_type source;
+        coordination_type coordination;
+    };
+    const subscribe_on_values initial;
+
+    ~subscribe_on()
+    {
+    }
+    subscribe_on(source_type s, coordination_type sf)
+        : initial(std::move(s), std::move(sf))
+    {
+    }
+
+    template<class Subscriber>
+    void on_subscribe(Subscriber s) const {
+
+        typedef Subscriber output_type;
+        struct subscribe_on_state_type
+            : public std::enable_shared_from_this<subscribe_on_state_type>
+            , public subscribe_on_values
+        {
+            subscribe_on_state_type(const subscribe_on_values& i, coordinator_type coor, const output_type& oarg)
+                : subscribe_on_values(i)
+                , coordinator(std::move(coor))
+                , out(oarg)
+            {
+            }
+            composite_subscription source_lifetime;
+            coordinator_type coordinator;
+            output_type out;
+        };
+
+        auto coordinator = initial.coordination.create_coordinator(s.get_subscription());
+
+        auto controller = coordinator.get_worker();
+
+        // take a copy of the values for each subscription
+        auto state = std::shared_ptr<subscribe_on_state_type>(new subscribe_on_state_type(initial, std::move(coordinator), std::move(s)));
+
+        auto disposer = [=](const rxsc::schedulable&){
+            state->source_lifetime.unsubscribe();
+            state->out.unsubscribe();
+        };
+        auto selectedDisposer = on_exception(
+            [&](){return state->coordinator.act(disposer);},
+            state->out);
+        if (selectedDisposer.empty()) {
+            return;
+        }
+
+        state->out.add([=](){
+            controller.schedule(selectedDisposer.get());
+        });
+        state->source_lifetime.add([=](){
+            controller.schedule(selectedDisposer.get());
+        });
+
+        auto producer = [=](const rxsc::schedulable&){
+            state->source.subscribe(state->source_lifetime, state->out);
+        };
+
+        auto selectedProducer = on_exception(
+            [&](){return state->coordinator.act(producer);},
+            state->out);
+        if (selectedProducer.empty()) {
+            return;
+        }
+
+        controller.schedule(selectedProducer.get());
+    }
+};
+
+template<class Coordination>
+class subscribe_on_factory
+{
+    typedef typename std::decay<Coordination>::type coordination_type;
+
+    coordination_type coordination;
+public:
+    subscribe_on_factory(coordination_type sf)
+        : coordination(std::move(sf))
+    {
+    }
+    template<class Observable>
+    auto operator()(Observable&& source)
+        ->      observable<typename std::decay<Observable>::type::value_type,   subscribe_on<typename std::decay<Observable>::type::value_type, Observable, Coordination>> {
+        return  observable<typename std::decay<Observable>::type::value_type,   subscribe_on<typename std::decay<Observable>::type::value_type, Observable, Coordination>>(
+                                                                                subscribe_on<typename std::decay<Observable>::type::value_type, Observable, Coordination>(std::forward<Observable>(source), coordination));
+    }
+};
+
+}
+
+template<class Coordination>
+auto subscribe_on(Coordination sf)
+    ->      detail::subscribe_on_factory<Coordination> {
+    return  detail::subscribe_on_factory<Coordination>(std::move(sf));
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/operators/rx-switch_on_next.hpp b/dependencies64/RxCpp/include/rxcpp/operators/rx-switch_on_next.hpp
new file mode 100644 (file)
index 0000000..3403553
--- /dev/null
@@ -0,0 +1,215 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_OPERATORS_RX_SWITCH_ON_NEXT_HPP)
+#define RXCPP_OPERATORS_RX_SWITCH_ON_NEXT_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace operators {
+
+namespace detail {
+
+template<class T, class Observable, class Coordination>
+struct switch_on_next
+    : public operator_base<typename std::decay<T>::type::value_type>
+{
+    //static_assert(is_observable<Observable>::value, "switch_on_next requires an observable");
+    //static_assert(is_observable<T>::value, "switch_on_next requires an observable that contains observables");
+
+    typedef switch_on_next<T, Observable, Coordination> this_type;
+
+    typedef typename std::decay<T>::type source_value_type;
+    typedef typename std::decay<Observable>::type source_type;
+
+    typedef typename source_type::source_operator_type source_operator_type;
+
+    typedef source_value_type collection_type;
+    typedef typename collection_type::value_type collection_value_type;
+
+    typedef typename std::decay<Coordination>::type coordination_type;
+    typedef typename coordination_type::coordinator_type coordinator_type;
+
+    struct values
+    {
+        values(source_operator_type o, coordination_type sf)
+            : source_operator(std::move(o))
+            , coordination(std::move(sf))
+        {
+        }
+        source_operator_type source_operator;
+        coordination_type coordination;
+    };
+    values initial;
+
+    switch_on_next(const source_type& o, coordination_type sf)
+        : initial(o.source_operator, std::move(sf))
+    {
+    }
+
+    template<class Subscriber>
+    void on_subscribe(Subscriber scbr) const {
+        static_assert(is_subscriber<Subscriber>::value, "subscribe must be passed a subscriber");
+
+        typedef Subscriber output_type;
+
+        struct switch_state_type
+            : public std::enable_shared_from_this<switch_state_type>
+            , public values
+        {
+            switch_state_type(values i, coordinator_type coor, output_type oarg)
+                : values(i)
+                , source(i.source_operator)
+                , pendingCompletions(0)
+                , coordinator(std::move(coor))
+                , out(std::move(oarg))
+            {
+            }
+            observable<source_value_type, source_operator_type> source;
+            // on_completed on the output must wait until all the
+            // subscriptions have received on_completed
+            int pendingCompletions;
+            coordinator_type coordinator;
+            composite_subscription inner_lifetime;
+            output_type out;
+        };
+
+        auto coordinator = initial.coordination.create_coordinator(scbr.get_subscription());
+
+        // take a copy of the values for each subscription
+        auto state = std::shared_ptr<switch_state_type>(new switch_state_type(initial, std::move(coordinator), std::move(scbr)));
+
+        composite_subscription outercs;
+
+        // when the out observer is unsubscribed all the
+        // inner subscriptions are unsubscribed as well
+        state->out.add(outercs);
+
+        auto source = on_exception(
+            [&](){return state->coordinator.in(state->source);},
+            state->out);
+        if (source.empty()) {
+            return;
+        }
+
+        ++state->pendingCompletions;
+        // this subscribe does not share the observer subscription
+        // so that when it is unsubscribed the observer can be called
+        // until the inner subscriptions have finished
+        auto sink = make_subscriber<collection_type>(
+            state->out,
+            outercs,
+        // on_next
+            [state](collection_type st) {
+
+                state->inner_lifetime.unsubscribe();
+
+                state->inner_lifetime = composite_subscription();
+
+                // when the out observer is unsubscribed all the
+                // inner subscriptions are unsubscribed as well
+                auto innerlifetimetoken = state->out.add(state->inner_lifetime);
+
+                state->inner_lifetime.add(make_subscription([state, innerlifetimetoken](){
+                    state->out.remove(innerlifetimetoken);
+                    --state->pendingCompletions;
+                }));
+
+                auto selectedSource = on_exception(
+                    [&](){return state->coordinator.in(st);},
+                    state->out);
+                if (selectedSource.empty()) {
+                    return;
+                }
+
+                // this subscribe does not share the source subscription
+                // so that when it is unsubscribed the source will continue
+                auto sinkInner = make_subscriber<collection_value_type>(
+                    state->out,
+                    state->inner_lifetime,
+                // on_next
+                    [state, st](collection_value_type ct) {
+                        state->out.on_next(std::move(ct));
+                    },
+                // on_error
+                    [state](std::exception_ptr e) {
+                        state->out.on_error(e);
+                    },
+                //on_completed
+                    [state](){
+                        if (state->pendingCompletions == 1) {
+                            state->out.on_completed();
+                        }
+                    }
+                );
+
+                auto selectedSinkInner = on_exception(
+                    [&](){return state->coordinator.out(sinkInner);},
+                    state->out);
+                if (selectedSinkInner.empty()) {
+                    return;
+                }
+
+                ++state->pendingCompletions;
+                selectedSource->subscribe(std::move(selectedSinkInner.get()));
+            },
+        // on_error
+            [state](std::exception_ptr e) {
+                state->out.on_error(e);
+            },
+        // on_completed
+            [state]() {
+                if (--state->pendingCompletions == 0) {
+                    state->out.on_completed();
+                }
+            }
+        );
+
+        auto selectedSink = on_exception(
+            [&](){return state->coordinator.out(sink);},
+            state->out);
+        if (selectedSink.empty()) {
+            return;
+        }
+
+        source->subscribe(std::move(selectedSink.get()));
+
+    }
+};
+
+template<class Coordination>
+class switch_on_next_factory
+{
+    typedef typename std::decay<Coordination>::type coordination_type;
+
+    coordination_type coordination;
+public:
+    switch_on_next_factory(coordination_type sf)
+        : coordination(std::move(sf))
+    {
+    }
+
+    template<class Observable>
+    auto operator()(Observable source)
+        ->      observable<typename switch_on_next<typename Observable::value_type, Observable, Coordination>::value_type,  switch_on_next<typename Observable::value_type, Observable, Coordination>> {
+        return  observable<typename switch_on_next<typename Observable::value_type, Observable, Coordination>::value_type,  switch_on_next<typename Observable::value_type, Observable, Coordination>>(
+                                                                                                                            switch_on_next<typename Observable::value_type, Observable, Coordination>(std::move(source), coordination));
+    }
+};
+
+}
+
+template<class Coordination>
+auto switch_on_next(Coordination&& sf)
+    ->      detail::switch_on_next_factory<Coordination> {
+    return  detail::switch_on_next_factory<Coordination>(std::forward<Coordination>(sf));
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/operators/rx-take.hpp b/dependencies64/RxCpp/include/rxcpp/operators/rx-take.hpp
new file mode 100644 (file)
index 0000000..5043385
--- /dev/null
@@ -0,0 +1,130 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_OPERATORS_RX_TAKE_HPP)
+#define RXCPP_OPERATORS_RX_TAKE_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace operators {
+
+namespace detail {
+
+template<class T, class Observable, class Count>
+struct take : public operator_base<T>
+{
+    typedef typename std::decay<Observable>::type source_type;
+    typedef typename std::decay<Count>::type count_type;
+    struct values
+    {
+        values(source_type s, count_type t)
+            : source(std::move(s))
+            , count(std::move(t))
+        {
+        }
+        source_type source;
+        count_type count;
+    };
+    values initial;
+
+    take(source_type s, count_type t)
+        : initial(std::move(s), std::move(t))
+    {
+    }
+
+    struct mode
+    {
+        enum type {
+            taking,    // capture messages
+            triggered, // ignore messages
+            errored,   // error occured
+            stopped    // observable completed
+        };
+    };
+
+    template<class Subscriber>
+    void on_subscribe(const Subscriber& s) const {
+
+        typedef Subscriber output_type;
+        struct state_type
+            : public std::enable_shared_from_this<state_type>
+            , public values
+        {
+            state_type(const values& i, const output_type& oarg)
+                : values(i)
+                , mode_value(mode::taking)
+                , out(oarg)
+            {
+            }
+            typename mode::type mode_value;
+            output_type out;
+        };
+        // take a copy of the values for each subscription
+        auto state = std::shared_ptr<state_type>(new state_type(initial, s));
+
+        composite_subscription source_lifetime;
+
+        s.add(source_lifetime);
+
+        state->source.subscribe(
+        // split subscription lifetime
+            source_lifetime,
+        // on_next
+            [state, source_lifetime](T t) {
+                if (state->mode_value < mode::triggered) {
+                    if (--state->count > 0) {
+                        state->out.on_next(t);
+                    } else {
+                        state->mode_value = mode::triggered;
+                        state->out.on_next(t);
+                        // must shutdown source before signaling completion
+                        source_lifetime.unsubscribe();
+                        state->out.on_completed();
+                    }
+                }
+            },
+        // on_error
+            [state](std::exception_ptr e) {
+                state->mode_value = mode::errored;
+                state->out.on_error(e);
+            },
+        // on_completed
+            [state]() {
+                state->mode_value = mode::stopped;
+                state->out.on_completed();
+            }
+        );
+    }
+};
+
+template<class T>
+class take_factory
+{
+    typedef typename std::decay<T>::type count_type;
+    count_type count;
+public:
+    take_factory(count_type t) : count(std::move(t)) {}
+    template<class Observable>
+    auto operator()(Observable&& source)
+        ->      observable<typename std::decay<Observable>::type::value_type,   take<typename std::decay<Observable>::type::value_type, Observable, count_type>> {
+        return  observable<typename std::decay<Observable>::type::value_type,   take<typename std::decay<Observable>::type::value_type, Observable, count_type>>(
+                                                                                take<typename std::decay<Observable>::type::value_type, Observable, count_type>(std::forward<Observable>(source), count));
+    }
+};
+
+}
+
+template<class T>
+auto take(T&& t)
+    ->      detail::take_factory<T> {
+    return  detail::take_factory<T>(std::forward<T>(t));
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/operators/rx-take_until.hpp b/dependencies64/RxCpp/include/rxcpp/operators/rx-take_until.hpp
new file mode 100644 (file)
index 0000000..b1fb8ff
--- /dev/null
@@ -0,0 +1,196 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_OPERATORS_RX_TAKE_UNTIL_HPP)
+#define RXCPP_OPERATORS_RX_TAKE_UNTIL_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace operators {
+
+namespace detail {
+
+template<class T, class Observable, class TriggerObservable, class Coordination>
+struct take_until : public operator_base<T>
+{
+    typedef typename std::decay<Observable>::type source_type;
+    typedef typename std::decay<TriggerObservable>::type trigger_source_type;
+    typedef typename std::decay<Coordination>::type coordination_type;
+    typedef typename coordination_type::coordinator_type coordinator_type;
+    struct values
+    {
+        values(source_type s, trigger_source_type t, coordination_type sf)
+            : source(std::move(s))
+            , trigger(std::move(t))
+            , coordination(std::move(sf))
+        {
+        }
+        source_type source;
+        trigger_source_type trigger;
+        coordination_type coordination;
+    };
+    values initial;
+
+    take_until(source_type s, trigger_source_type t, coordination_type sf)
+        : initial(std::move(s), std::move(t), std::move(sf))
+    {
+    }
+
+    struct mode
+    {
+        enum type {
+            taking,    // no messages from trigger
+            clear,     // trigger completed
+            triggered, // trigger sent on_next
+            errored,   // error either on trigger or on observable
+            stopped    // observable completed
+        };
+    };
+
+    template<class Subscriber>
+    void on_subscribe(Subscriber s) const {
+
+        typedef Subscriber output_type;
+        struct take_until_state_type
+            : public std::enable_shared_from_this<take_until_state_type>
+            , public values
+        {
+            take_until_state_type(const values& i, coordinator_type coor, const output_type& oarg)
+                : values(i)
+                , mode_value(mode::taking)
+                , coordinator(std::move(coor))
+                , out(oarg)
+            {
+                out.add(trigger_lifetime);
+                out.add(source_lifetime);
+            }
+            typename mode::type mode_value;
+            composite_subscription trigger_lifetime;
+            composite_subscription source_lifetime;
+            coordinator_type coordinator;
+            output_type out;
+        };
+
+        auto coordinator = initial.coordination.create_coordinator(s.get_subscription());
+
+        // take a copy of the values for each subscription
+        auto state = std::shared_ptr<take_until_state_type>(new take_until_state_type(initial, std::move(coordinator), std::move(s)));
+
+        auto trigger = on_exception(
+            [&](){return state->coordinator.in(state->trigger);},
+            state->out);
+        if (trigger.empty()) {
+            return;
+        }
+
+        auto source = on_exception(
+            [&](){return state->coordinator.in(state->source);},
+            state->out);
+        if (source.empty()) {
+            return;
+        }
+
+        auto sinkTrigger = make_subscriber<typename trigger_source_type::value_type>(
+        // share parts of subscription
+            state->out,
+        // new lifetime
+            state->trigger_lifetime,
+        // on_next
+            [state](const typename trigger_source_type::value_type&) {
+                if (state->mode_value != mode::taking) {return;}
+                state->mode_value = mode::triggered;
+                state->out.on_completed();
+            },
+        // on_error
+            [state](std::exception_ptr e) {
+                if (state->mode_value != mode::taking) {return;}
+                state->mode_value = mode::errored;
+                state->out.on_error(e);
+            },
+        // on_completed
+            [state]() {
+                if (state->mode_value != mode::taking) {return;}
+                state->mode_value = mode::clear;
+            }
+        );
+        auto selectedSinkTrigger = on_exception(
+            [&](){return state->coordinator.out(sinkTrigger);},
+            state->out);
+        if (selectedSinkTrigger.empty()) {
+            return;
+        }
+        trigger->subscribe(std::move(selectedSinkTrigger.get()));
+
+        auto sinkSource = make_subscriber<T>(
+        // split subscription lifetime
+            state->source_lifetime,
+        // on_next
+            [state](T t) {
+                //
+                // everything is crafted to minimize the overhead of this function.
+                //
+                if (state->mode_value < mode::triggered) {
+                    state->out.on_next(t);
+                }
+            },
+        // on_error
+            [state](std::exception_ptr e) {
+                if (state->mode_value > mode::clear) {return;}
+                state->mode_value = mode::errored;
+                state->out.on_error(e);
+            },
+        // on_completed
+            [state]() {
+                if (state->mode_value > mode::clear) {return;}
+                state->mode_value = mode::stopped;
+                state->out.on_completed();
+            }
+        );
+        auto selectedSinkSource = on_exception(
+            [&](){return state->coordinator.out(sinkSource);},
+            state->out);
+        if (selectedSinkSource.empty()) {
+            return;
+        }
+        source->subscribe(std::move(selectedSinkSource.get()));
+    }
+};
+
+template<class TriggerObservable, class Coordination>
+class take_until_factory
+{
+    typedef typename std::decay<TriggerObservable>::type trigger_source_type;
+    typedef typename std::decay<Coordination>::type coordination_type;
+
+    trigger_source_type trigger_source;
+    coordination_type coordination;
+public:
+    take_until_factory(trigger_source_type t, coordination_type sf)
+        : trigger_source(std::move(t))
+        , coordination(std::move(sf))
+    {
+    }
+    template<class Observable>
+    auto operator()(Observable&& source)
+        ->      observable<typename std::decay<Observable>::type::value_type,   take_until<typename std::decay<Observable>::type::value_type, Observable, trigger_source_type, Coordination>> {
+        return  observable<typename std::decay<Observable>::type::value_type,   take_until<typename std::decay<Observable>::type::value_type, Observable, trigger_source_type, Coordination>>(
+                                                                                take_until<typename std::decay<Observable>::type::value_type, Observable, trigger_source_type, Coordination>(std::forward<Observable>(source), trigger_source, coordination));
+    }
+};
+
+}
+
+template<class TriggerObservable, class Coordination>
+auto take_until(TriggerObservable t, Coordination sf)
+    ->      detail::take_until_factory<TriggerObservable, Coordination> {
+    return  detail::take_until_factory<TriggerObservable, Coordination>(std::move(t), std::move(sf));
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/operators/rx-window.hpp b/dependencies64/RxCpp/include/rxcpp/operators/rx-window.hpp
new file mode 100644 (file)
index 0000000..c2bf220
--- /dev/null
@@ -0,0 +1,130 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_OPERATORS_RX_WINDOW_HPP)
+#define RXCPP_OPERATORS_RX_WINDOW_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace operators {
+
+namespace detail {
+
+template<class T>
+struct window
+{
+    typedef typename std::decay<T>::type source_value_type;
+    struct window_values
+    {
+        window_values(int c, int s)
+            : count(c)
+            , skip(s)
+        {
+        }
+        int count;
+        int skip;
+    };
+
+    window_values initial;
+
+    window(int count, int skip)
+        : initial(count, skip)
+    {
+    }
+
+    template<class Subscriber>
+    struct window_observer : public window_values, public observer_base<observable<T>>
+    {
+        typedef window_observer<Subscriber> this_type;
+        typedef observer_base<observable<T>> base_type;
+        typedef typename base_type::value_type value_type;
+        typedef typename std::decay<Subscriber>::type dest_type;
+        typedef observer<T, this_type> observer_type;
+        dest_type dest;
+        mutable int cursor;
+        mutable std::deque<rxcpp::subjects::subject<T>> subj;
+
+        window_observer(dest_type d, window_values v)
+            : window_values(v)
+            , dest(std::move(d))
+            , cursor(0)
+        {
+            subj.push_back(rxcpp::subjects::subject<T>());
+            dest.on_next(subj[0].get_observable().as_dynamic());
+        }
+        void on_next(T v) const {
+            for (auto s : subj) {
+                s.get_subscriber().on_next(v);
+            }
+
+            int c = cursor - this->count + 1;
+            if (c >= 0 && c % this->skip == 0) {
+                subj[0].get_subscriber().on_completed();
+                subj.pop_front();
+            }
+
+            if (++cursor % this->skip == 0) {
+                subj.push_back(rxcpp::subjects::subject<T>());
+                dest.on_next(subj[subj.size() - 1].get_observable().as_dynamic());
+            }
+        }
+
+        void on_error(std::exception_ptr e) const {
+            for (auto s : subj) {
+                s.get_subscriber().on_error(e);
+            }
+            dest.on_error(e);
+        }
+
+        void on_completed() const {
+            for (auto s : subj) {
+                s.get_subscriber().on_completed();
+            }
+            dest.on_completed();
+        }
+
+        static subscriber<T, observer_type> make(dest_type d, window_values v) {
+            auto cs = d.get_subscription();
+            return make_subscriber<T>(std::move(cs), observer_type(this_type(std::move(d), std::move(v))));
+        }
+    };
+
+    template<class Subscriber>
+    auto operator()(Subscriber dest) const
+        -> decltype(window_observer<Subscriber>::make(std::move(dest), initial)) {
+        return      window_observer<Subscriber>::make(std::move(dest), initial);
+    }
+};
+
+class window_factory
+{
+    int count;
+    int skip;
+public:
+    window_factory(int c, int s) : count(c), skip(s) {}
+    template<class Observable>
+    auto operator()(Observable&& source)
+        -> decltype(source.template lift<observable<typename std::decay<Observable>::type::value_type>>(window<typename std::decay<Observable>::type::value_type>(count, skip))) {
+        return      source.template lift<observable<typename std::decay<Observable>::type::value_type>>(window<typename std::decay<Observable>::type::value_type>(count, skip));
+    }
+};
+
+}
+
+inline auto window(int count)
+    ->      detail::window_factory {
+    return  detail::window_factory(count, count);
+}
+inline auto window(int count, int skip)
+    ->      detail::window_factory {
+    return  detail::window_factory(count, skip);
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/rx-connectable_observable.hpp b/dependencies64/RxCpp/include/rxcpp/rx-connectable_observable.hpp
new file mode 100644 (file)
index 0000000..731d844
--- /dev/null
@@ -0,0 +1,196 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_RX_CONNECTABLE_OBSERVABLE_HPP)
+#define RXCPP_RX_CONNECTABLE_OBSERVABLE_HPP
+
+#include "rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace detail {
+
+template<class T>
+struct has_on_connect
+{
+    struct not_void {};
+    template<class CT>
+    static auto check(int) -> decltype((*(CT*)nullptr).on_connect(composite_subscription()));
+    template<class CT>
+    static not_void check(...);
+
+    typedef decltype(check<T>(0)) detail_result;
+    static const bool value = std::is_same<detail_result, void>::value;
+};
+
+}
+
+template<class T>
+class dynamic_connectable_observable
+    : public dynamic_observable<T>
+{
+    struct state_type
+        : public std::enable_shared_from_this<state_type>
+    {
+        typedef std::function<void(composite_subscription)> onconnect_type;
+
+        onconnect_type on_connect;
+    };
+    std::shared_ptr<state_type> state;
+
+    template<class U>
+    void construct(const dynamic_observable<U>& o, tag_dynamic_observable&&) {
+        state = o.state;
+    }
+
+    template<class U>
+    void construct(dynamic_observable<U>&& o, tag_dynamic_observable&&) {
+        state = std::move(o.state);
+    }
+
+    template<class SO>
+    void construct(SO&& source, rxs::tag_source&&) {
+        auto so = std::make_shared<typename std::decay<SO>::type>(std::forward<SO>(source));
+        state->on_connect = [so](composite_subscription cs) mutable {
+            so->on_connect(std::move(cs));
+        };
+    }
+
+public:
+
+    typedef tag_dynamic_observable dynamic_observable_tag;
+
+    dynamic_connectable_observable()
+    {
+    }
+
+    template<class SOF>
+    explicit dynamic_connectable_observable(SOF sof)
+        : dynamic_observable<T>(sof)
+        , state(std::make_shared<state_type>())
+    {
+        construct(std::move(sof),
+                  typename std::conditional<is_dynamic_observable<SOF>::value, tag_dynamic_observable, rxs::tag_source>::type());
+    }
+
+    template<class SF, class CF>
+    dynamic_connectable_observable(SF&& sf, CF&& cf)
+        : dynamic_observable<T>(std::forward<SF>(sf))
+        , state(std::make_shared<state_type>())
+    {
+        state->on_connect = std::forward<CF>(cf);
+    }
+
+    using dynamic_observable<T>::on_subscribe;
+
+    void on_connect(composite_subscription cs) const {
+        state->on_connect(std::move(cs));
+    }
+};
+
+template<class T, class Source>
+connectable_observable<T> make_dynamic_connectable_observable(Source&& s) {
+    return connectable_observable<T>(dynamic_connectable_observable<T>(std::forward<Source>(s)));
+}
+
+
+
+template<class T, class SourceOperator>
+class connectable_observable
+    : public observable<T, SourceOperator>
+{
+    typedef connectable_observable<T, SourceOperator> this_type;
+    typedef observable<T, SourceOperator> base_type;
+    typedef typename std::decay<SourceOperator>::type source_operator_type;
+
+    static_assert(detail::has_on_connect<source_operator_type>::value, "inner must have on_connect method void(composite_subscription)");
+
+public:
+    typedef tag_connectable_observable observable_tag;
+
+    connectable_observable()
+    {
+    }
+
+    explicit connectable_observable(const SourceOperator& o)
+        : base_type(o)
+    {
+    }
+    explicit connectable_observable(SourceOperator&& o)
+        : base_type(std::move(o))
+    {
+    }
+
+    // implicit conversion between observables of the same value_type
+    template<class SO>
+    connectable_observable(const connectable_observable<T, SO>& o)
+        : base_type(o)
+    {}
+    // implicit conversion between observables of the same value_type
+    template<class SO>
+    connectable_observable(connectable_observable<T, SO>&& o)
+        : base_type(std::move(o))
+    {}
+
+    ///
+    /// performs type-forgetting conversion to a new composite_observable
+    ///
+    connectable_observable<T> as_dynamic() {
+        return *this;
+    }
+
+    composite_subscription connect(composite_subscription cs = composite_subscription()) {
+        base_type::source_operator.on_connect(cs);
+        return cs;
+    }
+
+    /// ref_count ->
+    /// takes a connectable_observable source and uses a ref_count of the subscribers
+    /// to control the connection to the published source. The first subscription
+    /// will cause a call to connect() and the last unsubscribe will unsubscribe the
+    /// connection.
+    ///
+    auto ref_count() const
+        ->      observable<T,   rxo::detail::ref_count<T, this_type>> {
+        return  observable<T,   rxo::detail::ref_count<T, this_type>>(
+                                rxo::detail::ref_count<T, this_type>(*this));
+    }
+
+    /// connect_forever ->
+    /// takes a connectable_observable source and calls connect during
+    /// the construction of the expression. This means that the source
+    /// starts running without any subscribers and continues running
+    /// after all subscriptions have been unsubscribed.
+    ///
+    auto connect_forever() const
+        ->      observable<T,   rxo::detail::connect_forever<T, this_type>> {
+        return  observable<T,   rxo::detail::connect_forever<T, this_type>>(
+                                rxo::detail::connect_forever<T, this_type>(*this));
+    }
+};
+
+
+}
+
+//
+// support range() >> filter() >> subscribe() syntax
+// '>>' is spelled 'stream'
+//
+template<class T, class SourceOperator, class OperatorFactory>
+auto operator >> (const rxcpp::connectable_observable<T, SourceOperator>& source, OperatorFactory&& of)
+    -> decltype(source.op(std::forward<OperatorFactory>(of))) {
+    return      source.op(std::forward<OperatorFactory>(of));
+}
+
+//
+// support range() | filter() | subscribe() syntax
+// '|' is spelled 'pipe'
+//
+template<class T, class SourceOperator, class OperatorFactory>
+auto operator | (const rxcpp::connectable_observable<T, SourceOperator>& source, OperatorFactory&& of)
+    -> decltype(source.op(std::forward<OperatorFactory>(of))) {
+    return      source.op(std::forward<OperatorFactory>(of));
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/rx-coordination.hpp b/dependencies64/RxCpp/include/rxcpp/rx-coordination.hpp
new file mode 100644 (file)
index 0000000..abd1506
--- /dev/null
@@ -0,0 +1,303 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_RX_COORDINATION_HPP)
+#define RXCPP_RX_COORDINATION_HPP
+
+#include "rx-includes.hpp"
+
+namespace rxcpp {
+
+struct tag_coordinator {};
+struct coordinator_base {typedef tag_coordinator coordinator_tag;};
+template<class T>
+class is_coordinator
+{
+    template<class C>
+    static typename C::coordinator_tag* check(int);
+    template<class C>
+    static void check(...);
+public:
+    static const bool value = std::is_convertible<decltype(check<typename std::decay<T>::type>(0)), tag_coordinator*>::value;
+};
+
+struct tag_coordination {};
+struct coordination_base {typedef tag_coordination coordination_tag;};
+template<class T>
+class is_coordination
+{
+    template<class C>
+    static typename C::coordination_tag* check(int);
+    template<class C>
+    static void check(...);
+public:
+    static const bool value = std::is_convertible<decltype(check<typename std::decay<T>::type>(0)), tag_coordination*>::value;
+};
+
+template<class Input>
+class coordinator : public coordinator_base
+{
+public:
+    typedef Input input_type;
+
+private:
+    struct not_supported {typedef not_supported type;};
+
+    template<class Observable>
+    struct get_observable
+    {
+        typedef decltype((*(input_type*)nullptr).in((*(Observable*)nullptr))) type;
+    };
+
+    template<class Subscriber>
+    struct get_subscriber
+    {
+        typedef decltype((*(input_type*)nullptr).out((*(Subscriber*)nullptr))) type;
+    };
+
+    template<class F>
+    struct get_action_function
+    {
+        typedef decltype((*(input_type*)nullptr).act((*(F*)nullptr))) type;
+    };
+
+public:
+    input_type input;
+
+    template<class T>
+    struct get
+    {
+        typedef typename std::conditional<
+            rxsc::detail::is_action_function<T>::value, get_action_function<T>, typename std::conditional<
+            is_observable<T>::value, get_observable<T>, typename std::conditional<
+            is_subscriber<T>::value, get_subscriber<T>, not_supported>::type>::type>::type::type type;
+    };
+
+    coordinator(Input i) : input(i) {}
+
+    rxsc::worker get_worker() const {
+        return input.get_worker();
+    }
+    rxsc::scheduler get_scheduler() const {
+        return input.get_scheduler();
+    }
+
+    template<class Observable>
+    auto in(Observable o) const
+        -> typename get_observable<Observable>::type {
+        return input.in(std::move(o));
+        static_assert(is_observable<Observable>::value, "can only synchronize observables");
+    }
+
+    template<class Subscriber>
+    auto out(Subscriber s) const
+        -> typename get_subscriber<Subscriber>::type {
+        return input.out(std::move(s));
+        static_assert(is_subscriber<Subscriber>::value, "can only synchronize subscribers");
+    }
+
+    template<class F>
+    auto act(F f) const
+        -> typename get_action_function<F>::type {
+        return input.act(std::move(f));
+        static_assert(rxsc::detail::is_action_function<F>::value, "can only synchronize action functions");
+    }
+};
+
+class identity_one_worker : public coordination_base
+{
+    rxsc::scheduler factory;
+
+    class input_type
+    {
+        rxsc::worker controller;
+        rxsc::scheduler factory;
+    public:
+        explicit input_type(rxsc::worker w)
+            : controller(w)
+            , factory(rxsc::make_same_worker(w))
+        {
+        }
+        inline rxsc::worker get_worker() const {
+            return controller;
+        }
+        inline rxsc::scheduler get_scheduler() const {
+            return factory;
+        }
+        inline rxsc::scheduler::clock_type::time_point now() const {
+            return factory.now();
+        }
+        template<class Observable>
+        auto in(Observable o) const
+            -> Observable {
+            return std::move(o);
+        }
+        template<class Subscriber>
+        auto out(Subscriber s) const
+            -> Subscriber {
+            return std::move(s);
+        }
+        template<class F>
+        auto act(F f) const
+            -> F {
+            return std::move(f);
+        }
+    };
+
+public:
+
+    explicit identity_one_worker(rxsc::scheduler sc) : factory(sc) {}
+
+    typedef coordinator<input_type> coordinator_type;
+
+    inline rxsc::scheduler::clock_type::time_point now() const {
+        return factory.now();
+    }
+
+    inline coordinator_type create_coordinator(composite_subscription cs = composite_subscription()) const {
+        auto w = factory.create_worker(std::move(cs));
+        return coordinator_type(input_type(std::move(w)));
+    }
+};
+
+inline identity_one_worker identity_immediate() {
+    static identity_one_worker r(rxsc::make_immediate());
+    return r;
+}
+
+inline identity_one_worker identity_current_thread() {
+    static identity_one_worker r(rxsc::make_current_thread());
+    return r;
+}
+
+class serialize_one_worker : public coordination_base
+{
+    rxsc::scheduler factory;
+
+    template<class F>
+    struct serialize_action
+    {
+        F dest;
+        std::shared_ptr<std::mutex> lock;
+        serialize_action(F d, std::shared_ptr<std::mutex> m)
+            : dest(std::move(d))
+            , lock(std::move(m))
+        {
+            if (!lock) {
+                abort();
+            }
+        }
+        auto operator()(const rxsc::schedulable& scbl) const
+            -> decltype(dest(scbl)) {
+            std::unique_lock<std::mutex> guard(*lock);
+            return dest(scbl);
+        }
+    };
+
+    template<class Observer>
+    struct serialize_observer
+    {
+        typedef serialize_observer<Observer> this_type;
+        typedef typename std::decay<Observer>::type dest_type;
+        typedef typename dest_type::value_type value_type;
+        typedef observer<value_type, this_type> observer_type;
+        dest_type dest;
+        std::shared_ptr<std::mutex> lock;
+
+        serialize_observer(dest_type d, std::shared_ptr<std::mutex> m)
+            : dest(std::move(d))
+            , lock(std::move(m))
+        {
+            if (!lock) {
+                abort();
+            }
+        }
+        void on_next(value_type v) const {
+            std::unique_lock<std::mutex> guard(*lock);
+            dest.on_next(v);
+        }
+        void on_error(std::exception_ptr e) const {
+            std::unique_lock<std::mutex> guard(*lock);
+            dest.on_error(e);
+        }
+        void on_completed() const {
+            std::unique_lock<std::mutex> guard(*lock);
+            dest.on_completed();
+        }
+
+        template<class Subscriber>
+        static subscriber<value_type, observer_type> make(const Subscriber& s, std::shared_ptr<std::mutex> m) {
+            return make_subscriber<value_type>(s, observer_type(this_type(s.get_observer(), std::move(m))));
+        }
+    };
+
+    class input_type
+    {
+        rxsc::worker controller;
+        rxsc::scheduler factory;
+        std::shared_ptr<std::mutex> lock;
+    public:
+        explicit input_type(rxsc::worker w, std::shared_ptr<std::mutex> m)
+            : controller(w)
+            , factory(rxsc::make_same_worker(w))
+            , lock(std::move(m))
+        {
+        }
+        inline rxsc::worker get_worker() const {
+            return controller;
+        }
+        inline rxsc::scheduler get_scheduler() const {
+            return factory;
+        }
+        inline rxsc::scheduler::clock_type::time_point now() const {
+            return factory.now();
+        }
+        template<class Observable>
+        auto in(Observable o) const
+            -> Observable {
+            return std::move(o);
+        }
+        template<class Subscriber>
+        auto out(const Subscriber& s) const
+            -> decltype(serialize_observer<decltype(s.get_observer())>::make(s, lock)) {
+            return      serialize_observer<decltype(s.get_observer())>::make(s, lock);
+        }
+        template<class F>
+        auto act(F f) const
+            ->      serialize_action<F> {
+            return  serialize_action<F>(std::move(f), lock);
+        }
+    };
+
+public:
+
+    explicit serialize_one_worker(rxsc::scheduler sc) : factory(sc) {}
+
+    typedef coordinator<input_type> coordinator_type;
+
+    inline rxsc::scheduler::clock_type::time_point now() const {
+        return factory.now();
+    }
+
+    inline coordinator_type create_coordinator(composite_subscription cs = composite_subscription()) const {
+        auto w = factory.create_worker(std::move(cs));
+        std::shared_ptr<std::mutex> lock = std::make_shared<std::mutex>();
+        return coordinator_type(input_type(std::move(w), std::move(lock)));
+    }
+};
+
+inline serialize_one_worker serialize_event_loop() {
+    static serialize_one_worker r(rxsc::make_event_loop());
+    return r;
+}
+
+inline serialize_one_worker serialize_new_thread() {
+    static serialize_one_worker r(rxsc::make_new_thread());
+    return r;
+}
+
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/rx-grouped_observable.hpp b/dependencies64/RxCpp/include/rxcpp/rx-grouped_observable.hpp
new file mode 100644 (file)
index 0000000..84deef9
--- /dev/null
@@ -0,0 +1,187 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_RX_GROUPED_OBSERVABLE_HPP)
+#define RXCPP_RX_GROUPED_OBSERVABLE_HPP
+
+#include "rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace detail {
+
+template<class K, class Source>
+struct has_on_get_key_for
+{
+    struct not_void {};
+    template<class CS>
+    static auto check(int) -> decltype((*(CS*)nullptr).on_get_key());
+    template<class CS>
+    static not_void check(...);
+
+    typedef decltype(check<Source>(0)) detail_result;
+    static const bool value = std::is_same<detail_result, typename std::decay<K>::type>::value;
+};
+
+}
+
+template<class K, class T>
+class dynamic_grouped_observable
+    : public dynamic_observable<T>
+{
+public:
+    typedef typename std::decay<K>::type key_type;
+    typedef tag_dynamic_grouped_observable dynamic_observable_tag;
+
+private:
+    struct state_type
+        : public std::enable_shared_from_this<state_type>
+    {
+        typedef std::function<key_type()> ongetkey_type;
+
+        ongetkey_type on_get_key;
+    };
+    std::shared_ptr<state_type> state;
+
+    template<class U, class V>
+    friend bool operator==(const dynamic_grouped_observable<U, V>&, const dynamic_grouped_observable<U, V>&);
+
+    template<class U, class V>
+    void construct(const dynamic_grouped_observable<U, V>& o, const tag_dynamic_grouped_observable&) {
+        state = o.state;
+    }
+
+    template<class U, class V>
+    void construct(dynamic_grouped_observable<U, V>&& o, const tag_dynamic_grouped_observable&) {
+        state = std::move(o.state);
+    }
+
+    template<class SO>
+    void construct(SO&& source, const rxs::tag_source&) {
+        auto so = std::make_shared<typename std::decay<SO>::type>(std::forward<SO>(source));
+        state->on_get_key = [so]() mutable {
+            return so->on_get_key();
+        };
+    }
+
+public:
+
+    dynamic_grouped_observable()
+    {
+    }
+
+    template<class SOF>
+    explicit dynamic_grouped_observable(SOF sof)
+        : dynamic_observable<T>(sof)
+        , state(std::make_shared<state_type>())
+    {
+        construct(std::move(sof),
+                  typename std::conditional<is_dynamic_grouped_observable<SOF>::value, tag_dynamic_grouped_observable, rxs::tag_source>::type());
+    }
+
+    template<class SF, class CF>
+    dynamic_grouped_observable(SF&& sf, CF&& cf)
+        : dynamic_observable<T>(std::forward<SF>(sf))
+        , state(std::make_shared<state_type>())
+    {
+        state->on_connect = std::forward<CF>(cf);
+    }
+
+    using dynamic_observable<T>::on_subscribe;
+
+    key_type on_get_key() const {
+        return state->on_get_key();
+    }
+};
+
+template<class K, class T>
+inline bool operator==(const dynamic_grouped_observable<K, T>& lhs, const dynamic_grouped_observable<K, T>& rhs) {
+    return lhs.state == rhs.state;
+}
+template<class K, class T>
+inline bool operator!=(const dynamic_grouped_observable<K, T>& lhs, const dynamic_grouped_observable<K, T>& rhs) {
+    return !(lhs == rhs);
+}
+
+template<class K, class T, class Source>
+grouped_observable<K, T> make_dynamic_grouped_observable(Source&& s) {
+    return grouped_observable<K, T>(dynamic_grouped_observable<K, T>(std::forward<Source>(s)));
+}
+
+
+
+template<class K, class T, class SourceOperator>
+class grouped_observable
+    : public observable<T, SourceOperator>
+{
+    typedef grouped_observable<K, T, SourceOperator> this_type;
+    typedef observable<T, SourceOperator> base_type;
+    typedef typename std::decay<SourceOperator>::type source_operator_type;
+
+    static_assert(detail::has_on_get_key_for<K, source_operator_type>::value, "inner must have on_get_key method key_type()");
+
+public:
+    typedef typename std::decay<K>::type key_type;
+    typedef tag_grouped_observable observable_tag;
+
+    grouped_observable()
+    {
+    }
+
+    explicit grouped_observable(const SourceOperator& o)
+        : base_type(o)
+    {
+    }
+    explicit grouped_observable(SourceOperator&& o)
+        : base_type(std::move(o))
+    {
+    }
+
+    // implicit conversion between observables of the same value_type
+    template<class SO>
+    grouped_observable(const grouped_observable<K, T, SO>& o)
+        : base_type(o)
+    {}
+    // implicit conversion between observables of the same value_type
+    template<class SO>
+    grouped_observable(grouped_observable<K, T, SO>&& o)
+        : base_type(std::move(o))
+    {}
+
+    ///
+    /// performs type-forgetting conversion to a new grouped_observable
+    ///
+    grouped_observable<K, T> as_dynamic() const {
+        return *this;
+    }
+
+    key_type get_key() const {
+        return base_type::source_operator.on_get_key();
+    }
+};
+
+
+}
+
+//
+// support range() >> filter() >> subscribe() syntax
+// '>>' is spelled 'stream'
+//
+template<class T, class SourceOperator, class OperatorFactory>
+auto operator >> (const rxcpp::grouped_observable<T, SourceOperator>& source, OperatorFactory&& of)
+    -> decltype(source.op(std::forward<OperatorFactory>(of))) {
+    return      source.op(std::forward<OperatorFactory>(of));
+}
+
+//
+// support range() | filter() | subscribe() syntax
+// '|' is spelled 'pipe'
+//
+template<class T, class SourceOperator, class OperatorFactory>
+auto operator | (const rxcpp::grouped_observable<T, SourceOperator>& source, OperatorFactory&& of)
+    -> decltype(source.op(std::forward<OperatorFactory>(of))) {
+    return      source.op(std::forward<OperatorFactory>(of));
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/rx-includes.hpp b/dependencies64/RxCpp/include/rxcpp/rx-includes.hpp
new file mode 100644 (file)
index 0000000..5ca50e1
--- /dev/null
@@ -0,0 +1,140 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_RX_INCLUDES_HPP)
+#define RXCPP_RX_INCLUDES_HPP
+
+#include "rx-trace.hpp"
+
+// some configuration macros
+#if defined(_MSC_VER)
+
+#if _MSC_VER > 1600
+#pragma warning(disable: 4348) // false positives on : redefinition of default parameter : parameter 2
+#define RXCPP_USE_RVALUEREF 1
+#endif
+
+#if _MSC_VER >= 1800
+#define RXCPP_USE_VARIADIC_TEMPLATES 1
+#endif
+
+#if _CPPRTTI
+#define RXCPP_USE_RTTI 1
+#endif
+
+#elif defined(__clang__)
+
+#if __has_feature(cxx_rvalue_references)
+#define RXCPP_USE_RVALUEREF 1
+#endif
+#if __has_feature(cxx_rtti)
+#define RXCPP_USE_RTTI 1
+#endif
+#if __has_feature(cxx_variadic_templates)
+#define RXCPP_USE_VARIADIC_TEMPLATES 1
+#endif
+
+#elif defined(__GNUG__)
+
+#define GCC_VERSION (__GNUC__ * 10000 + \
+                     __GNUC_MINOR__ * 100 + \
+                     __GNUC_PATCHLEVEL__)
+
+#if GCC_VERSION >= 40801
+#define RXCPP_USE_RVALUEREF 1
+#endif
+
+#if GCC_VERSION >= 40400
+#define RXCPP_USE_VARIADIC_TEMPLATES 1
+#endif
+
+#if defined(__GXX_RTTI)
+#define RXCPP_USE_RTTI 1
+#endif
+
+#endif
+
+#if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)
+#define RXCPP_USE_WINRT 0
+#else
+#define RXCPP_USE_WINRT 1
+#endif
+
+#if defined(RXCPP_FORCE_USE_VARIADIC_TEMPLATES)
+#undef RXCPP_USE_VARIADIC_TEMPLATES
+#define RXCPP_USE_VARIADIC_TEMPLATES RXCPP_FORCE_USE_VARIADIC_TEMPLATES
+#endif
+
+#if defined(RXCPP_FORCE_USE_RVALUEREF)
+#undef RXCPP_USE_RVALUEREF
+#define RXCPP_USE_RVALUEREF RXCPP_FORCE_USE_RVALUEREF
+#endif
+
+#if defined(RXCPP_FORCE_USE_RTTI)
+#undef RXCPP_USE_RTTI
+#define RXCPP_USE_RTTI RXCPP_FORCE_USE_RTTI
+#endif
+
+#if defined(RXCPP_FORCE_USE_WINRT)
+#undef RXCPP_USE_WINRT
+#define RXCPP_USE_WINRT RXCPP_FORCE_USE_WINRT
+#endif
+
+#if defined(_MSC_VER) && !RXCPP_USE_VARIADIC_TEMPLATES
+// resolve args needs enough to store all the possible resolved args
+#define _VARIADIC_MAX 10
+#endif
+
+#pragma push_macro("min")
+#pragma push_macro("max")
+#undef min
+#undef max
+
+#include <stdlib.h>
+
+#include <cstddef>
+
+#include <iostream>
+#include <iomanip>
+
+#include <exception>
+#include <functional>
+#include <memory>
+#include <array>
+#include <vector>
+#include <algorithm>
+#include <atomic>
+#include <map>
+#include <set>
+#include <mutex>
+#include <deque>
+#include <thread>
+#include <future>
+#include <vector>
+#include <list>
+#include <queue>
+#include <chrono>
+#include <condition_variable>
+#include <initializer_list>
+#include <typeinfo>
+
+#include "rx-util.hpp"
+#include "rx-predef.hpp"
+#include "rx-subscription.hpp"
+#include "rx-observer.hpp"
+#include "rx-scheduler.hpp"
+#include "rx-subscriber.hpp"
+#include "rx-notification.hpp"
+#include "rx-coordination.hpp"
+#include "rx-sources.hpp"
+#include "rx-subjects.hpp"
+#include "rx-operators.hpp"
+#include "rx-observable.hpp"
+#include "rx-connectable_observable.hpp"
+#include "rx-grouped_observable.hpp"
+
+#pragma pop_macro("min")
+#pragma pop_macro("max")
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/rx-notification.hpp b/dependencies64/RxCpp/include/rxcpp/rx-notification.hpp
new file mode 100644 (file)
index 0000000..b572c27
--- /dev/null
@@ -0,0 +1,286 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_RX_NOTIFICATION_HPP)
+#define RXCPP_RX_NOTIFICATION_HPP
+
+#include "rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace notifications {
+
+class subscription
+{
+    long s;
+    long u;
+
+public:
+    explicit inline subscription(long s)
+        : s(s), u(std::numeric_limits<long>::max()) {
+    }
+    inline subscription(long s, long u)
+        : s(s), u(u) {
+    }
+    inline long subscribe() const {
+        return s;
+    }
+    inline long unsubscribe() const {
+        return u;
+    }
+};
+
+inline bool operator == (subscription lhs, subscription rhs) {
+    return lhs.subscribe() == rhs.subscribe() && lhs.unsubscribe() == rhs.unsubscribe();
+}
+
+inline std::ostream& operator<< (std::ostream& out, const subscription& s) {
+    out << s.subscribe() << "-" << s.unsubscribe();
+    return out;
+}
+
+namespace detail {
+
+template<typename T>
+struct notification_base
+    : public std::enable_shared_from_this<notification_base<T>>
+{
+    typedef subscriber<T> observer_type;
+    typedef std::shared_ptr<notification_base<T>> type;
+
+    virtual ~notification_base() {}
+
+    virtual void out(std::ostream& out) const =0;
+    virtual bool equals(const type& other) const = 0;
+    virtual void accept(const observer_type& o) const =0;
+};
+
+template<class T>
+std::ostream& operator<< (std::ostream& out, const std::vector<T>& v);
+
+template<class T>
+auto to_stream(std::ostream& os, const T& t, int, int)
+    -> decltype(os << t) {
+    return      os << t;
+}
+
+#if RXCPP_USE_RTTI
+template<class T>
+std::ostream& to_stream(std::ostream& os, const T&, int, ...) {
+    return os << "< " << typeid(T).name() << " does not support ostream>";
+}
+#endif
+
+template<class T>
+std::ostream& to_stream(std::ostream& os, const T&, ...) {
+    return os << "<the value does not support ostream>";
+}
+
+template<class T>
+inline std::ostream& operator<< (std::ostream& os, const std::vector<T>& v) {
+    os << "[";
+    bool emit = false;
+    for(auto& i : v) {
+        if (emit) {
+            os << ", ";
+        } else {
+            emit = true;
+        }
+        to_stream(os, i, 0, 0);
+    }
+    os << "]";
+    return os;
+}
+
+
+}
+
+template<typename T>
+struct notification
+{
+    typedef typename detail::notification_base<T>::type type;
+    typedef typename detail::notification_base<T>::observer_type observer_type;
+
+private:
+    typedef detail::notification_base<T> base;
+
+    struct on_next_notification : public base {
+        on_next_notification(T value) : value(std::move(value)) {
+        }
+        virtual void out(std::ostream& os) const {
+            os << "on_next( ";
+            detail::to_stream(os, value, 0, 0);
+            os << ")";
+        }
+        virtual bool equals(const typename base::type& other) const {
+            bool result = false;
+            other->accept(make_subscriber<T>(make_observer_dynamic<T>([this, &result](T v) {
+                    result = this->value == v;
+                })));
+            return result;
+        }
+        virtual void accept(const typename base::observer_type& o) const {
+            o.on_next(value);
+        }
+        const T value;
+    };
+
+    struct on_error_notification : public base {
+        on_error_notification(std::exception_ptr ep) : ep(ep) {
+        }
+        virtual void out(std::ostream& os) const {
+            os << "on_error(";
+            try {
+                std::rethrow_exception(ep);
+            } catch (const std::exception& e) {
+                os << e.what();
+            } catch (...) {
+                os << "<not derived from std::exception>";
+            }
+            os << ")";
+        }
+        virtual bool equals(const typename base::type& other) const {
+            bool result = false;
+            // not trying to compare exceptions
+            other->accept(make_subscriber<T>(make_observer_dynamic<T>([](T){}, [&result](std::exception_ptr){
+                result = true;
+            })));
+            return result;
+        }
+        virtual void accept(const typename base::observer_type& o) const {
+            o.on_error(ep);
+        }
+        const std::exception_ptr ep;
+    };
+
+    struct on_completed_notification : public base {
+        on_completed_notification() {
+        }
+        virtual void out(std::ostream& os) const {
+            os << "on_completed()";
+        }
+        virtual bool equals(const typename base::type& other) const {
+            bool result = false;
+            other->accept(make_subscriber<T>(make_observer_dynamic<T>([](T){}, [&result](){
+                result = true;
+            })));
+            return result;
+        }
+        virtual void accept(const typename base::observer_type& o) const {
+            o.on_completed();
+        }
+    };
+
+    struct exception_tag {};
+
+    template<typename Exception>
+    static
+    type make_on_error(exception_tag&&, Exception&& e) {
+        std::exception_ptr ep;
+        try {
+            throw std::forward<Exception>(e);
+        }
+        catch (...) {
+            ep = std::current_exception();
+        }
+        return std::make_shared<on_error_notification>(ep);
+    }
+
+    struct exception_ptr_tag {};
+
+    static
+    type make_on_error(exception_ptr_tag&&, std::exception_ptr ep) {
+        return std::make_shared<on_error_notification>(ep);
+    }
+
+    struct on_next_factory
+    {
+        type operator()(T value) const {
+            return std::make_shared<on_next_notification>(std::move(value));
+        }
+    };
+
+    struct on_completed_factory
+    {
+        type operator()() const {
+            return std::make_shared<on_completed_notification>();
+        }
+    };
+
+    struct on_error_factory
+    {
+        template<typename Exception>
+        type operator()(Exception&& e) const {
+            return make_on_error(typename std::conditional<
+                std::is_same<typename std::decay<Exception>::type, std::exception_ptr>::value,
+                    exception_ptr_tag, exception_tag>::type(),
+                std::forward<Exception>(e));
+        }
+    };
+public:
+    const static on_next_factory on_next;
+    const static on_completed_factory on_completed;
+    const static on_error_factory on_error;
+};
+
+template<class T>
+//static
+RXCPP_SELECT_ANY const typename notification<T>::on_next_factory notification<T>::on_next = notification<T>::on_next_factory();
+
+template<class T>
+//static
+RXCPP_SELECT_ANY const typename notification<T>::on_completed_factory notification<T>::on_completed = notification<T>::on_completed_factory();
+
+template<class T>
+//static
+RXCPP_SELECT_ANY const typename notification<T>::on_error_factory notification<T>::on_error = notification<T>::on_error_factory();
+
+template<class T>
+bool operator == (const std::shared_ptr<detail::notification_base<T>>& lhs, const std::shared_ptr<detail::notification_base<T>>& rhs) {
+    if (!lhs && !rhs) {return true;}
+    if (!lhs || !rhs) {return false;}
+    return lhs->equals(rhs);
+}
+
+template<class T>
+std::ostream& operator<< (std::ostream& os, const std::shared_ptr<detail::notification_base<T>>& n) {
+    n->out(os);
+    return os;
+}
+
+
+template<class T>
+class recorded
+{
+    long t;
+    T v;
+public:
+    recorded(long t, T v)
+        : t(t), v(v) {
+    }
+    long time() const {
+        return t;
+    }
+    const T& value() const {
+        return v;
+    }
+};
+
+template<class T>
+bool operator == (recorded<T> lhs, recorded<T> rhs) {
+    return lhs.time() == rhs.time() && lhs.value() == rhs.value();
+}
+
+template<class T>
+std::ostream& operator<< (std::ostream& out, const recorded<T>& r) {
+    out << "@" << r.time() << "-" << r.value();
+    return out;
+}
+
+}
+namespace rxn=notifications;
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/rx-observable.hpp b/dependencies64/RxCpp/include/rxcpp/rx-observable.hpp
new file mode 100644 (file)
index 0000000..6014b4d
--- /dev/null
@@ -0,0 +1,1260 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_RX_OBSERVABLE_HPP)
+#define RXCPP_RX_OBSERVABLE_HPP
+
+#include "rx-includes.hpp"
+
+#ifdef __GNUG__
+#define EXPLICIT_THIS this->
+#else
+#define EXPLICIT_THIS
+#endif
+
+namespace rxcpp {
+
+namespace detail {
+
+template<class Source, class F>
+struct is_operator_factory_for
+{
+    struct not_void {};
+    template<class CS, class CF>
+    static auto check(int) -> decltype((*(CF*)nullptr)(*(CS*)nullptr));
+    template<class CS, class CF>
+    static not_void check(...);
+
+    typedef typename std::decay<Source>::type source_type;
+    typedef typename std::decay<F>::type function_type;
+
+    typedef decltype(check<source_type, function_type>(0)) detail_result;
+    static const bool value = !std::is_same<detail_result, not_void>::value && is_observable<source_type>::value;
+};
+
+template<class Subscriber, class T>
+struct has_on_subscribe_for
+{
+    struct not_void {};
+    template<class CS, class CT>
+    static auto check(int) -> decltype((*(CT*)nullptr).on_subscribe(*(CS*)nullptr));
+    template<class CS, class CT>
+    static not_void check(...);
+
+    typedef decltype(check<typename std::decay<Subscriber>::type, T>(0)) detail_result;
+    static const bool value = std::is_same<detail_result, void>::value;
+};
+
+}
+
+template<class T>
+class dynamic_observable
+    : public rxs::source_base<T>
+{
+    struct state_type
+        : public std::enable_shared_from_this<state_type>
+    {
+        typedef std::function<void(subscriber<T>)> onsubscribe_type;
+
+        onsubscribe_type on_subscribe;
+    };
+    std::shared_ptr<state_type> state;
+
+    template<class U>
+    friend bool operator==(const dynamic_observable<U>&, const dynamic_observable<U>&);
+
+    template<class SO>
+    void construct(SO&& source, rxs::tag_source&&) {
+        typename std::decay<SO>::type so = std::forward<SO>(source);
+        state->on_subscribe = [so](subscriber<T> o) mutable {
+            so.on_subscribe(std::move(o));
+        };
+    }
+
+    struct tag_function {};
+    template<class F>
+    void construct(F&& f, tag_function&&) {
+        state->on_subscribe = std::forward<F>(f);
+    }
+
+public:
+
+    typedef tag_dynamic_observable dynamic_observable_tag;
+
+    dynamic_observable()
+    {
+    }
+
+    template<class SOF>
+    explicit dynamic_observable(SOF&& sof, typename std::enable_if<!is_dynamic_observable<SOF>::value, void**>::type = 0)
+        : state(std::make_shared<state_type>())
+    {
+        construct(std::forward<SOF>(sof),
+                  typename std::conditional<rxs::is_source<SOF>::value || rxo::is_operator<SOF>::value, rxs::tag_source, tag_function>::type());
+    }
+
+    void on_subscribe(subscriber<T> o) const {
+        state->on_subscribe(std::move(o));
+    }
+
+    template<class Subscriber>
+    typename std::enable_if<is_subscriber<Subscriber>::value, void>::type
+    on_subscribe(Subscriber o) const {
+        state->on_subscribe(o.as_dynamic());
+    }
+};
+
+template<class T>
+inline bool operator==(const dynamic_observable<T>& lhs, const dynamic_observable<T>& rhs) {
+    return lhs.state == rhs.state;
+}
+template<class T>
+inline bool operator!=(const dynamic_observable<T>& lhs, const dynamic_observable<T>& rhs) {
+    return !(lhs == rhs);
+}
+
+template<class T, class Source>
+observable<T> make_observable_dynamic(Source&& s) {
+    return observable<T>(dynamic_observable<T>(std::forward<Source>(s)));
+}
+
+namespace detail {
+template<bool Selector, class Default, class SO>
+struct resolve_observable;
+
+template<class Default, class SO>
+struct resolve_observable<true, Default, SO>
+{
+    typedef typename SO::type type;
+    typedef typename type::value_type value_type;
+    static const bool value = true;
+    typedef observable<value_type, type> observable_type;
+    template<class... AN>
+    static observable_type make(const Default&, AN&&... an) {
+        return observable_type(type(std::forward<AN>(an)...));
+    }
+};
+template<class Default, class SO>
+struct resolve_observable<false, Default, SO>
+{
+    static const bool value = false;
+    typedef Default observable_type;
+    template<class... AN>
+    static observable_type make(const observable_type& that, const AN&...) {
+        return that;
+    }
+};
+template<class SO>
+struct resolve_observable<true, void, SO>
+{
+    typedef typename SO::type type;
+    typedef typename type::value_type value_type;
+    static const bool value = true;
+    typedef observable<value_type, type> observable_type;
+    template<class... AN>
+    static observable_type make(AN&&... an) {
+        return observable_type(type(std::forward<AN>(an)...));
+    }
+};
+template<class SO>
+struct resolve_observable<false, void, SO>
+{
+    static const bool value = false;
+    typedef void observable_type;
+    template<class... AN>
+    static observable_type make(const AN&...) {
+    }
+};
+
+}
+
+template<class Selector, class Default, template<class... TN> class SO, class... AN>
+struct defer_observable
+    : public detail::resolve_observable<Selector::value, Default, rxu::defer_type<SO, AN...>>
+{
+};
+
+template<class T, class Observable>
+class blocking_observable
+{
+    template<class Obsvbl, class... ArgN>
+    static auto blocking_subscribe(const Obsvbl& source, ArgN&&... an)
+        -> composite_subscription {
+        std::mutex lock;
+        std::condition_variable wake;
+        composite_subscription cs;
+        struct tracking
+        {
+            ~tracking()
+            {
+                if (!disposed || !wakened) abort();
+            }
+            tracking()
+            {
+                disposed = false;
+                wakened = false;
+                false_wakes = 0;
+                true_wakes = 0;
+            }
+            std::atomic_bool disposed;
+            std::atomic_bool wakened;
+            std::atomic_int false_wakes;
+            std::atomic_int true_wakes;
+        };
+        auto track = std::make_shared<tracking>();
+
+        auto scbr = make_subscriber<T>(std::forward<ArgN>(an)...);
+        cs = scbr.get_subscription();
+        cs.add(
+            [&, track](){
+                // OSX geting invalid x86 op if notify_one is after the disposed = true
+                // presumably because the condition_variable may already have been awakened
+                // and is now sitting in a while loop on disposed
+                wake.notify_one();
+                track->disposed = true;
+            });
+        std::unique_lock<std::mutex> guard(lock);
+        source.subscribe(std::move(scbr));
+        wake.wait(guard,
+            [&, track](){
+                // this is really not good.
+                // false wakeups were never followed by true wakeups so..
+
+                // anyways this gets triggered before disposed is set now so wait.
+                while (!track->disposed) {
+                    ++track->false_wakes;
+                }
+                ++track->true_wakes;
+                return true;
+            });
+        track->wakened = true;
+        if (!track->disposed || !track->wakened) abort();
+        return composite_subscription::empty();
+    }
+
+public:
+    typedef typename std::decay<Observable>::type observable_type;
+    observable_type source;
+    ~blocking_observable()
+    {
+    }
+    blocking_observable(observable_type s) : source(std::move(s)) {}
+
+    ///
+    /// subscribe will cause this observable to emit values to the provided subscriber.
+    /// callers must provide enough arguments to make a subscriber.
+    /// overrides are supported. thus
+    ///   subscribe(thesubscriber, composite_subscription())
+    /// will take thesubscriber.get_observer() and the provided
+    /// subscription and subscribe to the new subscriber.
+    /// the on_next, on_error, on_completed methods can be supplied instead of an observer
+    /// if a subscription or subscriber is not provided then a new subscription will be created.
+    ///
+    template<class... ArgN>
+    auto subscribe(ArgN&&... an) const
+        -> composite_subscription {
+        return blocking_subscribe(source, std::forward<ArgN>(an)...);
+    }
+
+    T first() {
+        rxu::maybe<T> result;
+        composite_subscription cs;
+        subscribe(cs, [&](T v){result.reset(v); cs.unsubscribe();});
+        if (result.empty()) abort();
+        return result.get();
+    }
+
+    T last() const {
+        rxu::maybe<T> result;
+        subscribe([&](T v){result.reset(v);});
+        if (result.empty()) abort();
+        return result.get();
+    }
+
+    int count() const {
+        return source.count().as_blocking().last();
+    }
+    T sum() const {
+        return source.sum().as_blocking().last();
+    }
+    double average() const {
+        return source.average().as_blocking().last();
+    }
+};
+
+template<>
+class observable<void, void>;
+
+
+template<class T, class SourceOperator>
+class observable
+    : public observable_base<T>
+{
+    static_assert(std::is_same<T, typename SourceOperator::value_type>::value, "SourceOperator::value_type must be the same as T in observable<T, SourceOperator>");
+
+    typedef observable<T, SourceOperator> this_type;
+
+public:
+    typedef typename std::decay<SourceOperator>::type source_operator_type;
+    mutable source_operator_type source_operator;
+
+private:
+
+    template<class U, class SO>
+    friend class observable;
+
+    template<class U, class SO>
+    friend bool operator==(const observable<U, SO>&, const observable<U, SO>&);
+
+    template<class Subscriber>
+    auto detail_subscribe(Subscriber o) const
+        -> composite_subscription {
+
+        typedef typename std::decay<Subscriber>::type subscriber_type;
+
+        static_assert(is_subscriber<subscriber_type>::value, "subscribe must be passed a subscriber");
+        static_assert(std::is_same<typename source_operator_type::value_type, T>::value && std::is_convertible<T*, typename subscriber_type::value_type*>::value, "the value types in the sequence must match or be convertible");
+        static_assert(detail::has_on_subscribe_for<subscriber_type, source_operator_type>::value, "inner must have on_subscribe method that accepts this subscriber ");
+
+        trace_activity().subscribe_enter(*this, o);
+
+        if (!o.is_subscribed()) {
+            trace_activity().subscribe_return(*this);
+            return o.get_subscription();
+        }
+
+        auto safe_subscribe = [&]() {
+            try {
+                source_operator.on_subscribe(o);
+            }
+            catch(...) {
+                if (!o.is_subscribed()) {
+                    throw;
+                }
+                o.on_error(std::current_exception());
+                o.unsubscribe();
+            }
+        };
+
+        // make sure to let current_thread take ownership of the thread as early as possible.
+        if (rxsc::current_thread::is_schedule_required()) {
+            const auto& sc = rxsc::make_current_thread();
+            sc.create_worker(o.get_subscription()).schedule(
+                [&](const rxsc::schedulable& scbl) {
+                    safe_subscribe();
+                });
+        } else {
+            // current_thread already owns this thread.
+            safe_subscribe();
+        }
+
+        trace_activity().subscribe_return(*this);
+        return o.get_subscription();
+    }
+
+public:
+    typedef T value_type;
+
+    static_assert(rxo::is_operator<source_operator_type>::value || rxs::is_source<source_operator_type>::value, "observable must wrap an operator or source");
+
+    ~observable()
+    {
+    }
+
+    observable()
+    {
+    }
+
+    explicit observable(const source_operator_type& o)
+        : source_operator(o)
+    {
+    }
+    explicit observable(source_operator_type&& o)
+        : source_operator(std::move(o))
+    {
+    }
+
+    /// implicit conversion between observables of the same value_type
+    template<class SO>
+    observable(const observable<T, SO>& o)
+        : source_operator(o.source_operator)
+    {}
+    /// implicit conversion between observables of the same value_type
+    template<class SO>
+    observable(observable<T, SO>&& o)
+        : source_operator(std::move(o.source_operator))
+    {}
+
+#if 0
+    template<class I>
+    void on_subscribe(observer<T, I> o) const {
+        source_operator.on_subscribe(o);
+    }
+#endif
+
+    ///
+    /// returns a new observable that performs type-forgetting conversion of this observable
+    ///
+    observable<T> as_dynamic() const {
+        return *this;
+    }
+
+    ///
+    /// returns new observable that contains the blocking methods for this observable
+    ///
+    blocking_observable<T, this_type> as_blocking() const {
+        return blocking_observable<T, this_type>(*this);
+    }
+
+    ///
+    /// takes any function that will take this observable and produce a result value.
+    /// this is intended to allow externally defined operators, that use subscribe,
+    /// to be connected into the expression.
+    ///
+    template<class OperatorFactory>
+    auto op(OperatorFactory&& of) const
+        -> decltype(of(*(const this_type*)nullptr)) {
+        return      of(*this);
+        static_assert(detail::is_operator_factory_for<this_type, OperatorFactory>::value, "Function passed for op() must have the signature Result(SourceObservable)");
+    }
+
+    ///
+    /// takes any function that will take a subscriber for this observable and produce a subscriber.
+    /// this is intended to allow externally defined operators, that use make_subscriber, to be connected
+    /// into the expression.
+    ///
+    template<class ResultType, class Operator>
+    auto lift(Operator&& op) const
+        ->      observable<typename rxo::detail::lift_operator<ResultType, source_operator_type, Operator>::value_type, rxo::detail::lift_operator<ResultType, source_operator_type, Operator>> {
+        return  observable<typename rxo::detail::lift_operator<ResultType, source_operator_type, Operator>::value_type, rxo::detail::lift_operator<ResultType, source_operator_type, Operator>>(
+                                                                                                                        rxo::detail::lift_operator<ResultType, source_operator_type, Operator>(source_operator, std::forward<Operator>(op)));
+        static_assert(detail::is_lift_function_for<T, subscriber<ResultType>, Operator>::value, "Function passed for lift() must have the signature subscriber<...>(subscriber<T, ...>)");
+    }
+
+    ///
+    /// subscribe will cause this observable to emit values to the provided subscriber.
+    /// callers must provide enough arguments to make a subscriber.
+    /// overrides are supported. thus
+    ///   subscribe(thesubscriber, composite_subscription())
+    /// will take thesubscriber.get_observer() and the provided
+    /// subscription and subscribe to the new subscriber.
+    /// the on_next, on_error, on_completed methods can be supplied instead of an observer
+    /// if a subscription or subscriber is not provided then a new subscription will be created.
+    ///
+    template<class... ArgN>
+    auto subscribe(ArgN&&... an) const
+        -> composite_subscription {
+        return detail_subscribe(make_subscriber<T>(std::forward<ArgN>(an)...));
+    }
+
+    /// filter (AKA Where) ->
+    /// for each item from this observable use Predicate to select which items to emit from the new observable that is returned.
+    ///
+    template<class Predicate>
+    auto filter(Predicate p) const
+        -> decltype(EXPLICIT_THIS lift<T>(rxo::detail::filter<T, Predicate>(std::move(p)))) {
+        return                    lift<T>(rxo::detail::filter<T, Predicate>(std::move(p)));
+    }
+
+    /// finally () ->
+    ///
+    template<class LastCall>
+    auto finally(LastCall lc) const
+        -> decltype(EXPLICIT_THIS lift<T>(rxo::detail::finally<T, LastCall>(std::move(lc)))) {
+        return                    lift<T>(rxo::detail::finally<T, LastCall>(std::move(lc)));
+    }
+
+    /// map (AKA Select) ->
+    /// for each item from this observable use Selector to produce an item to emit from the new observable that is returned.
+    ///
+    template<class Selector>
+    auto map(Selector s) const
+        -> decltype(EXPLICIT_THIS lift<typename rxo::detail::map<T, Selector>::value_type>(rxo::detail::map<T, Selector>(std::move(s)))) {
+        return                    lift<typename rxo::detail::map<T, Selector>::value_type>(rxo::detail::map<T, Selector>(std::move(s)));
+    }
+
+    /// distinct_until_changed ->
+    /// for each item from this observable, filter out repeated values and emit only changes from the new observable that is returned.
+    ///
+    auto distinct_until_changed() const
+        -> decltype(EXPLICIT_THIS lift<T>(rxo::detail::distinct_until_changed<T>())) {
+        return                    lift<T>(rxo::detail::distinct_until_changed<T>());
+    }
+
+    /// window ->
+    /// produce observables containing count items emitted by this observable
+    ///
+    auto window(int count) const
+        -> decltype(EXPLICIT_THIS lift<observable<T>>(rxo::detail::window<T>(count, count))) {
+        return                    lift<observable<T>>(rxo::detail::window<T>(count, count));
+    }
+
+    /// window ->
+    /// produce observables containing count items emitted by this observable
+    ///
+    auto window(int count, int skip) const
+        -> decltype(EXPLICIT_THIS lift<observable<T>>(rxo::detail::window<T>(count, skip))) {
+        return                    lift<observable<T>>(rxo::detail::window<T>(count, skip));
+    }
+
+    /// buffer ->
+    /// collect count items from this observable and produce a vector of them to emit from the new observable that is returned.
+    ///
+    auto buffer(int count) const
+        -> decltype(EXPLICIT_THIS lift<std::vector<T>>(rxo::detail::buffer_count<T>(count, count))) {
+        return                    lift<std::vector<T>>(rxo::detail::buffer_count<T>(count, count));
+    }
+
+    /// buffer ->
+    /// start a new vector every skip items and collect count items from this observable into each vector to emit from the new observable that is returned.
+    ///
+    auto buffer(int count, int skip) const
+        -> decltype(EXPLICIT_THIS lift<std::vector<T>>(rxo::detail::buffer_count<T>(count, skip))) {
+        return                    lift<std::vector<T>>(rxo::detail::buffer_count<T>(count, skip));
+    }
+
+    template<class Coordination>
+    struct defer_switch_on_next : public defer_observable<
+        is_observable<value_type>,
+        this_type,
+        rxo::detail::switch_on_next, value_type, observable<value_type>, Coordination>
+    {
+    };
+
+    /// switch_on_next (AKA Switch) ->
+    /// All sources must be synchronized! This means that calls across all the subscribers must be serial.
+    /// for each item from this observable subscribe to that observable after unsubscribing from any previous subscription.
+    ///
+    auto switch_on_next() const
+        -> typename defer_switch_on_next<identity_one_worker>::observable_type {
+        return      defer_switch_on_next<identity_one_worker>::make(*this, *this, identity_current_thread());
+    }
+
+    /// switch_on_next (AKA Switch) ->
+    /// The coodination is used to synchronize sources from different contexts.
+    /// for each item from this observable subscribe to that observable after unsubscribing from any previous subscription.
+    ///
+    template<class Coordination>
+    auto switch_on_next(Coordination cn) const
+        ->  typename std::enable_if<
+                        defer_switch_on_next<Coordination>::value,
+            typename    defer_switch_on_next<Coordination>::observable_type>::type {
+        return          defer_switch_on_next<Coordination>::make(*this, *this, std::move(cn));
+    }
+
+    template<class Coordination>
+    struct defer_merge : public defer_observable<
+        is_observable<value_type>,
+        this_type,
+        rxo::detail::merge, value_type, observable<value_type>, Coordination>
+    {
+    };
+
+    /// merge ->
+    /// All sources must be synchronized! This means that calls across all the subscribers must be serial.
+    /// for each item from this observable subscribe.
+    /// for each item from all of the nested observables deliver from the new observable that is returned.
+    ///
+    auto merge() const
+        -> typename defer_merge<identity_one_worker>::observable_type {
+        return      defer_merge<identity_one_worker>::make(*this, *this, identity_current_thread());
+    }
+
+    /// merge ->
+    /// The coordination is used to synchronize sources from different contexts.
+    /// for each item from this observable subscribe.
+    /// for each item from all of the nested observables deliver from the new observable that is returned.
+    ///
+    template<class Coordination>
+    auto merge(Coordination cn) const
+        ->  typename std::enable_if<
+                        defer_merge<Coordination>::value,
+            typename    defer_merge<Coordination>::observable_type>::type {
+        return          defer_merge<Coordination>::make(*this, *this, std::move(cn));
+    }
+
+    template<class Coordination, class Value0>
+    struct defer_merge_from : public defer_observable<
+        rxu::all_true<
+            is_coordination<Coordination>::value,
+            is_observable<Value0>::value>,
+        this_type,
+        rxo::detail::merge, observable<value_type>, observable<observable<value_type>>, Coordination>
+    {
+    };
+
+    /// merge ->
+    /// All sources must be synchronized! This means that calls across all the subscribers must be serial.
+    /// for each item from this observable subscribe.
+    /// for each item from all of the nested observables deliver from the new observable that is returned.
+    ///
+    template<class Value0, class... ValueN>
+    auto merge(Value0 v0, ValueN... vn) const
+        ->  typename std::enable_if<
+                        defer_merge_from<identity_one_worker, Value0>::value,
+            typename    defer_merge_from<identity_one_worker, Value0>::observable_type>::type {
+        return          defer_merge_from<identity_one_worker, Value0>::make(*this, rxs::from(this->as_dynamic(), v0.as_dynamic(), vn.as_dynamic()...), identity_current_thread());
+    }
+
+    /// merge ->
+    /// The coordination is used to synchronize sources from different contexts.
+    /// for each item from this observable subscribe.
+    /// for each item from all of the nested observables deliver from the new observable that is returned.
+    ///
+    template<class Coordination, class Value0, class... ValueN>
+    auto merge(Coordination cn, Value0 v0, ValueN... vn) const
+        ->  typename std::enable_if<
+                        defer_merge_from<Coordination, Value0>::value,
+            typename    defer_merge_from<Coordination, Value0>::observable_type>::type {
+        return          defer_merge_from<Coordination, Value0>::make(*this, rxs::from(this->as_dynamic(), v0.as_dynamic(), vn.as_dynamic()...), std::move(cn));
+    }
+
+    /// flat_map (AKA SelectMany) ->
+    /// All sources must be synchronized! This means that calls across all the subscribers must be serial.
+    /// for each item from this observable use the CollectionSelector to select an observable and subscribe to that observable.
+    /// for each item from all of the selected observables use the ResultSelector to select a value to emit from the new observable that is returned.
+    ///
+    template<class CollectionSelector, class ResultSelector>
+    auto flat_map(CollectionSelector&& s, ResultSelector&& rs) const
+        ->      observable<typename rxo::detail::flat_map<this_type, CollectionSelector, ResultSelector, identity_one_worker>::value_type,  rxo::detail::flat_map<this_type, CollectionSelector, ResultSelector, identity_one_worker>> {
+        return  observable<typename rxo::detail::flat_map<this_type, CollectionSelector, ResultSelector, identity_one_worker>::value_type,  rxo::detail::flat_map<this_type, CollectionSelector, ResultSelector, identity_one_worker>>(
+                                                                                                                                            rxo::detail::flat_map<this_type, CollectionSelector, ResultSelector, identity_one_worker>(*this, std::forward<CollectionSelector>(s), std::forward<ResultSelector>(rs), identity_current_thread()));
+    }
+
+    /// flat_map (AKA SelectMany) ->
+    /// The coodination is used to synchronize sources from different contexts.
+    /// for each item from this observable use the CollectionSelector to select an observable and subscribe to that observable.
+    /// for each item from all of the selected observables use the ResultSelector to select a value to emit from the new observable that is returned.
+    ///
+    template<class CollectionSelector, class ResultSelector, class Coordination>
+    auto flat_map(CollectionSelector&& s, ResultSelector&& rs, Coordination&& sf) const
+        ->      observable<typename rxo::detail::flat_map<this_type, CollectionSelector, ResultSelector, Coordination>::value_type, rxo::detail::flat_map<this_type, CollectionSelector, ResultSelector, Coordination>> {
+        return  observable<typename rxo::detail::flat_map<this_type, CollectionSelector, ResultSelector, Coordination>::value_type, rxo::detail::flat_map<this_type, CollectionSelector, ResultSelector, Coordination>>(
+                                                                                                                                    rxo::detail::flat_map<this_type, CollectionSelector, ResultSelector, Coordination>(*this, std::forward<CollectionSelector>(s), std::forward<ResultSelector>(rs), std::forward<Coordination>(sf)));
+    }
+
+    template<class Coordination>
+    struct defer_concat : public defer_observable<
+        is_observable<value_type>,
+        this_type,
+        rxo::detail::concat, value_type, observable<value_type>, Coordination>
+    {
+    };
+
+    /// concat ->
+    /// All sources must be synchronized! This means that calls across all the subscribers must be serial.
+    /// for each item from this observable subscribe to one at a time. in the order received.
+    /// for each item from all of the nested observables deliver from the new observable that is returned.
+    ///
+    auto concat() const
+        -> typename defer_concat<identity_one_worker>::observable_type {
+        return      defer_concat<identity_one_worker>::make(*this, *this, identity_current_thread());
+    }
+
+    /// concat ->
+    /// The coordination is used to synchronize sources from different contexts.
+    /// for each item from this observable subscribe to one at a time. in the order received.
+    /// for each item from all of the nested observables deliver from the new observable that is returned.
+    ///
+    template<class Coordination>
+    auto concat(Coordination cn) const
+        ->  typename std::enable_if<
+                        defer_concat<Coordination>::value,
+            typename    defer_concat<Coordination>::observable_type>::type {
+        return          defer_concat<Coordination>::make(*this, *this, std::move(cn));
+    }
+
+    template<class Coordination, class Value0>
+    struct defer_concat_from : public defer_observable<
+        rxu::all_true<
+            is_coordination<Coordination>::value,
+            is_observable<Value0>::value>,
+        this_type,
+        rxo::detail::concat, observable<value_type>, observable<observable<value_type>>, Coordination>
+    {
+    };
+
+    /// concat ->
+    /// All sources must be synchronized! This means that calls across all the subscribers must be serial.
+    /// for each item from this observable subscribe to one at a time. in the order received.
+    /// for each item from all of the nested observables deliver from the new observable that is returned.
+    ///
+    template<class Value0, class... ValueN>
+    auto concat(Value0 v0, ValueN... vn) const
+        ->  typename std::enable_if<
+                        defer_concat_from<identity_one_worker, Value0>::value,
+            typename    defer_concat_from<identity_one_worker, Value0>::observable_type>::type {
+        return          defer_concat_from<identity_one_worker, Value0>::make(*this, rxs::from(this->as_dynamic(), v0.as_dynamic(), vn.as_dynamic()...), identity_current_thread());
+    }
+
+    /// concat ->
+    /// The coordination is used to synchronize sources from different contexts.
+    /// for each item from this observable subscribe to one at a time. in the order received.
+    /// for each item from all of the nested observables deliver from the new observable that is returned.
+    ///
+    template<class Coordination, class Value0, class... ValueN>
+    auto concat(Coordination cn, Value0 v0, ValueN... vn) const
+        ->  typename std::enable_if<
+                        defer_concat_from<Coordination, Value0>::value,
+            typename    defer_concat_from<Coordination, Value0>::observable_type>::type {
+        return          defer_concat_from<Coordination, Value0>::make(*this, rxs::from(this->as_dynamic(), v0.as_dynamic(), vn.as_dynamic()...), std::move(cn));
+    }
+
+    /// concat_map ->
+    /// All sources must be synchronized! This means that calls across all the subscribers must be serial.
+    /// for each item from this observable use the CollectionSelector to select an observable and subscribe to that observable.
+    /// for each item from all of the selected observables use the ResultSelector to select a value to emit from the new observable that is returned.
+    ///
+    template<class CollectionSelector, class ResultSelector>
+    auto concat_map(CollectionSelector&& s, ResultSelector&& rs) const
+        ->      observable<typename rxo::detail::concat_map<this_type, CollectionSelector, ResultSelector, identity_one_worker>::value_type,    rxo::detail::concat_map<this_type, CollectionSelector, ResultSelector, identity_one_worker>> {
+        return  observable<typename rxo::detail::concat_map<this_type, CollectionSelector, ResultSelector, identity_one_worker>::value_type,    rxo::detail::concat_map<this_type, CollectionSelector, ResultSelector, identity_one_worker>>(
+                                                                                                                                                rxo::detail::concat_map<this_type, CollectionSelector, ResultSelector, identity_one_worker>(*this, std::forward<CollectionSelector>(s), std::forward<ResultSelector>(rs), identity_current_thread()));
+    }
+
+    /// concat_map ->
+    /// The coordination is used to synchronize sources from different contexts.
+    /// for each item from this observable use the CollectionSelector to select an observable and subscribe to that observable.
+    /// for each item from all of the selected observables use the ResultSelector to select a value to emit from the new observable that is returned.
+    ///
+    template<class CollectionSelector, class ResultSelector, class Coordination>
+    auto concat_map(CollectionSelector&& s, ResultSelector&& rs, Coordination&& sf) const
+        ->      observable<typename rxo::detail::concat_map<this_type, CollectionSelector, ResultSelector, Coordination>::value_type,   rxo::detail::concat_map<this_type, CollectionSelector, ResultSelector, Coordination>> {
+        return  observable<typename rxo::detail::concat_map<this_type, CollectionSelector, ResultSelector, Coordination>::value_type,   rxo::detail::concat_map<this_type, CollectionSelector, ResultSelector, Coordination>>(
+                                                                                                                                        rxo::detail::concat_map<this_type, CollectionSelector, ResultSelector, Coordination>(*this, std::forward<CollectionSelector>(s), std::forward<ResultSelector>(rs), std::forward<Coordination>(sf)));
+    }
+
+    template<class Coordination, class Selector, class... ObservableN>
+    struct defer_combine_latest : public defer_observable<
+        rxu::all_true<is_coordination<Coordination>::value, !is_coordination<Selector>::value, !is_observable<Selector>::value, is_observable<ObservableN>::value...>,
+        this_type,
+        rxo::detail::combine_latest, Coordination, Selector, ObservableN...>
+    {
+    };
+
+    /// combine_latest ->
+    /// All sources must be synchronized! This means that calls across all the subscribers must be serial.
+    /// for each item from all of the observables use the Selector to select a value to emit from the new observable that is returned.
+    ///
+    template<class Selector, class... ObservableN>
+    auto combine_latest(Selector&& s, ObservableN... on) const
+        ->  typename std::enable_if<
+                        defer_combine_latest<identity_one_worker, Selector, this_type, ObservableN...>::value,
+            typename    defer_combine_latest<identity_one_worker, Selector, this_type, ObservableN...>::observable_type>::type {
+        return          defer_combine_latest<identity_one_worker, Selector, this_type, ObservableN...>::make(*this, identity_current_thread(), std::forward<Selector>(s), std::make_tuple(*this, on...));
+    }
+
+    /// combine_latest ->
+    /// The coordination is used to synchronize sources from different contexts.
+    /// for each item from all of the observables use the Selector to select a value to emit from the new observable that is returned.
+    ///
+    template<class Coordination, class Selector, class... ObservableN>
+    auto combine_latest(Coordination cn, Selector&& s, ObservableN... on) const
+        ->  typename std::enable_if<
+                        defer_combine_latest<Coordination, Selector, this_type, ObservableN...>::value,
+            typename    defer_combine_latest<Coordination, Selector, this_type, ObservableN...>::observable_type>::type {
+        return          defer_combine_latest<Coordination, Selector, this_type, ObservableN...>::make(*this, std::move(cn), std::forward<Selector>(s), std::make_tuple(*this, on...));
+    }
+
+    /// combine_latest ->
+    /// All sources must be synchronized! This means that calls across all the subscribers must be serial.
+    /// for each item from all of the observables use the Selector to select a value to emit from the new observable that is returned.
+    ///
+    template<class... ObservableN>
+    auto combine_latest(ObservableN... on) const
+        ->  typename std::enable_if<
+                        defer_combine_latest<identity_one_worker, rxu::detail::pack, this_type, ObservableN...>::value,
+            typename    defer_combine_latest<identity_one_worker, rxu::detail::pack, this_type, ObservableN...>::observable_type>::type {
+        return          defer_combine_latest<identity_one_worker, rxu::detail::pack, this_type, ObservableN...>::make(*this, identity_current_thread(), rxu::pack(), std::make_tuple(*this, on...));
+    }
+
+    /// combine_latest ->
+    /// The coordination is used to synchronize sources from different contexts.
+    /// for each item from all of the observables use the Selector to select a value to emit from the new observable that is returned.
+    ///
+    template<class Coordination, class... ObservableN>
+    auto combine_latest(Coordination cn, ObservableN... on) const
+        ->  typename std::enable_if<
+                        defer_combine_latest<Coordination, rxu::detail::pack, this_type, ObservableN...>::value,
+            typename    defer_combine_latest<Coordination, rxu::detail::pack, this_type, ObservableN...>::observable_type>::type {
+        return          defer_combine_latest<Coordination, rxu::detail::pack, this_type, ObservableN...>::make(*this, std::move(cn), rxu::pack(), std::make_tuple(*this, on...));
+    }
+
+    /// group_by ->
+    ///
+    template<class KeySelector, class MarbleSelector, class BinaryPredicate>
+    inline auto group_by(KeySelector ks, MarbleSelector ms, BinaryPredicate p) const
+        -> decltype(EXPLICIT_THIS lift<typename rxo::detail::group_by_traits<T, this_type, KeySelector, MarbleSelector, BinaryPredicate>::grouped_observable_type>(rxo::detail::group_by<T, this_type, KeySelector, MarbleSelector, BinaryPredicate>(std::move(ks), std::move(ms), std::move(p)))) {
+        return                    lift<typename rxo::detail::group_by_traits<T, this_type, KeySelector, MarbleSelector, BinaryPredicate>::grouped_observable_type>(rxo::detail::group_by<T, this_type, KeySelector, MarbleSelector, BinaryPredicate>(std::move(ks), std::move(ms), std::move(p)));
+    }
+
+    /// group_by ->
+    ///
+    template<class KeySelector, class MarbleSelector>
+    inline auto group_by(KeySelector ks, MarbleSelector ms) const
+        -> decltype(EXPLICIT_THIS lift<typename rxo::detail::group_by_traits<T, this_type, KeySelector, MarbleSelector, rxu::less>::grouped_observable_type>(rxo::detail::group_by<T, this_type, KeySelector, MarbleSelector, rxu::less>(std::move(ks), std::move(ms), rxu::less()))) {
+        return                    lift<typename rxo::detail::group_by_traits<T, this_type, KeySelector, MarbleSelector, rxu::less>::grouped_observable_type>(rxo::detail::group_by<T, this_type, KeySelector, MarbleSelector, rxu::less>(std::move(ks), std::move(ms), rxu::less()));
+    }
+
+    /// multicast ->
+    /// allows connections to the source to be independent of subscriptions
+    ///
+    template<class Subject>
+    auto multicast(Subject sub) const
+        ->      connectable_observable<T,   rxo::detail::multicast<T, this_type, Subject>> {
+        return  connectable_observable<T,   rxo::detail::multicast<T, this_type, Subject>>(
+                                            rxo::detail::multicast<T, this_type, Subject>(*this, std::move(sub)));
+    }
+
+    /// publish_synchronized ->
+    /// turns a cold observable hot and allows connections to the source to be independent of subscriptions.
+    /// all values are queued and delivered using the scheduler from the supplied coordination
+    ///
+    template<class Coordination>
+    auto publish_synchronized(Coordination cn, composite_subscription cs = composite_subscription()) const
+        -> decltype(EXPLICIT_THIS multicast(rxsub::synchronize<T, Coordination>(std::move(cn), cs))) {
+        return                    multicast(rxsub::synchronize<T, Coordination>(std::move(cn), cs));
+    }
+
+    /// publish ->
+    /// turns a cold observable hot and allows connections to the source to be independent of subscriptions
+    /// NOTE: multicast of a subject
+    ///
+    auto publish(composite_subscription cs = composite_subscription()) const
+        -> decltype(EXPLICIT_THIS multicast(rxsub::subject<T>(cs))) {
+        return                    multicast(rxsub::subject<T>(cs));
+    }
+
+    /// publish ->
+    /// turns a cold observable hot, sends the most recent value to any new subscriber and allows connections to the source to be independent of subscriptions
+    /// NOTE: multicast of a behavior
+    ///
+    auto publish(T first, composite_subscription cs = composite_subscription()) const
+        -> decltype(EXPLICIT_THIS multicast(rxsub::behavior<T>(first, cs))) {
+        return      multicast(rxsub::behavior<T>(first, cs));
+    }
+
+    /// subscribe_on ->
+    /// subscription and unsubscription are queued and delivered using the scheduler from the supplied coordination
+    ///
+    template<class Coordination>
+    auto subscribe_on(Coordination cn) const
+        ->      observable<typename rxo::detail::subscribe_on<T, this_type, Coordination>::value_type,  rxo::detail::subscribe_on<T, this_type, Coordination>> {
+        return  observable<typename rxo::detail::subscribe_on<T, this_type, Coordination>::value_type,  rxo::detail::subscribe_on<T, this_type, Coordination>>(
+                                                                                                        rxo::detail::subscribe_on<T, this_type, Coordination>(*this, std::move(cn)));
+    }
+
+    /// observe_on ->
+    /// all values are queued and delivered using the scheduler from the supplied coordination
+    ///
+    template<class Coordination>
+    auto observe_on(Coordination cn) const
+        -> decltype(EXPLICIT_THIS lift<T>(rxo::detail::observe_on<T, Coordination>(std::move(cn)))) {
+        return                    lift<T>(rxo::detail::observe_on<T, Coordination>(std::move(cn)));
+    }
+
+    /// reduce ->
+    /// for each item from this observable use Accumulator to combine items, when completed use ResultSelector to produce a value that will be emitted from the new observable that is returned.
+    ///
+    template<class Seed, class Accumulator, class ResultSelector>
+    auto reduce(Seed seed, Accumulator&& a, ResultSelector&& rs) const
+        ->      observable<typename rxo::detail::reduce<T, source_operator_type, Accumulator, ResultSelector, Seed>::value_type,    rxo::detail::reduce<T, source_operator_type, Accumulator, ResultSelector, Seed>> {
+        return  observable<typename rxo::detail::reduce<T, source_operator_type, Accumulator, ResultSelector, Seed>::value_type,    rxo::detail::reduce<T, source_operator_type, Accumulator, ResultSelector, Seed>>(
+                                                                                                                                    rxo::detail::reduce<T, source_operator_type, Accumulator, ResultSelector, Seed>(source_operator, std::forward<Accumulator>(a), std::forward<ResultSelector>(rs), seed));
+    }
+
+    template<class Seed, class Accumulator, class ResultSelector>
+    struct defer_reduce : public defer_observable<
+        rxu::all_true<
+            rxu::defer_trait<rxo::detail::is_accumulate_function_for, T, Seed, Accumulator>::value,
+            rxu::defer_trait<rxo::detail::is_result_function_for, Seed, ResultSelector>::value>,
+        void,
+        rxo::detail::reduce, T, source_operator_type, Accumulator, ResultSelector, Seed>
+    {
+    };
+
+    /// first ->
+    /// for each item from this observable reduce it by sending only the first item.
+    ///
+    auto first() const
+        -> observable<T>;
+
+    /// last ->
+    /// for each item from this observable reduce it by sending only the last item.
+    ///
+    auto last() const
+        -> observable<T>;
+
+    /// count ->
+    /// for each item from this observable reduce it by incrementing a count.
+    ///
+    auto count() const
+        -> observable<int>;
+
+    /// sum ->
+    /// for each item from this observable reduce it by adding to the previous items.
+    ///
+    auto sum() const
+        -> typename defer_reduce<rxu::defer_seed_type<rxo::detail::initialize_seeder, T>, rxu::plus, rxu::defer_type<identity_for, T>>::observable_type {
+        return      defer_reduce<rxu::defer_seed_type<rxo::detail::initialize_seeder, T>, rxu::plus, rxu::defer_type<identity_for, T>>::make(source_operator, rxu::plus(), identity_for<T>(), rxo::detail::initialize_seeder<T>().seed());
+    }
+
+    /// average ->
+    /// for each item from this observable reduce it by adding to the previous values and then dividing by the number of items at the end.
+    ///
+    auto average() const
+        -> typename defer_reduce<rxu::defer_seed_type<rxo::detail::average, T>, rxu::defer_type<rxo::detail::average, T>, rxu::defer_type<rxo::detail::average, T>>::observable_type {
+        return      defer_reduce<rxu::defer_seed_type<rxo::detail::average, T>, rxu::defer_type<rxo::detail::average, T>, rxu::defer_type<rxo::detail::average, T>>::make(source_operator, rxo::detail::average<T>(), rxo::detail::average<T>(), rxo::detail::average<T>().seed());
+    }
+
+    /// scan ->
+    /// for each item from this observable use Accumulator to combine items into a value that will be emitted from the new observable that is returned.
+    ///
+    template<class Seed, class Accumulator>
+    auto scan(Seed seed, Accumulator&& a) const
+        ->      observable<Seed,    rxo::detail::scan<T, this_type, Accumulator, Seed>> {
+        return  observable<Seed,    rxo::detail::scan<T, this_type, Accumulator, Seed>>(
+                                    rxo::detail::scan<T, this_type, Accumulator, Seed>(*this, std::forward<Accumulator>(a), seed));
+    }
+
+    /// skip ->
+    /// make new observable with skipped first count items from this observable
+    ///
+    ///
+    template<class Count>
+    auto skip(Count t) const
+        ->      observable<T,   rxo::detail::skip<T, this_type, Count>> {
+        return  observable<T,   rxo::detail::skip<T, this_type, Count>>(
+                                rxo::detail::skip<T, this_type, Count>(*this, t));
+    }
+
+    /// skip_until ->
+    /// All sources must be synchronized! This means that calls across all the subscribers must be serial.
+    /// make new observable with items skipped until on_next occurs on the TriggerSource
+    ///
+    ///
+    template<class TriggerSource>
+    auto skip_until(TriggerSource&& t) const
+        -> typename std::enable_if<is_observable<TriggerSource>::value,
+                observable<T,   rxo::detail::skip_until<T, this_type, TriggerSource, identity_one_worker>>>::type {
+        return  observable<T,   rxo::detail::skip_until<T, this_type, TriggerSource, identity_one_worker>>(
+                                rxo::detail::skip_until<T, this_type, TriggerSource, identity_one_worker>(*this, std::forward<TriggerSource>(t), identity_one_worker(rxsc::make_current_thread())));
+    }
+
+    /// skip_until ->
+    /// The coordination is used to synchronize sources from different contexts.
+    /// make new observable with items skipped until on_next occurs on the TriggerSource
+    ///
+    ///
+    template<class TriggerSource, class Coordination>
+    auto skip_until(TriggerSource&& t, Coordination&& sf) const
+        -> typename std::enable_if<is_observable<TriggerSource>::value && is_coordination<Coordination>::value,
+                observable<T,   rxo::detail::skip_until<T, this_type, TriggerSource, Coordination>>>::type {
+        return  observable<T,   rxo::detail::skip_until<T, this_type, TriggerSource, Coordination>>(
+                                rxo::detail::skip_until<T, this_type, TriggerSource, Coordination>(*this, std::forward<TriggerSource>(t), std::forward<Coordination>(sf)));
+    }
+
+    /// take ->
+    /// for the first count items from this observable emit them from the new observable that is returned.
+    ///
+    ///
+    template<class Count>
+    auto take(Count t) const
+        ->      observable<T,   rxo::detail::take<T, this_type, Count>> {
+        return  observable<T,   rxo::detail::take<T, this_type, Count>>(
+                                rxo::detail::take<T, this_type, Count>(*this, t));
+    }
+
+    /// take_until ->
+    /// All sources must be synchronized! This means that calls across all the subscribers must be serial.
+    /// for each item from this observable until on_next occurs on the TriggerSource, emit them from the new observable that is returned.
+    ///
+    ///
+    template<class TriggerSource>
+    auto take_until(TriggerSource t) const
+        -> typename std::enable_if<is_observable<TriggerSource>::value,
+                observable<T,   rxo::detail::take_until<T, this_type, TriggerSource, identity_one_worker>>>::type {
+        return  observable<T,   rxo::detail::take_until<T, this_type, TriggerSource, identity_one_worker>>(
+                                rxo::detail::take_until<T, this_type, TriggerSource, identity_one_worker>(*this, std::move(t), identity_current_thread()));
+    }
+
+    /// take_until ->
+    /// The coordination is used to synchronize sources from different contexts.
+    /// for each item from this observable until on_next occurs on the TriggerSource, emit them from the new observable that is returned.
+    ///
+    ///
+    template<class TriggerSource, class Coordination>
+    auto take_until(TriggerSource t, Coordination sf) const
+        -> typename std::enable_if<is_observable<TriggerSource>::value && is_coordination<Coordination>::value,
+                observable<T,   rxo::detail::take_until<T, this_type, TriggerSource, Coordination>>>::type {
+        return  observable<T,   rxo::detail::take_until<T, this_type, TriggerSource, Coordination>>(
+                                rxo::detail::take_until<T, this_type, TriggerSource, Coordination>(*this, std::move(t), std::move(sf)));
+    }
+
+    /// take_until ->
+    /// All sources must be synchronized! This means that calls across all the subscribers must be serial.
+    /// for each item from this observable until the specified time, emit them from the new observable that is returned.
+    ///
+    ///
+    template<class TimePoint>
+    auto take_until(TimePoint when) const
+        -> typename std::enable_if<std::is_convertible<TimePoint, rxsc::scheduler::clock_type::time_point>::value,
+                observable<T,   rxo::detail::take_until<T, this_type, decltype(rxs::interval(when, identity_current_thread())), identity_one_worker>>>::type {
+        auto cn = identity_current_thread();
+        return  take_until(rxs::interval(when, cn), cn);
+    }
+
+    /// take_until ->
+    /// The coordination is used to synchronize sources from different contexts.
+    /// for each item from this observable until the specified time, emit them from the new observable that is returned.
+    ///
+    ///
+    template<class Coordination>
+    auto take_until(rxsc::scheduler::clock_type::time_point when, Coordination cn) const
+        -> typename std::enable_if<is_coordination<Coordination>::value,
+                observable<T,   rxo::detail::take_until<T, this_type, decltype(rxs::interval(when, cn)), Coordination>>>::type {
+        return  take_until(rxs::interval(when, cn), cn);
+    }
+
+    /// repeat ->
+    /// infinitely repeats this observable
+    ///
+    ///
+    auto repeat() const
+        ->      observable<T, rxo::detail::repeat<T, this_type, int>> {
+        return  observable<T, rxo::detail::repeat<T, this_type, int>>(
+            rxo::detail::repeat<T, this_type, int>(*this, 0));
+    }
+
+    /// repeat ->
+    /// repeats this observable for given number of times
+    ///
+    ///
+    template<class Count>
+    auto repeat(Count t) const
+        ->      observable<T, rxo::detail::repeat<T, this_type, Count>> {
+        return  observable<T, rxo::detail::repeat<T, this_type, Count>>(
+            rxo::detail::repeat<T, this_type, Count>(*this, t));
+    }
+
+    /// retry ->
+    /// infinitely retrys this observable
+    ///
+    ///
+    auto retry() const
+        ->      observable<T, rxo::detail::retry<T, this_type, int>> {
+        return  observable<T, rxo::detail::retry<T, this_type, int>>(
+            rxo::detail::retry<T, this_type, int>(*this, 0));
+    }
+
+    /// retry ->
+    /// retrys this observable for given number of times
+    ///
+    ///
+    template<class Count>
+    auto retry(Count t) const
+        ->      observable<T, rxo::detail::retry<T, this_type, Count>> {
+        return  observable<T, rxo::detail::retry<T, this_type, Count>>(
+            rxo::detail::retry<T, this_type, Count>(*this, t));
+    }
+
+    /// start_with ->
+    /// start with the supplied values, then concatenate this observable
+    ///
+    ///
+    template<class Value0, class... ValueN>
+    auto start_with(Value0 v0, ValueN... vn) const
+        -> decltype(rxo::start_with(*(this_type*)nullptr, std::move(v0), std::move(vn)...)) {
+        return      rxo::start_with(*this, std::move(v0), std::move(vn)...);
+    }
+
+};
+
+template<class T, class SourceOperator>
+auto observable<T, SourceOperator>::last() const
+    -> observable<T> {
+    rxu::maybe<T> seed;
+    return this->reduce(seed, [](rxu::maybe<T>, T t){return rxu::maybe<T>(std::move(t));}, [](rxu::maybe<T> result){return result.get();});
+}
+
+template<class T, class SourceOperator>
+auto observable<T, SourceOperator>::first() const
+    -> observable<T> {
+    return this->take(1).last();
+}
+
+template<class T, class SourceOperator>
+auto observable<T, SourceOperator>::count() const
+    -> observable<int> {
+    return this->reduce(0, [](int current, const T&){return ++current;}, [](int result){return result;});
+}
+
+template<class T, class SourceOperator>
+inline bool operator==(const observable<T, SourceOperator>& lhs, const observable<T, SourceOperator>& rhs) {
+    return lhs.source_operator == rhs.source_operator;
+}
+template<class T, class SourceOperator>
+inline bool operator!=(const observable<T, SourceOperator>& lhs, const observable<T, SourceOperator>& rhs) {
+    return !(lhs == rhs);
+}
+
+// observable<> has static methods to construct observable sources and adaptors.
+// observable<> is not constructable
+template<>
+class observable<void, void>
+{
+    ~observable();
+public:
+    template<class T, class OnSubscribe>
+    static auto create(OnSubscribe os)
+        -> decltype(rxs::create<T>(std::move(os))) {
+        return      rxs::create<T>(std::move(os));
+    }
+    template<class T>
+    static auto range(T first = 0, T last = std::numeric_limits<T>::max(), ptrdiff_t step = 1)
+        -> decltype(rxs::range<T>(first, last, step, identity_current_thread())) {
+        return      rxs::range<T>(first, last, step, identity_current_thread());
+    }
+    template<class T, class Coordination>
+    static auto range(T first, T last, ptrdiff_t step, Coordination cn)
+        -> decltype(rxs::range<T>(first, last, step, std::move(cn))) {
+        return      rxs::range<T>(first, last, step, std::move(cn));
+    }
+    template<class T, class Coordination>
+    static auto range(T first, T last, Coordination cn)
+        -> decltype(rxs::range<T>(first, last, std::move(cn))) {
+        return      rxs::range<T>(first, last, std::move(cn));
+    }
+    template<class T, class Coordination>
+    static auto range(T first, Coordination cn)
+        -> decltype(rxs::range<T>(first, std::move(cn))) {
+        return      rxs::range<T>(first, std::move(cn));
+    }
+    template<class T>
+    static auto never()
+        -> decltype(rxs::never<T>()) {
+        return      rxs::never<T>();
+    }
+    template<class ObservableFactory>
+    static auto defer(ObservableFactory of)
+        -> decltype(rxs::defer(std::move(of))) {
+        return      rxs::defer(std::move(of));
+    }
+    static auto interval(rxsc::scheduler::clock_type::time_point when)
+        -> decltype(rxs::interval(when)) {
+        return      rxs::interval(when);
+    }
+    template<class Coordination>
+    static auto interval(rxsc::scheduler::clock_type::time_point when, Coordination cn)
+        -> decltype(rxs::interval(when, std::move(cn))) {
+        return      rxs::interval(when, std::move(cn));
+    }
+    static auto interval(rxsc::scheduler::clock_type::time_point initial, rxsc::scheduler::clock_type::duration period)
+        -> decltype(rxs::interval(initial, period)) {
+        return      rxs::interval(initial, period);
+    }
+    template<class Coordination>
+    static auto interval(rxsc::scheduler::clock_type::time_point initial, rxsc::scheduler::clock_type::duration period, Coordination cn)
+        -> decltype(rxs::interval(initial, period, std::move(cn))) {
+        return      rxs::interval(initial, period, std::move(cn));
+    }
+    template<class Collection>
+    static auto iterate(Collection c)
+        -> decltype(rxs::iterate(std::move(c), identity_current_thread())) {
+        return      rxs::iterate(std::move(c), identity_current_thread());
+    }
+    template<class Collection, class Coordination>
+    static auto iterate(Collection c, Coordination cn)
+        -> decltype(rxs::iterate(std::move(c), std::move(cn))) {
+        return      rxs::iterate(std::move(c), std::move(cn));
+    }
+    template<class T>
+    static auto from()
+        -> decltype(    rxs::from<T>()) {
+        return          rxs::from<T>();
+    }
+    template<class T, class Coordination>
+    static auto from(Coordination cn)
+        -> typename std::enable_if<is_coordination<Coordination>::value,
+            decltype(   rxs::from<T>(std::move(cn)))>::type {
+        return          rxs::from<T>(std::move(cn));
+    }
+    template<class Value0, class... ValueN>
+    static auto from(Value0 v0, ValueN... vn)
+        -> typename std::enable_if<!is_coordination<Value0>::value,
+            decltype(   rxs::from(v0, vn...))>::type {
+        return          rxs::from(v0, vn...);
+    }
+    template<class Coordination, class Value0, class... ValueN>
+    static auto from(Coordination cn, Value0 v0, ValueN... vn)
+        -> typename std::enable_if<is_coordination<Coordination>::value,
+            decltype(   rxs::from(std::move(cn), v0, vn...))>::type {
+        return          rxs::from(std::move(cn), v0, vn...);
+    }
+    template<class T>
+    static auto empty()
+        -> decltype(from<T>()) {
+        return      from<T>();
+    }
+    template<class T, class Coordination>
+    static auto empty(Coordination cn)
+        -> decltype(from(std::move(cn), std::array<T, 0>())) {
+        return      from(std::move(cn), std::array<T, 0>());
+    }
+    template<class T>
+    static auto just(T v)
+        -> decltype(from(std::move(v))) {
+        return      from(std::move(v));
+    }
+    template<class T, class Coordination>
+    static auto just(T v, Coordination cn)
+        -> decltype(from(std::move(cn), std::move(v))) {
+        return      from(std::move(cn), std::move(v));
+    }
+    template<class T, class Exception>
+    static auto error(Exception&& e)
+        -> decltype(rxs::error<T>(std::forward<Exception>(e))) {
+        return      rxs::error<T>(std::forward<Exception>(e));
+    }
+    template<class T, class Exception, class Coordination>
+    static auto error(Exception&& e, Coordination cn)
+        -> decltype(rxs::error<T>(std::forward<Exception>(e), std::move(cn))) {
+        return      rxs::error<T>(std::forward<Exception>(e), std::move(cn));
+    }
+    template<class Observable, class Value0, class... ValueN>
+    static auto start_with(Observable o, Value0 v0, ValueN... vn)
+        -> decltype(rxs::from(typename Observable::value_type(v0), typename Observable::value_type(vn)...).concat(o)) {
+        return      rxs::from(typename Observable::value_type(v0), typename Observable::value_type(vn)...).concat(o);
+    }
+    template<class ResourceFactory, class ObservableFactory>
+    static auto scope(ResourceFactory rf, ObservableFactory of)
+        -> decltype(rxs::scope(std::move(rf), std::move(of))) {
+        return      rxs::scope(std::move(rf), std::move(of));
+    }
+};
+
+
+}
+
+//
+// support range() >> filter() >> subscribe() syntax
+// '>>' is spelled 'stream'
+//
+template<class T, class SourceOperator, class OperatorFactory>
+auto operator >> (const rxcpp::observable<T, SourceOperator>& source, OperatorFactory&& of)
+    -> decltype(source.op(std::forward<OperatorFactory>(of))) {
+    return      source.op(std::forward<OperatorFactory>(of));
+}
+
+//
+// support range() | filter() | subscribe() syntax
+// '|' is spelled 'pipe'
+//
+template<class T, class SourceOperator, class OperatorFactory>
+auto operator | (const rxcpp::observable<T, SourceOperator>& source, OperatorFactory&& of)
+    -> decltype(source.op(std::forward<OperatorFactory>(of))) {
+    return      source.op(std::forward<OperatorFactory>(of));
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/rx-observer.hpp b/dependencies64/RxCpp/include/rxcpp/rx-observer.hpp
new file mode 100644 (file)
index 0000000..6fad944
--- /dev/null
@@ -0,0 +1,422 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_RX_OBSERVER_HPP)
+#define RXCPP_RX_OBSERVER_HPP
+
+#include "rx-includes.hpp"
+
+namespace rxcpp {
+
+
+template<class T>
+struct observer_base
+{
+    typedef T value_type;
+    typedef tag_observer observer_tag;
+};
+
+namespace detail {
+template<class T>
+struct OnNextEmpty
+{
+    void operator()(const T&) const {}
+};
+struct OnErrorEmpty
+{
+    void operator()(std::exception_ptr) const {
+        // error implicitly ignored, abort
+        abort();
+    }
+};
+struct OnCompletedEmpty
+{
+    void operator()() const {}
+};
+
+template<class T, class F>
+struct is_on_next_of
+{
+    struct not_void {};
+    template<class CT, class CF>
+    static auto check(int) -> decltype((*(CF*)nullptr)(*(CT*)nullptr));
+    template<class CT, class CF>
+    static not_void check(...);
+
+    typedef decltype(check<T, typename std::decay<F>::type>(0)) detail_result;
+    static const bool value = std::is_same<detail_result, void>::value;
+};
+
+template<class F>
+struct is_on_error
+{
+    struct not_void {};
+    template<class CF>
+    static auto check(int) -> decltype((*(CF*)nullptr)(*(std::exception_ptr*)nullptr));
+    template<class CF>
+    static not_void check(...);
+
+    static const bool value = std::is_same<decltype(check<typename std::decay<F>::type>(0)), void>::value;
+};
+
+template<class F>
+struct is_on_completed
+{
+    struct not_void {};
+    template<class CF>
+    static auto check(int) -> decltype((*(CF*)nullptr)());
+    template<class CF>
+    static not_void check(...);
+
+    static const bool value = std::is_same<decltype(check<typename std::decay<F>::type>(0)), void>::value;
+};
+
+}
+
+template<class T, class OnNext, class OnError = detail::OnErrorEmpty, class OnCompleted = detail::OnCompletedEmpty>
+class static_observer
+{
+public:
+    typedef static_observer<T, OnNext, OnError, OnCompleted> this_type;
+    typedef typename std::decay<OnNext>::type on_next_t;
+    typedef typename std::decay<OnError>::type on_error_t;
+    typedef typename std::decay<OnCompleted>::type on_completed_t;
+
+private:
+    on_next_t onnext;
+    on_error_t onerror;
+    on_completed_t oncompleted;
+
+public:
+    static_assert(detail::is_on_next_of<T, on_next_t>::value,     "Function supplied for on_next must be a function with the signature void(T);");
+    static_assert(detail::is_on_error<on_error_t>::value,         "Function supplied for on_error must be a function with the signature void(std::exception_ptr);");
+    static_assert(detail::is_on_completed<on_completed_t>::value, "Function supplied for on_completed must be a function with the signature void();");
+
+    explicit static_observer(on_next_t n, on_error_t e = on_error_t(), on_completed_t c = on_completed_t())
+        : onnext(std::move(n))
+        , onerror(std::move(e))
+        , oncompleted(std::move(c))
+    {
+    }
+    static_observer(const this_type& o)
+        : onnext(o.onnext)
+        , onerror(o.onerror)
+        , oncompleted(o.oncompleted)
+    {
+    }
+    static_observer(this_type&& o)
+        : onnext(std::move(o.onnext))
+        , onerror(std::move(o.onerror))
+        , oncompleted(std::move(o.oncompleted))
+    {
+    }
+    this_type& operator=(this_type o) {
+        onnext = std::move(o.onnext);
+        onerror = std::move(o.onerror);
+        oncompleted = std::move(o.oncompleted);
+        return *this;
+    }
+
+    // use V so that std::move can be used safely
+    template<class V>
+    void on_next(V v) const {
+        onnext(std::move(v));
+    }
+    void on_error(std::exception_ptr e) const {
+        onerror(e);
+    }
+    void on_completed() const {
+        oncompleted();
+    }
+};
+
+template<class T>
+class dynamic_observer
+{
+public:
+    typedef tag_dynamic_observer dynamic_observer_tag;
+
+private:
+    typedef dynamic_observer<T> this_type;
+    typedef observer_base<T> base_type;
+
+    struct virtual_observer : public std::enable_shared_from_this<virtual_observer>
+    {
+        virtual void on_next(T) const =0;
+        virtual void on_error(std::exception_ptr e) const =0;
+        virtual void on_completed() const =0;
+    };
+
+    template<class Observer>
+    struct specific_observer : public virtual_observer
+    {
+        explicit specific_observer(Observer o)
+            : destination(std::move(o))
+        {
+        }
+
+        Observer destination;
+        virtual void on_next(T t) const {
+            destination.on_next(std::move(t));
+        }
+        virtual void on_error(std::exception_ptr e) const {
+            destination.on_error(e);
+        }
+        virtual void on_completed() const {
+            destination.on_completed();
+        }
+    };
+
+    std::shared_ptr<virtual_observer> destination;
+
+    template<class Observer>
+    static auto make_destination(Observer o)
+        -> std::shared_ptr<virtual_observer> {
+        return std::make_shared<specific_observer<Observer>>(std::move(o));
+    }
+
+public:
+    dynamic_observer()
+    {
+    }
+    dynamic_observer(const this_type& o)
+        : destination(o.destination)
+    {
+    }
+    dynamic_observer(this_type&& o)
+        : destination(std::move(o.destination))
+    {
+    }
+
+    template<class Observer>
+    explicit dynamic_observer(Observer o)
+        : destination(make_destination(std::move(o)))
+    {
+    }
+
+    this_type& operator=(this_type o) {
+        destination = std::move(o.destination);
+        return *this;
+    }
+
+    // perfect forwarding delays the copy of the value.
+    template<class V>
+    void on_next(V&& v) const {
+        if (destination) {
+            destination->on_next(std::forward<V>(v));
+        }
+    }
+    void on_error(std::exception_ptr e) const {
+        if (destination) {
+            destination->on_error(e);
+        }
+    }
+    void on_completed() const {
+        if (destination) {
+            destination->on_completed();
+        }
+    }
+};
+
+
+template<class T, class I>
+class observer : public observer_base<T>
+{
+    typedef observer<T, I> this_type;
+    typedef typename std::decay<I>::type inner_t;
+
+    inner_t inner;
+
+    observer();
+public:
+    ~observer()
+    {
+    }
+    observer(const this_type& o)
+        : inner(o.inner)
+    {
+    }
+    observer(this_type&& o)
+        : inner(std::move(o.inner))
+    {
+    }
+    explicit observer(inner_t inner)
+        : inner(std::move(inner))
+    {
+    }
+    this_type& operator=(this_type o) {
+        inner = std::move(o.inner);
+        return *this;
+    }
+    template<class V>
+    void on_next(V&& v) const {
+        inner.on_next(std::forward<V>(v));
+    }
+    void on_error(std::exception_ptr e) const {
+        inner.on_error(e);
+    }
+    void on_completed() const {
+        inner.on_completed();
+    }
+    observer<T> as_dynamic() const {
+        return observer<T>(dynamic_observer<T>(inner));
+    }
+};
+template<class T>
+class observer<T, void> : public observer_base<T>
+{
+    typedef observer this_type;
+public:
+    observer()
+    {
+    }
+    template<class V>
+    void on_next(V&&) const {
+    }
+    void on_error(std::exception_ptr) const {
+    }
+    void on_completed() const {
+    }
+};
+
+template<class T>
+auto make_observer()
+    ->     observer<T, void> {
+    return observer<T, void>();
+}
+
+template<class T, class U, class I>
+auto make_observer(observer<U, I> o)
+    ->      observer<T, I> {
+    return  observer<T, I>(std::move(o));
+}
+template<class T, class Observer>
+auto make_observer(Observer ob)
+    -> typename std::enable_if<
+        !detail::is_on_next_of<T, Observer>::value &&
+        !is_observer<Observer>::value,
+            observer<T, Observer>>::type {
+    return  observer<T, Observer>(std::move(ob));
+}
+template<class T, class OnNext>
+auto make_observer(OnNext on)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value,
+            observer<T, static_observer<T, OnNext>>>::type {
+    return  observer<T, static_observer<T, OnNext>>(
+                        static_observer<T, OnNext>(std::move(on)));
+}
+template<class T, class OnNext, class OnError>
+auto make_observer(OnNext on, OnError oe)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value &&
+        detail::is_on_error<OnError>::value,
+            observer<T, static_observer<T, OnNext, OnError>>>::type {
+    return  observer<T, static_observer<T, OnNext, OnError>>(
+                        static_observer<T, OnNext, OnError>(std::move(on), std::move(oe)));
+}
+template<class T, class OnNext, class OnCompleted>
+auto make_observer(OnNext on, OnCompleted oc)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value &&
+        detail::is_on_completed<OnCompleted>::value,
+            observer<T, static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>>>::type {
+    return  observer<T, static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>>(
+                        static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>(std::move(on), detail::OnErrorEmpty(), std::move(oc)));
+}
+template<class T, class OnNext, class OnError, class OnCompleted>
+auto make_observer(OnNext on, OnError oe, OnCompleted oc)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value &&
+        detail::is_on_error<OnError>::value &&
+        detail::is_on_completed<OnCompleted>::value,
+            observer<T, static_observer<T, OnNext, OnError, OnCompleted>>>::type {
+    return  observer<T, static_observer<T, OnNext, OnError, OnCompleted>>(
+                        static_observer<T, OnNext, OnError, OnCompleted>(std::move(on), std::move(oe), std::move(oc)));
+}
+
+
+template<class T, class Observer>
+auto make_observer_dynamic(Observer o)
+    -> typename std::enable_if<
+        is_observer<Observer>::value,
+            observer<T>>::type {
+    return  observer<T>(dynamic_observer<T>(std::move(o)));
+}
+template<class T, class OnNext>
+auto make_observer_dynamic(OnNext&& on)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value,
+            observer<T, dynamic_observer<T>>>::type {
+    return  observer<T, dynamic_observer<T>>(
+                        dynamic_observer<T>(make_observer<T>(std::forward<OnNext>(on))));
+}
+template<class T, class OnNext, class OnError>
+auto make_observer_dynamic(OnNext&& on, OnError&& oe)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value &&
+        detail::is_on_error<OnError>::value,
+            observer<T, dynamic_observer<T>>>::type {
+    return  observer<T, dynamic_observer<T>>(
+                        dynamic_observer<T>(make_observer<T>(std::forward<OnNext>(on), std::forward<OnError>(oe))));
+}
+template<class T, class OnNext, class OnCompleted>
+auto make_observer_dynamic(OnNext&& on, OnCompleted&& oc)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value &&
+        detail::is_on_completed<OnCompleted>::value,
+            observer<T, dynamic_observer<T>>>::type {
+    return  observer<T, dynamic_observer<T>>(
+                        dynamic_observer<T>(make_observer<T>(std::forward<OnNext>(on), std::forward<OnCompleted>(oc))));
+}
+template<class T, class OnNext, class OnError, class OnCompleted>
+auto make_observer_dynamic(OnNext&& on, OnError&& oe, OnCompleted&& oc)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value &&
+        detail::is_on_error<OnError>::value &&
+        detail::is_on_completed<OnCompleted>::value,
+            observer<T, dynamic_observer<T>>>::type {
+    return  observer<T, dynamic_observer<T>>(
+                        dynamic_observer<T>(make_observer<T>(std::forward<OnNext>(on), std::forward<OnError>(oe), std::forward<OnCompleted>(oc))));
+}
+
+namespace detail {
+
+template<class F>
+struct maybe_from_result
+{
+    typedef decltype((*(F*)nullptr)()) decl_result_type;
+    typedef typename std::decay<decl_result_type>::type result_type;
+    typedef rxu::maybe<result_type> type;
+};
+
+}
+
+template<class F, class OnError>
+auto on_exception(const F& f, const OnError& c)
+    ->  typename std::enable_if<detail::is_on_error<OnError>::value, typename detail::maybe_from_result<F>::type>::type {
+    typename detail::maybe_from_result<F>::type r;
+    try {
+        r.reset(f());
+    } catch (...) {
+        c(std::current_exception());
+    }
+    return r;
+}
+
+template<class F, class Subscriber>
+auto on_exception(const F& f, const Subscriber& s)
+    ->  typename std::enable_if<is_subscriber<Subscriber>::value, typename detail::maybe_from_result<F>::type>::type {
+    typename detail::maybe_from_result<F>::type r;
+    try {
+        r.reset(f());
+    } catch (...) {
+        s.on_error(std::current_exception());
+    }
+    return r;
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/rx-operators.hpp b/dependencies64/RxCpp/include/rxcpp/rx-operators.hpp
new file mode 100644 (file)
index 0000000..3b8d21a
--- /dev/null
@@ -0,0 +1,67 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_RX_OPERATORS_HPP)
+#define RXCPP_RX_OPERATORS_HPP
+
+#include "rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace operators {
+
+struct tag_operator {};
+template<class T>
+struct operator_base
+{
+    typedef T value_type;
+    typedef tag_operator operator_tag;
+};
+template<class T>
+class is_operator
+{
+    template<class C>
+    static typename C::operator_tag* check(int);
+    template<class C>
+    static void check(...);
+public:
+    static const bool value = std::is_convertible<decltype(check<typename std::decay<T>::type>(0)), tag_operator*>::value;
+};
+
+}
+namespace rxo=operators;
+
+}
+
+#include "operators/rx-buffer_count.hpp"
+#include "operators/rx-combine_latest.hpp"
+#include "operators/rx-concat.hpp"
+#include "operators/rx-concat_map.hpp"
+#include "operators/rx-connect_forever.hpp"
+#include "operators/rx-distinct_until_changed.hpp"
+#include "operators/rx-filter.hpp"
+#include "operators/rx-finally.hpp"
+#include "operators/rx-flat_map.hpp"
+#include "operators/rx-group_by.hpp"
+#include "operators/rx-lift.hpp"
+#include "operators/rx-map.hpp"
+#include "operators/rx-merge.hpp"
+#include "operators/rx-multicast.hpp"
+#include "operators/rx-observe_on.hpp"
+#include "operators/rx-publish.hpp"
+#include "operators/rx-reduce.hpp"
+#include "operators/rx-ref_count.hpp"
+#include "operators/rx-repeat.hpp"
+#include "operators/rx-scan.hpp"
+#include "operators/rx-skip.hpp"
+#include "operators/rx-skip_until.hpp"
+#include "operators/rx-start_with.hpp"
+#include "operators/rx-subscribe.hpp"
+#include "operators/rx-subscribe_on.hpp"
+#include "operators/rx-switch_on_next.hpp"
+#include "operators/rx-take.hpp"
+#include "operators/rx-take_until.hpp"
+#include "operators/rx-window.hpp"
+#include "operators/rx-retry.hpp"
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/rx-predef.hpp b/dependencies64/RxCpp/include/rxcpp/rx-predef.hpp
new file mode 100644 (file)
index 0000000..bd94151
--- /dev/null
@@ -0,0 +1,258 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_RX_PREDEF_HPP)
+#define RXCPP_RX_PREDEF_HPP
+
+#include "rx-includes.hpp"
+
+namespace rxcpp {
+
+//
+// create a typedef for rxcpp_trace_type to override the default
+//
+inline auto trace_activity() -> decltype(rxcpp_trace_activity(trace_tag()))& {
+    static decltype(rxcpp_trace_activity(trace_tag())) trace;
+    return trace;
+}
+
+
+struct tag_action {};
+template<class T>
+class is_action
+{
+    struct not_void {};
+    template<class C>
+    static typename C::action_tag* check(int);
+    template<class C>
+    static not_void check(...);
+public:
+    static const bool value = std::is_convertible<decltype(check<typename std::decay<T>::type>(0)), tag_action*>::value;
+};
+
+struct tag_worker {};
+template<class T>
+class is_worker
+{
+    struct not_void {};
+    template<class C>
+    static typename C::worker_tag* check(int);
+    template<class C>
+    static not_void check(...);
+public:
+    static const bool value = std::is_convertible<decltype(check<typename std::decay<T>::type>(0)), tag_worker*>::value;
+};
+
+struct tag_scheduler {};
+template<class T>
+class is_scheduler
+{
+    struct not_void {};
+    template<class C>
+    static typename C::scheduler_tag* check(int);
+    template<class C>
+    static not_void check(...);
+public:
+    static const bool value = std::is_convertible<decltype(check<typename std::decay<T>::type>(0)), tag_scheduler*>::value;
+};
+
+struct tag_schedulable {};
+template<class T>
+class is_schedulable
+{
+    struct not_void {};
+    template<class C>
+    static typename C::schedulable_tag* check(int);
+    template<class C>
+    static not_void check(...);
+public:
+    static const bool value = std::is_convertible<decltype(check<typename std::decay<T>::type>(0)), tag_schedulable*>::value;
+};
+
+
+template<class T>
+class dynamic_observer;
+
+template<class T, class I = dynamic_observer<T>>
+class observer;
+
+struct tag_observer {};
+template<class T>
+class is_observer
+{
+    template<class C>
+    static typename C::observer_tag* check(int);
+    template<class C>
+    static void check(...);
+public:
+    static const bool value = std::is_convertible<decltype(check<typename std::decay<T>::type>(0)), tag_observer*>::value;
+};
+
+struct tag_dynamic_observer {};
+template<class T>
+class is_dynamic_observer
+{
+    struct not_void {};
+    template<class C>
+    static typename C::dynamic_observer_tag* check(int);
+    template<class C>
+    static not_void check(...);
+public:
+    static const bool value = std::is_convertible<decltype(check<typename std::decay<T>::type>(0)), tag_dynamic_observer*>::value;
+};
+
+struct tag_subscriber {};
+template<class T>
+class is_subscriber
+{
+    struct not_void {};
+    template<class C>
+    static typename C::subscriber_tag* check(int);
+    template<class C>
+    static not_void check(...);
+public:
+    static const bool value = std::is_convertible<decltype(check<typename std::decay<T>::type>(0)), tag_subscriber*>::value;
+};
+
+struct tag_dynamic_observable {};
+template<class T>
+class is_dynamic_observable
+{
+    struct not_void {};
+    template<class C>
+    static typename C::dynamic_observable_tag* check(int);
+    template<class C>
+    static not_void check(...);
+public:
+    static const bool value = std::is_convertible<decltype(check<typename std::decay<T>::type>(0)), tag_dynamic_observable*>::value;
+};
+
+template<class T>
+class dynamic_observable;
+
+template<
+    class T = void,
+    class SourceObservable = typename std::conditional<std::is_same<T, void>::value,
+        void, dynamic_observable<T>>::type>
+class observable;
+
+template<class T, class Source>
+observable<T> make_observable_dynamic(Source&&);
+
+template<class Selector, class Default, template<class... TN> class SO, class... AN>
+struct defer_observable;
+
+struct tag_observable {};
+template<class T>
+struct observable_base {
+    typedef tag_observable observable_tag;
+    typedef T value_type;
+};
+template<class T>
+class is_observable
+{
+    template<class C>
+    static typename C::observable_tag check(int);
+    template<class C>
+    static void check(...);
+public:
+    static const bool value = std::is_convertible<decltype(check<typename std::decay<T>::type>(0)), tag_observable>::value;
+};
+
+struct tag_dynamic_connectable_observable : public tag_dynamic_observable {};
+
+template<class T>
+class is_dynamic_connectable_observable
+{
+    struct not_void {};
+    template<class C>
+    static typename C::dynamic_observable_tag* check(int);
+    template<class C>
+    static not_void check(...);
+public:
+    static const bool value = std::is_convertible<decltype(check<typename std::decay<T>::type>(0)), tag_dynamic_connectable_observable*>::value;
+};
+
+template<class T>
+class dynamic_connectable_observable;
+
+template<class T,
+    class SourceObservable = typename std::conditional<std::is_same<T, void>::value,
+        void, dynamic_connectable_observable<T>>::type>
+class connectable_observable;
+
+struct tag_connectable_observable : public tag_observable {};
+template<class T>
+class is_connectable_observable
+{
+    template<class C>
+    static typename C::observable_tag check(int);
+    template<class C>
+    static void check(...);
+public:
+    static const bool value = std::is_convertible<decltype(check<typename std::decay<T>::type>(0)), tag_connectable_observable>::value;
+};
+
+struct tag_dynamic_grouped_observable : public tag_dynamic_observable {};
+
+template<class T>
+class is_dynamic_grouped_observable
+{
+    struct not_void {};
+    template<class C>
+    static typename C::dynamic_observable_tag* check(int);
+    template<class C>
+    static not_void check(...);
+public:
+    static const bool value = std::is_convertible<decltype(check<typename std::decay<T>::type>(0)), tag_dynamic_grouped_observable*>::value;
+};
+
+template<class K, class T>
+class dynamic_grouped_observable;
+
+template<class K, class T,
+    class SourceObservable = typename std::conditional<std::is_same<T, void>::value,
+        void, dynamic_grouped_observable<K, T>>::type>
+class grouped_observable;
+
+template<class K, class T, class Source>
+grouped_observable<K, T> make_dynamic_grouped_observable(Source&& s);
+
+struct tag_grouped_observable : public tag_observable {};
+template<class T>
+class is_grouped_observable
+{
+    template<class C>
+    static typename C::observable_tag check(int);
+    template<class C>
+    static void check(...);
+public:
+    static const bool value = std::is_convertible<decltype(check<typename std::decay<T>::type>(0)), tag_grouped_observable>::value;
+};
+
+//
+// this type is the default used by operators that subscribe to
+// multiple sources. It assumes that the sources are already synchronized
+//
+struct identity_observable
+{
+    template<class Observable>
+    auto operator()(Observable o)
+        -> Observable {
+        return      std::move(o);
+        static_assert(is_observable<Observable>::value, "only support observables");
+    }
+};
+
+template<class T>
+struct identity_for
+{
+    T operator()(T t) {
+        return      std::move(t);
+    }
+};
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/rx-scheduler.hpp b/dependencies64/RxCpp/include/rxcpp/rx-scheduler.hpp
new file mode 100644 (file)
index 0000000..df5f681
--- /dev/null
@@ -0,0 +1,885 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_RX_SCHEDULER_HPP)
+#define RXCPP_RX_SCHEDULER_HPP
+
+#include "rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace schedulers {
+
+class worker_interface;
+class scheduler_interface;
+
+namespace detail {
+
+class action_type;
+typedef std::shared_ptr<action_type> action_ptr;
+
+typedef std::shared_ptr<worker_interface> worker_interface_ptr;
+typedef std::shared_ptr<const worker_interface> const_worker_interface_ptr;
+
+typedef std::shared_ptr<scheduler_interface> scheduler_interface_ptr;
+typedef std::shared_ptr<const scheduler_interface> const_scheduler_interface_ptr;
+
+}
+
+// It is essential to keep virtual function calls out of an inner loop.
+// To make tail-recursion work efficiently the recursion objects create
+// a space on the stack inside the virtual function call in the actor that
+// allows the callback and the scheduler to share stack space that records
+// the request and the allowance without any virtual calls in the loop.
+
+/// recursed is set on a schedulable by the action to allow the called
+/// function to request to be rescheduled.
+class recursed
+{
+    bool& isrequested;
+public:
+    explicit recursed(bool& r)
+        : isrequested(r)
+    {
+    }
+    /// request to be rescheduled
+    inline void operator()() const {
+        isrequested = true;
+    }
+};
+
+/// recurse is passed to the action by the scheduler.
+/// the action uses recurse to coordinate the scheduler and the function.
+class recurse
+{
+    bool& isallowed;
+    mutable bool isrequested;
+    recursed requestor;
+public:
+    explicit recurse(bool& a)
+        : isallowed(a)
+        , isrequested(true)
+        , requestor(isrequested)
+    {
+    }
+    /// does the scheduler allow tail-recursion now?
+    inline bool is_allowed() const {
+        return isallowed;
+    }
+    /// did the function request to be recursed?
+    inline bool is_requested() const {
+        return isrequested;
+    }
+    /// reset the function request. call before each call to the function.
+    inline void reset() const {
+        isrequested = false;
+    }
+    /// get the recursed to set into the schedulable for the function to use to request recursion
+    inline const recursed& get_recursed() const {
+        return requestor;
+    }
+};
+
+/// recursion is used by the scheduler to signal to each action whether tail recursion is allowed.
+class recursion
+{
+    mutable bool isallowed;
+    recurse recursor;
+public:
+    recursion()
+        : isallowed(true)
+        , recursor(isallowed)
+    {
+    }
+    explicit recursion(bool b)
+        : isallowed(b)
+        , recursor(isallowed)
+    {
+    }
+    /// set whether tail-recursion is allowed
+    inline void reset(bool b = true) const {
+        isallowed = b;
+    }
+    /// get the recurse to pass into each action being called
+    inline const recurse& get_recurse() const {
+        return recursor;
+    }
+};
+
+
+struct action_base
+{
+    typedef tag_action action_tag;
+};
+
+class schedulable;
+
+/// action provides type-forgetting for a potentially recursive set of calls to a function that takes a schedulable
+class action : public action_base
+{
+    typedef action this_type;
+    detail::action_ptr inner;
+    static detail::action_ptr shared_empty;
+public:
+    action()
+    {
+    }
+    explicit action(detail::action_ptr i)
+    : inner(std::move(i))
+    {
+    }
+
+    /// return the empty action
+    inline static action empty() {
+        return action(shared_empty);
+    }
+
+    /// call the function
+    inline void operator()(const schedulable& s, const recurse& r) const;
+};
+
+struct scheduler_base
+{
+    typedef std::chrono::steady_clock clock_type;
+    typedef tag_scheduler scheduler_tag;
+};
+
+struct worker_base : public subscription_base
+{
+    typedef tag_worker worker_tag;
+};
+
+class worker_interface
+    : public std::enable_shared_from_this<worker_interface>
+{
+    typedef worker_interface this_type;
+
+public:
+    typedef scheduler_base::clock_type clock_type;
+
+    virtual ~worker_interface() {}
+
+    virtual clock_type::time_point now() const = 0;
+
+    virtual void schedule(const schedulable& scbl) const = 0;
+    virtual void schedule(clock_type::time_point when, const schedulable& scbl) const = 0;
+};
+
+namespace detail {
+
+template<class F>
+struct is_action_function
+{
+    struct not_void {};
+    template<class CF>
+    static auto check(int) -> decltype((*(CF*)nullptr)(*(schedulable*)nullptr));
+    template<class CF>
+    static not_void check(...);
+
+    static const bool value = std::is_same<decltype(check<typename std::decay<F>::type>(0)), void>::value;
+};
+
+}
+
+/// a worker ensures that all scheduled actions on the same instance are executed in-order with no overlap
+/// a worker ensures that all scheduled actions are unsubscribed when it is unsubscribed
+/// some inner implementations will impose additional constraints on the execution of items.
+class worker : public worker_base
+{
+    typedef worker this_type;
+    detail::worker_interface_ptr inner;
+    composite_subscription lifetime;
+    friend bool operator==(const worker&, const worker&);
+public:
+    typedef scheduler_base::clock_type clock_type;
+    typedef composite_subscription::weak_subscription weak_subscription;
+
+    worker()
+    {
+    }
+    worker(composite_subscription cs, detail::const_worker_interface_ptr i)
+        : inner(std::const_pointer_cast<worker_interface>(i))
+        , lifetime(std::move(cs))
+    {
+    }
+    worker(composite_subscription cs, worker o)
+        : inner(o.inner)
+        , lifetime(std::move(cs))
+    {
+    }
+
+    inline const composite_subscription& get_subscription() const {
+        return lifetime;
+    }
+    inline composite_subscription& get_subscription() {
+        return lifetime;
+    }
+
+    // composite_subscription
+    //
+    inline bool is_subscribed() const {
+        return lifetime.is_subscribed();
+    }
+    inline weak_subscription add(subscription s) const {
+        return lifetime.add(std::move(s));
+    }
+    inline void remove(weak_subscription w) const {
+        return lifetime.remove(std::move(w));
+    }
+    inline void clear() const {
+        return lifetime.clear();
+    }
+    inline void unsubscribe() const {
+        return lifetime.unsubscribe();
+    }
+
+    // worker_interface
+    //
+    /// return the current time for this worker
+    inline clock_type::time_point now() const {
+        return inner->now();
+    }
+
+    /// insert the supplied schedulable to be run as soon as possible
+    inline void schedule(const schedulable& scbl) const {
+        // force rebinding scbl to this worker
+        schedule_rebind(scbl);
+    }
+
+    /// insert the supplied schedulable to be run at the time specified
+    inline void schedule(clock_type::time_point when, const schedulable& scbl) const {
+        // force rebinding scbl to this worker
+        schedule_rebind(when, scbl);
+    }
+
+    // helpers
+    //
+
+    /// insert the supplied schedulable to be run at now() + the delay specified
+    inline void schedule(clock_type::duration when, const schedulable& scbl) const {
+        // force rebinding scbl to this worker
+        schedule_rebind(now() + when, scbl);
+    }
+
+    /// insert the supplied schedulable to be run at the initial time specified and then again at initial + (N * period)
+    /// this will continue until the worker or schedulable is unsubscribed.
+    inline void schedule_periodically(clock_type::time_point initial, clock_type::duration period, const schedulable& scbl) const {
+        // force rebinding scbl to this worker
+        schedule_periodically_rebind(initial, period, scbl);
+    }
+
+    /// insert the supplied schedulable to be run at now() + the initial delay specified and then again at now() + initial + (N * period)
+    /// this will continue until the worker or schedulable is unsubscribed.
+    inline void schedule_periodically(clock_type::duration initial, clock_type::duration period, const schedulable& scbl) const {
+        // force rebinding scbl to this worker
+        schedule_periodically_rebind(now() + initial, period, scbl);
+    }
+
+    /// use the supplied arguments to make a schedulable and then insert it to be run
+    template<class Arg0, class... ArgN>
+    auto schedule(Arg0&& a0, ArgN&&... an) const
+        -> typename std::enable_if<
+            (detail::is_action_function<Arg0>::value ||
+            is_subscription<Arg0>::value) &&
+            !is_schedulable<Arg0>::value>::type;
+    template<class... ArgN>
+    /// use the supplied arguments to make a schedulable and then insert it to be run
+    void schedule_rebind(const schedulable& scbl, ArgN&&... an) const;
+
+    /// use the supplied arguments to make a schedulable and then insert it to be run
+    template<class Arg0, class... ArgN>
+    auto schedule(clock_type::time_point when, Arg0&& a0, ArgN&&... an) const
+        -> typename std::enable_if<
+            (detail::is_action_function<Arg0>::value ||
+            is_subscription<Arg0>::value) &&
+            !is_schedulable<Arg0>::value>::type;
+    /// use the supplied arguments to make a schedulable and then insert it to be run
+    template<class... ArgN>
+    void schedule_rebind(clock_type::time_point when, const schedulable& scbl, ArgN&&... an) const;
+
+    /// use the supplied arguments to make a schedulable and then insert it to be run
+    template<class Arg0, class... ArgN>
+    auto schedule_periodically(clock_type::time_point initial, clock_type::duration period, Arg0&& a0, ArgN&&... an) const
+        -> typename std::enable_if<
+            (detail::is_action_function<Arg0>::value ||
+            is_subscription<Arg0>::value) &&
+            !is_schedulable<Arg0>::value>::type;
+    /// use the supplied arguments to make a schedulable and then insert it to be run
+    template<class... ArgN>
+    void schedule_periodically_rebind(clock_type::time_point initial, clock_type::duration period, const schedulable& scbl, ArgN&&... an) const;
+};
+
+inline bool operator==(const worker& lhs, const worker& rhs) {
+    return lhs.inner == rhs.inner && lhs.lifetime == rhs.lifetime;
+}
+inline bool operator!=(const worker& lhs, const worker& rhs) {
+    return !(lhs == rhs);
+}
+
+class scheduler_interface
+    : public std::enable_shared_from_this<scheduler_interface>
+{
+    typedef scheduler_interface this_type;
+
+public:
+    typedef scheduler_base::clock_type clock_type;
+
+    virtual ~scheduler_interface() {}
+
+    virtual clock_type::time_point now() const = 0;
+
+    virtual worker create_worker(composite_subscription cs) const = 0;
+};
+
+
+struct schedulable_base :
+    // public subscription_base, <- already in worker base
+    public worker_base,
+    public action_base
+{
+    typedef tag_schedulable schedulable_tag;
+};
+
+class scheduler : public scheduler_base
+{
+    typedef scheduler this_type;
+    detail::scheduler_interface_ptr inner;
+    friend bool operator==(const scheduler&, const scheduler&);
+public:
+    typedef scheduler_base::clock_type clock_type;
+
+    scheduler()
+    {
+    }
+    explicit scheduler(detail::scheduler_interface_ptr i)
+        : inner(std::move(i))
+    {
+    }
+    explicit scheduler(detail::const_scheduler_interface_ptr i)
+    : inner(std::move(std::const_pointer_cast<scheduler_interface>(i)))
+    {
+    }
+
+    /// return the current time for this scheduler
+    inline clock_type::time_point now() const {
+        return inner->now();
+    }
+    /// create a worker with a lifetime.
+    /// when the worker is unsubscribed all scheduled items will be unsubscribed.
+    /// items scheduled to a worker will be run one at a time.
+    /// scheduling order is preserved: when more than one item is scheduled for
+    /// time T then at time T they will be run in the order that they were scheduled.
+    inline worker create_worker(composite_subscription cs = composite_subscription()) const {
+        return inner->create_worker(cs);
+    }
+};
+
+template<class Scheduler, class... ArgN>
+inline scheduler make_scheduler(ArgN&&... an) {
+    return scheduler(std::static_pointer_cast<scheduler_interface>(std::make_shared<Scheduler>(std::forward<ArgN>(an)...)));
+}
+
+
+class schedulable : public schedulable_base
+{
+    typedef schedulable this_type;
+
+    composite_subscription lifetime;
+    worker controller;
+    action activity;
+    bool scoped;
+    composite_subscription::weak_subscription action_scope;
+
+    struct detacher
+    {
+        ~detacher()
+        {
+            if (that) {
+                that->unsubscribe();
+            }
+        }
+        detacher(const this_type* that)
+            : that(that)
+        {
+        }
+        const this_type* that;
+    };
+
+    class recursed_scope_type
+    {
+        mutable const recursed* requestor;
+
+        class exit_recursed_scope_type
+        {
+            const recursed_scope_type* that;
+        public:
+            ~exit_recursed_scope_type()
+            {
+                    that->requestor = nullptr;
+            }
+            exit_recursed_scope_type(const recursed_scope_type* that)
+                : that(that)
+            {
+            }
+        };
+    public:
+        recursed_scope_type()
+            : requestor(nullptr)
+        {
+        }
+        recursed_scope_type(const recursed_scope_type&)
+            : requestor(nullptr)
+        {
+            // does not aquire recursion scope
+        }
+        recursed_scope_type& operator=(const recursed_scope_type& o)
+        {
+            // no change in recursion scope
+            return *this;
+        }
+        exit_recursed_scope_type reset(const recurse& r) const {
+            requestor = std::addressof(r.get_recursed());
+            return exit_recursed_scope_type(this);
+        }
+        bool is_recursed() const {
+            return !!requestor;
+        }
+        void operator()() const {
+            (*requestor)();
+        }
+    };
+    recursed_scope_type recursed_scope;
+
+public:
+    typedef composite_subscription::weak_subscription weak_subscription;
+    typedef scheduler_base::clock_type clock_type;
+
+    ~schedulable()
+    {
+        if (scoped) {
+            controller.remove(action_scope);
+        }
+    }
+    schedulable()
+        : scoped(false)
+    {
+    }
+
+    /// action and worker share lifetime
+    schedulable(worker q, action a)
+        : lifetime(q.get_subscription())
+        , controller(std::move(q))
+        , activity(std::move(a))
+        , scoped(false)
+    {
+    }
+    /// action and worker have independent lifetimes
+    schedulable(composite_subscription cs, worker q, action a)
+        : lifetime(std::move(cs))
+        , controller(std::move(q))
+        , activity(std::move(a))
+        , scoped(true)
+        , action_scope(controller.add(lifetime))
+    {
+    }
+    /// inherit lifetimes
+    schedulable(schedulable scbl, worker q, action a)
+        : lifetime(scbl.get_subscription())
+        , controller(std::move(q))
+        , activity(std::move(a))
+        , scoped(scbl.scoped)
+        , action_scope(scbl.scoped ? controller.add(lifetime) : weak_subscription())
+    {
+    }
+
+    inline const composite_subscription& get_subscription() const {
+        return lifetime;
+    }
+    inline composite_subscription& get_subscription() {
+        return lifetime;
+    }
+    inline const worker& get_worker() const {
+        return controller;
+    }
+    inline worker& get_worker() {
+        return controller;
+    }
+    inline const action& get_action() const {
+        return activity;
+    }
+    inline action& get_action() {
+        return activity;
+    }
+
+    inline static schedulable empty(worker sc) {
+        return schedulable(composite_subscription::empty(), sc, action::empty());
+    }
+
+    inline auto set_recursed(const recurse& r) const
+        -> decltype(recursed_scope.reset(r)) {
+        return      recursed_scope.reset(r);
+    }
+
+    // recursed
+    //
+    bool is_recursed() const {
+        return recursed_scope.is_recursed();
+    }
+    /// requests tail-recursion of the same action
+    /// this will exit the process if called when
+    /// is_recursed() is false.
+    /// Note: to improve perf it is not required
+    /// to call is_recursed() before calling this
+    /// operator. Context is sufficient. The schedulable
+    /// passed to the action by the scheduler will return
+    /// true from is_recursed()
+    inline void operator()() const {
+        recursed_scope();
+    }
+
+    // composite_subscription
+    //
+    inline bool is_subscribed() const {
+        return lifetime.is_subscribed();
+    }
+    inline weak_subscription add(subscription s) const {
+        return lifetime.add(std::move(s));
+    }
+    template<class F>
+    auto add(F f) const
+    -> typename std::enable_if<rxcpp::detail::is_unsubscribe_function<F>::value, weak_subscription>::type {
+        return lifetime.add(make_subscription(std::move(f)));
+    }
+    inline void remove(weak_subscription w) const {
+        return lifetime.remove(std::move(w));
+    }
+    inline void clear() const {
+        return lifetime.clear();
+    }
+    inline void unsubscribe() const {
+        return lifetime.unsubscribe();
+    }
+
+    // scheduler
+    //
+    inline clock_type::time_point now() const {
+        return controller.now();
+    }
+    /// put this on the queue of the stored scheduler to run asap
+    inline void schedule() const {
+        if (is_subscribed()) {
+            controller.schedule(*this);
+        }
+    }
+    /// put this on the queue of the stored scheduler to run at the specified time
+    inline void schedule(clock_type::time_point when) const {
+        if (is_subscribed()) {
+            controller.schedule(when, *this);
+        }
+    }
+    /// put this on the queue of the stored scheduler to run after a delay from now
+    inline void schedule(clock_type::duration when) const {
+        if (is_subscribed()) {
+            controller.schedule(when, *this);
+        }
+    }
+
+    // action
+    //
+    /// invokes the action
+    inline void operator()(const recurse& r) const {
+        if (!is_subscribed()) {
+            return;
+        }
+        detacher protect(this);
+        activity(*this, r);
+        protect.that = nullptr;
+    }
+};
+
+struct current_thread;
+
+namespace detail {
+
+class action_type
+    : public std::enable_shared_from_this<action_type>
+{
+    typedef action_type this_type;
+
+public:
+    typedef std::function<void(const schedulable&, const recurse&)> function_type;
+
+private:
+    function_type f;
+
+public:
+    action_type()
+    {
+    }
+
+    action_type(function_type f)
+        : f(std::move(f))
+    {
+    }
+
+    inline void operator()(const schedulable& s, const recurse& r) {
+        if (!f) {
+            abort();
+        }
+        f(s, r);
+    }
+};
+
+}
+
+inline void action::operator()(const schedulable& s, const recurse& r) const {
+    (*inner)(s, r);
+}
+
+//static
+RXCPP_SELECT_ANY detail::action_ptr action::shared_empty = detail::action_ptr(new detail::action_type());
+
+
+inline action make_action_empty() {
+    return action::empty();
+}
+
+template<class F>
+inline action make_action(F&& f) {
+    static_assert(detail::is_action_function<F>::value, "action function must be void(schedulable)");
+    auto fn = std::forward<F>(f);
+    return action(std::make_shared<detail::action_type>(
+        // tail-recurse inside of the virtual function call
+        // until a new action, lifetime or scheduler is returned
+        [fn](const schedulable& s, const recurse& r) {
+            trace_activity().action_enter(s);
+            auto scope = s.set_recursed(r);
+            while (s.is_subscribed()) {
+                r.reset();
+                fn(s);
+                if (!r.is_allowed() || !r.is_requested()) {
+                    if (r.is_requested()) {
+                        s.schedule();
+                    }
+                    break;
+                }
+                trace_activity().action_recurse(s);
+            }
+            trace_activity().action_return(s);
+        }));
+}
+
+// copy
+inline auto make_schedulable(
+    const   schedulable& scbl)
+    ->      schedulable {
+    return  schedulable(scbl);
+}
+// move
+inline auto make_schedulable(
+            schedulable&& scbl)
+    ->      schedulable {
+    return  schedulable(std::move(scbl));
+}
+
+inline schedulable make_schedulable(worker sc, action a) {
+    return schedulable(sc, a);
+}
+inline schedulable make_schedulable(worker sc, composite_subscription cs, action a) {
+    return schedulable(cs, sc, a);
+}
+
+template<class F>
+auto make_schedulable(worker sc, F&& f)
+    -> typename std::enable_if<detail::is_action_function<F>::value, schedulable>::type {
+    return schedulable(sc, make_action(std::forward<F>(f)));
+}
+template<class F>
+auto make_schedulable(worker sc, composite_subscription cs, F&& f)
+    -> typename std::enable_if<detail::is_action_function<F>::value, schedulable>::type {
+    return schedulable(cs, sc, make_action(std::forward<F>(f)));
+}
+template<class F>
+auto make_schedulable(schedulable scbl, composite_subscription cs, F&& f)
+    -> typename std::enable_if<detail::is_action_function<F>::value, schedulable>::type {
+    return schedulable(cs, scbl.get_worker(), make_action(std::forward<F>(f)));
+}
+template<class F>
+auto make_schedulable(schedulable scbl, worker sc, F&& f)
+    -> typename std::enable_if<detail::is_action_function<F>::value, schedulable>::type {
+    return schedulable(scbl, sc, make_action(std::forward<F>(f)));
+}
+template<class F>
+auto make_schedulable(schedulable scbl, F&& f)
+    -> typename std::enable_if<detail::is_action_function<F>::value, schedulable>::type {
+    return schedulable(scbl, scbl.get_worker(), make_action(std::forward<F>(f)));
+}
+
+inline auto make_schedulable(schedulable scbl, composite_subscription cs)
+    -> schedulable {
+    return schedulable(cs, scbl.get_worker(), scbl.get_action());
+}
+inline auto make_schedulable(schedulable scbl, worker sc, composite_subscription cs)
+    -> schedulable {
+    return schedulable(cs, sc, scbl.get_action());
+}
+inline auto make_schedulable(schedulable scbl, worker sc)
+    -> schedulable {
+    return schedulable(scbl, sc, scbl.get_action());
+}
+
+template<class Arg0, class... ArgN>
+auto worker::schedule(Arg0&& a0, ArgN&&... an) const
+    -> typename std::enable_if<
+        (detail::is_action_function<Arg0>::value ||
+        is_subscription<Arg0>::value) &&
+        !is_schedulable<Arg0>::value>::type {
+    auto scbl = make_schedulable(*this, std::forward<Arg0>(a0), std::forward<ArgN>(an)...);
+    trace_activity().schedule_enter(*inner.get(), scbl);
+    inner->schedule(std::move(scbl));
+    trace_activity().schedule_return(*inner.get());
+}
+template<class... ArgN>
+void worker::schedule_rebind(const schedulable& scbl, ArgN&&... an) const {
+    auto rescbl = make_schedulable(scbl, *this, std::forward<ArgN>(an)...);
+    trace_activity().schedule_enter(*inner.get(), rescbl);
+    inner->schedule(std::move(rescbl));
+    trace_activity().schedule_return(*inner.get());
+}
+
+template<class Arg0, class... ArgN>
+auto worker::schedule(clock_type::time_point when, Arg0&& a0, ArgN&&... an) const
+    -> typename std::enable_if<
+        (detail::is_action_function<Arg0>::value ||
+        is_subscription<Arg0>::value) &&
+        !is_schedulable<Arg0>::value>::type {
+    auto scbl = make_schedulable(*this, std::forward<Arg0>(a0), std::forward<ArgN>(an)...);
+    trace_activity().schedule_when_enter(*inner.get(), when, scbl);
+    inner->schedule(when, std::move(scbl));
+    trace_activity().schedule_when_return(*inner.get());
+}
+template<class... ArgN>
+void worker::schedule_rebind(clock_type::time_point when, const schedulable& scbl, ArgN&&... an) const {
+    auto rescbl = make_schedulable(scbl, *this, std::forward<ArgN>(an)...);
+    trace_activity().schedule_when_enter(*inner.get(), when, rescbl);
+    inner->schedule(when, std::move(rescbl));
+    trace_activity().schedule_when_return(*inner.get());
+}
+
+template<class Arg0, class... ArgN>
+auto worker::schedule_periodically(clock_type::time_point initial, clock_type::duration period, Arg0&& a0, ArgN&&... an) const
+    -> typename std::enable_if<
+        (detail::is_action_function<Arg0>::value ||
+        is_subscription<Arg0>::value) &&
+        !is_schedulable<Arg0>::value>::type {
+    schedule_periodically_rebind(initial, period, make_schedulable(*this, std::forward<Arg0>(a0), std::forward<ArgN>(an)...));
+}
+template<class... ArgN>
+void worker::schedule_periodically_rebind(clock_type::time_point initial, clock_type::duration period, const schedulable& scbl, ArgN&&... an) const {
+    std::shared_ptr<clock_type::time_point> target(new clock_type::time_point(initial));
+    auto activity = make_schedulable(scbl, *this, std::forward<ArgN>(an)...);
+    auto periodic = make_schedulable(
+        activity,
+        [target, period, activity](schedulable self) {
+            // any recursion requests will be pushed to the scheduler queue
+            recursion r(false);
+            // call action
+            activity(r.get_recurse());
+
+            // schedule next occurance (if the action took longer than 'period' target will be in the past)
+            *target += period;
+            self.schedule(*target);
+        });
+    trace_activity().schedule_when_enter(*inner.get(), *target, periodic);
+    inner->schedule(*target, periodic);
+    trace_activity().schedule_when_return(*inner.get());
+}
+
+namespace detail {
+
+template<class TimePoint>
+struct time_schedulable
+{
+    typedef TimePoint time_point_type;
+
+    time_schedulable(TimePoint when, schedulable a)
+        : when(when)
+        , what(std::move(a))
+    {
+    }
+    TimePoint when;
+    schedulable what;
+};
+
+
+// Sorts time_schedulable items in priority order sorted
+// on value of time_schedulable.when. Items with equal
+// values for when are sorted in fifo order.
+template<class TimePoint>
+class schedulable_queue {
+public:
+    typedef time_schedulable<TimePoint> item_type;
+    typedef std::pair<item_type, int64_t> elem_type;
+    typedef std::vector<elem_type> container_type;
+    typedef const item_type& const_reference;
+
+private:
+    struct compare_elem
+    {
+        bool operator()(const elem_type& lhs, const elem_type& rhs) const {
+            if (lhs.first.when == rhs.first.when) {
+                return lhs.second > rhs.second;
+            }
+            else {
+                return lhs.first.when > rhs.first.when;
+            }
+        }
+    };
+
+    typedef std::priority_queue<
+        elem_type,
+        container_type,
+        compare_elem
+    > queue_type;
+
+    queue_type queue;
+
+    int64_t ordinal;
+public:
+    const_reference top() const {
+        return queue.top().first;
+    }
+
+    void pop() {
+        queue.pop();
+    }
+
+    bool empty() const {
+        return queue.empty();
+    }
+
+    void push(const item_type& value) {
+        queue.push(elem_type(value, ordinal++));
+    }
+
+    void push(item_type&& value) {
+        queue.push(elem_type(std::move(value), ordinal++));
+    }
+};
+
+}
+
+}
+namespace rxsc=schedulers;
+
+}
+
+#include "schedulers/rx-currentthread.hpp"
+#include "schedulers/rx-newthread.hpp"
+#include "schedulers/rx-eventloop.hpp"
+#include "schedulers/rx-immediate.hpp"
+#include "schedulers/rx-virtualtime.hpp"
+#include "schedulers/rx-sameworker.hpp"
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/rx-sources.hpp b/dependencies64/RxCpp/include/rxcpp/rx-sources.hpp
new file mode 100644 (file)
index 0000000..25d40ec
--- /dev/null
@@ -0,0 +1,47 @@
+
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_RX_SOURCES_HPP)
+#define RXCPP_RX_SOURCES_HPP
+
+#include "rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace sources {
+
+struct tag_source {};
+template<class T>
+struct source_base
+{
+    typedef T value_type;
+    typedef tag_source source_tag;
+};
+template<class T>
+class is_source
+{
+    template<class C>
+    static typename C::source_tag* check(int);
+    template<class C>
+    static void check(...);
+public:
+    static const bool value = std::is_convertible<decltype(check<typename std::decay<T>::type>(0)), tag_source*>::value;
+};
+
+}
+namespace rxs=sources;
+
+}
+
+#include "sources/rx-create.hpp"
+#include "sources/rx-range.hpp"
+#include "sources/rx-iterate.hpp"
+#include "sources/rx-interval.hpp"
+#include "sources/rx-defer.hpp"
+#include "sources/rx-never.hpp"
+#include "sources/rx-error.hpp"
+#include "sources/rx-scope.hpp"
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/rx-subjects.hpp b/dependencies64/RxCpp/include/rxcpp/rx-subjects.hpp
new file mode 100644 (file)
index 0000000..c7ad600
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_RX_SCHEDULER_SUBJECTS_HPP)
+#define RXCPP_RX_SCHEDULER_SUBJECTS_HPP
+
+#include "rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace subjects {
+
+}
+namespace rxsub=subjects;
+
+}
+
+#include "subjects/rx-subject.hpp"
+#include "subjects/rx-behavior.hpp"
+#include "subjects/rx-synchronize.hpp"
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/rx-subscriber.hpp b/dependencies64/RxCpp/include/rxcpp/rx-subscriber.hpp
new file mode 100644 (file)
index 0000000..39e6bdc
--- /dev/null
@@ -0,0 +1,857 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_RX_SUBSCRIBER_HPP)
+#define RXCPP_RX_SUBSCRIBER_HPP
+
+#include "rx-includes.hpp"
+
+namespace rxcpp {
+
+template<class T>
+struct subscriber_base : public observer_base<T>, public subscription_base
+{
+    typedef tag_subscriber subscriber_tag;
+};
+
+template<class T, class Observer = observer<T>>
+class subscriber : public subscriber_base<T>
+{
+    static_assert(!is_subscriber<Observer>::value, "not allowed to nest subscribers");
+    static_assert(is_observer<Observer>::value, "subscriber must contain an observer<T, ...>");
+    typedef subscriber<T, Observer> this_type;
+    typedef typename std::decay<Observer>::type observer_type;
+
+    composite_subscription lifetime;
+    observer_type destination;
+    trace_id id;
+
+    struct nextdetacher
+    {
+        ~nextdetacher()
+        {
+            trace_activity().on_next_return(*that);
+            if (do_unsubscribe) {
+                that->unsubscribe();
+            }
+        }
+        nextdetacher(const this_type* that)
+            : that(that)
+            , do_unsubscribe(true)
+        {
+        }
+        template<class U>
+        void operator()(U u) {
+            trace_activity().on_next_enter(*that, u);
+            that->destination.on_next(std::move(u));
+            do_unsubscribe = false;
+        }
+        const this_type* that;
+        bool do_unsubscribe;
+    };
+
+    struct errordetacher
+    {
+        ~errordetacher()
+        {
+            trace_activity().on_error_return(*that);
+            that->unsubscribe();
+        }
+        errordetacher(const this_type* that)
+            : that(that)
+        {
+        }
+        inline void operator()(std::exception_ptr ex) {
+            trace_activity().on_error_enter(*that, ex);
+            that->destination.on_error(std::move(ex));
+        }
+        const this_type* that;
+    };
+
+    struct completeddetacher
+    {
+        ~completeddetacher()
+        {
+            trace_activity().on_completed_return(*that);
+            that->unsubscribe();
+        }
+        completeddetacher(const this_type* that)
+            : that(that)
+        {
+        }
+        inline void operator()() {
+            trace_activity().on_completed_enter(*that);
+            that->destination.on_completed();
+        }
+        const this_type* that;
+    };
+
+    subscriber();
+public:
+    typedef typename composite_subscription::weak_subscription weak_subscription;
+
+    subscriber(const this_type& o)
+        : lifetime(o.lifetime)
+        , destination(o.destination)
+        , id(o.id)
+    {
+    }
+    subscriber(this_type&& o)
+        : lifetime(std::move(o.lifetime))
+        , destination(std::move(o.destination))
+        , id(std::move(o.id))
+    {
+    }
+
+    template<class U, class O>
+    friend class subscriber;
+
+    template<class O>
+    subscriber(
+        const subscriber<T, O>& o,
+        typename std::enable_if<
+               !std::is_same<O, observer<T>>::value &&
+               std::is_same<Observer, observer<T>>::value, void**>::type select = nullptr)
+        : lifetime(o.lifetime)
+        , destination(o.destination.as_dynamic())
+        , id(o.id)
+    {
+    }
+
+    template<class U>
+    subscriber(trace_id id, composite_subscription cs, U&& o)
+        : lifetime(std::move(cs))
+        , destination(std::forward<U>(o))
+        , id(std::move(id))
+    {
+        static_assert(!is_subscriber<U>::value, "cannot nest subscribers");
+        static_assert(is_observer<U>::value, "must pass observer to subscriber");
+        trace_activity().create_subscriber(*this);
+    }
+
+    this_type& operator=(this_type o) {
+        lifetime = std::move(o.lifetime);
+        destination = std::move(o.destination);
+        id = std::move(o.id);
+        return *this;
+    }
+
+    const observer_type& get_observer() const {
+        return destination;
+    }
+    observer_type& get_observer() {
+        return destination;
+    }
+    const composite_subscription& get_subscription() const {
+        return lifetime;
+    }
+    composite_subscription& get_subscription() {
+        return lifetime;
+    }
+    trace_id get_id() const {
+        return id;
+    }
+
+    subscriber<T> as_dynamic() const {
+        return subscriber<T>(id, lifetime, destination.as_dynamic());
+    }
+
+    // observer
+    //
+    template<class V>
+    void on_next(V&& v) const {
+        if (!is_subscribed()) {
+            return;
+        }
+        nextdetacher protect(this);
+        protect(std::forward<V>(v));
+    }
+    void on_error(std::exception_ptr e) const {
+        if (!is_subscribed()) {
+            return;
+        }
+        errordetacher protect(this);
+        protect(std::move(e));
+    }
+    void on_completed() const {
+        if (!is_subscribed()) {
+            return;
+        }
+        completeddetacher protect(this);
+        protect();
+    }
+
+    // composite_subscription
+    //
+    bool is_subscribed() const {
+        return lifetime.is_subscribed();
+    }
+    weak_subscription add(subscription s) const {
+        return lifetime.add(std::move(s));
+    }
+    template<class F>
+    auto add(F f) const
+    -> typename std::enable_if<detail::is_unsubscribe_function<F>::value, weak_subscription>::type {
+        return lifetime.add(make_subscription(std::move(f)));
+    }
+    void remove(weak_subscription w) const {
+        return lifetime.remove(std::move(w));
+    }
+    void clear() const {
+        return lifetime.clear();
+    }
+    void unsubscribe() const {
+        return lifetime.unsubscribe();
+    }
+
+};
+
+template<class T, class Observer>
+auto make_subscriber(
+            subscriber<T,   Observer> o)
+    ->      subscriber<T,   Observer> {
+    return  subscriber<T,   Observer>(std::move(o));
+}
+
+// observer
+//
+
+template<class T>
+auto make_subscriber()
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, detail::OnNextEmpty<T>>::value,
+            subscriber<T,   observer<T, static_observer<T, detail::OnNextEmpty<T>>>>>::type {
+    return  subscriber<T,   observer<T, static_observer<T, detail::OnNextEmpty<T>>>>(trace_id::make_next_id_subscriber(), composite_subscription(),
+                            observer<T, static_observer<T, detail::OnNextEmpty<T>>>(
+                                        static_observer<T, detail::OnNextEmpty<T>>(detail::OnNextEmpty<T>())));
+}
+
+template<class T, class I>
+auto make_subscriber(
+    const                   observer<T, I>& o)
+    ->      subscriber<T,   observer<T, I>> {
+    return  subscriber<T,   observer<T, I>>(trace_id::make_next_id_subscriber(), composite_subscription(), o);
+}
+template<class T, class Observer>
+auto make_subscriber(const Observer& o)
+    -> typename std::enable_if<
+        is_observer<Observer>::value,
+            subscriber<T,   Observer>>::type {
+    return  subscriber<T,   Observer>(trace_id::make_next_id_subscriber(), composite_subscription(), o);
+}
+template<class T, class Observer>
+auto make_subscriber(const Observer& o)
+    -> typename std::enable_if<
+        !detail::is_on_next_of<T, Observer>::value &&
+        !is_subscriber<Observer>::value &&
+        !is_subscription<Observer>::value &&
+        !is_observer<Observer>::value,
+            subscriber<T,   observer<T, Observer>>>::type {
+    return  subscriber<T,   observer<T, Observer>>(trace_id::make_next_id_subscriber(), composite_subscription(), o);
+}
+template<class T, class OnNext>
+auto make_subscriber(const OnNext& on)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value,
+            subscriber<T,   observer<T, static_observer<T, OnNext>>>>::type {
+    return  subscriber<T,   observer<T, static_observer<T, OnNext>>>(trace_id::make_next_id_subscriber(), composite_subscription(),
+                            observer<T, static_observer<T, OnNext>>(
+                                        static_observer<T, OnNext>(on)));
+}
+template<class T, class OnNext, class OnError>
+auto make_subscriber(const OnNext& on, const OnError& oe)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value &&
+        detail::is_on_error<OnError>::value,
+            subscriber<T,   observer<T, static_observer<T, OnNext, OnError>>>>::type {
+    return  subscriber<T,   observer<T, static_observer<T, OnNext, OnError>>>(trace_id::make_next_id_subscriber(), composite_subscription(),
+                            observer<T, static_observer<T, OnNext, OnError>>(
+                                        static_observer<T, OnNext, OnError>(on, oe)));
+}
+template<class T, class OnNext, class OnCompleted>
+auto make_subscriber(const OnNext& on, const OnCompleted& oc)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value &&
+        detail::is_on_completed<OnCompleted>::value,
+            subscriber<T,   observer<T, static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>>>>::type {
+    return  subscriber<T,   observer<T, static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>>>(trace_id::make_next_id_subscriber(), composite_subscription(),
+                            observer<T, static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>>(
+                                        static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>(on, detail::OnErrorEmpty(), oc)));
+}
+template<class T, class OnNext, class OnError, class OnCompleted>
+auto make_subscriber(const OnNext& on, const OnError& oe, const OnCompleted& oc)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value &&
+        detail::is_on_error<OnError>::value &&
+        detail::is_on_completed<OnCompleted>::value,
+            subscriber<T,   observer<T, static_observer<T, OnNext, OnError, OnCompleted>>>>::type {
+    return  subscriber<T,   observer<T, static_observer<T, OnNext, OnError, OnCompleted>>>(trace_id::make_next_id_subscriber(), composite_subscription(),
+                            observer<T, static_observer<T, OnNext, OnError, OnCompleted>>(
+                                        static_observer<T, OnNext, OnError, OnCompleted>(on, oe, oc)));
+}
+
+// explicit lifetime
+//
+
+template<class T>
+auto make_subscriber(const composite_subscription& cs)
+    ->      subscriber<T,   observer<T, static_observer<T, detail::OnNextEmpty<T>>>> {
+    return  subscriber<T,   observer<T, static_observer<T, detail::OnNextEmpty<T>>>>(trace_id::make_next_id_subscriber(), cs,
+                            observer<T, static_observer<T, detail::OnNextEmpty<T>>>(
+                                        static_observer<T, detail::OnNextEmpty<T>>(detail::OnNextEmpty<T>())));
+}
+
+template<class T, class I>
+auto make_subscriber(const composite_subscription& cs,
+    const                   observer<T, I>& o)
+    ->      subscriber<T,   observer<T, I>> {
+    return  subscriber<T,   observer<T, I>>(trace_id::make_next_id_subscriber(), cs, o);
+}
+template<class T, class I>
+auto make_subscriber(const composite_subscription& cs,
+    const                   subscriber<T, I>& s)
+    ->      subscriber<T,   I> {
+    return  subscriber<T,   I>(trace_id::make_next_id_subscriber(), cs, s.get_observer());
+}
+template<class T, class Observer>
+auto make_subscriber(const composite_subscription& cs, const Observer& o)
+    -> typename std::enable_if<
+        !is_subscriber<Observer>::value &&
+        is_observer<Observer>::value,
+            subscriber<T,   Observer>>::type {
+    return  subscriber<T,   Observer>(trace_id::make_next_id_subscriber(), cs, o);
+}
+template<class T, class Observer>
+auto make_subscriber(const composite_subscription& cs, const Observer& o)
+    -> typename std::enable_if<
+        !detail::is_on_next_of<T, Observer>::value &&
+        !is_subscriber<Observer>::value &&
+        !is_subscription<Observer>::value &&
+        !is_observer<Observer>::value,
+            subscriber<T,   observer<T, Observer>>>::type {
+    return  subscriber<T,   observer<T, Observer>>(trace_id::make_next_id_subscriber(), cs, make_observer<T>(o));
+}
+template<class T, class OnNext>
+auto make_subscriber(const composite_subscription& cs, const OnNext& on)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value,
+            subscriber<T,   observer<T, static_observer<T, OnNext>>>>::type {
+    return  subscriber<T,   observer<T, static_observer<T, OnNext>>>(trace_id::make_next_id_subscriber(), cs,
+                            observer<T, static_observer<T, OnNext>>(
+                                        static_observer<T, OnNext>(on)));
+}
+template<class T, class OnNext, class OnError>
+auto make_subscriber(const composite_subscription& cs, const OnNext& on, const OnError& oe)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value &&
+        detail::is_on_error<OnError>::value,
+            subscriber<T,   observer<T, static_observer<T, OnNext, OnError>>>>::type {
+    return  subscriber<T,   observer<T, static_observer<T, OnNext, OnError>>>(trace_id::make_next_id_subscriber(), cs,
+                            observer<T, static_observer<T, OnNext, OnError>>(
+                                        static_observer<T, OnNext, OnError>(on, oe)));
+}
+template<class T, class OnNext, class OnCompleted>
+auto make_subscriber(const composite_subscription& cs, const OnNext& on, const OnCompleted& oc)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value &&
+        detail::is_on_completed<OnCompleted>::value,
+            subscriber<T,   observer<T, static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>>>>::type {
+    return  subscriber<T,   observer<T, static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>>>(trace_id::make_next_id_subscriber(), cs,
+                            observer<T, static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>>(
+                                        static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>(on, detail::OnErrorEmpty(), oc)));
+}
+template<class T, class OnNext, class OnError, class OnCompleted>
+auto make_subscriber(const composite_subscription& cs, const OnNext& on, const OnError& oe, const OnCompleted& oc)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value &&
+        detail::is_on_error<OnError>::value &&
+        detail::is_on_completed<OnCompleted>::value,
+            subscriber<T,   observer<T, static_observer<T, OnNext, OnError, OnCompleted>>>>::type {
+    return  subscriber<T,   observer<T, static_observer<T, OnNext, OnError, OnCompleted>>>(trace_id::make_next_id_subscriber(), cs,
+                            observer<T, static_observer<T, OnNext, OnError, OnCompleted>>(
+                                        static_observer<T, OnNext, OnError, OnCompleted>(on, oe, oc)));
+}
+
+// explicit id
+//
+
+template<class T>
+auto make_subscriber(trace_id id)
+    ->      subscriber<T,   observer<T, static_observer<T, detail::OnNextEmpty<T>>>> {
+    return  subscriber<T,   observer<T, static_observer<T, detail::OnNextEmpty<T>>>>(std::move(id), composite_subscription(),
+                            observer<T, static_observer<T, detail::OnNextEmpty<T>>>(
+                                        static_observer<T, detail::OnNextEmpty<T>>(detail::OnNextEmpty<T>())));
+}
+
+template<class T>
+auto make_subscriber(trace_id id, const composite_subscription& cs)
+    ->      subscriber<T,   observer<T, static_observer<T, detail::OnNextEmpty<T>>>> {
+    return  subscriber<T,   observer<T, static_observer<T, detail::OnNextEmpty<T>>>>(std::move(id), cs,
+                            observer<T, static_observer<T, detail::OnNextEmpty<T>>>(
+                                        static_observer<T, detail::OnNextEmpty<T>>(detail::OnNextEmpty<T>())));
+}
+
+template<class T, class I>
+auto make_subscriber(trace_id id,
+    const                   observer<T, I>& o)
+    ->      subscriber<T,   observer<T, I>> {
+    return  subscriber<T,   observer<T, I>>(std::move(id), composite_subscription(), o);
+}
+template<class T, class I>
+auto make_subscriber(trace_id id, const composite_subscription& cs,
+    const                   observer<T, I>& o)
+    ->      subscriber<T,   observer<T, I>> {
+    return  subscriber<T,   observer<T, I>>(std::move(id), cs, o);
+}
+template<class T, class Observer>
+auto make_subscriber(trace_id id, const Observer& o)
+    -> typename std::enable_if<
+        is_observer<Observer>::value,
+            subscriber<T,   Observer>>::type {
+    return  subscriber<T,   Observer>(std::move(id), composite_subscription(), o);
+}
+template<class T, class Observer>
+auto make_subscriber(trace_id id, const composite_subscription& cs, const Observer& o)
+    -> typename std::enable_if<
+        is_observer<Observer>::value,
+            subscriber<T,   Observer>>::type {
+    return  subscriber<T,   Observer>(std::move(id), cs, o);
+}
+template<class T, class Observer>
+auto make_subscriber(trace_id id, const Observer& o)
+    -> typename std::enable_if<
+        !detail::is_on_next_of<T, Observer>::value &&
+        !is_subscriber<Observer>::value &&
+        !is_subscription<Observer>::value &&
+        !is_observer<Observer>::value,
+            subscriber<T,   observer<T, Observer>>>::type {
+    return  subscriber<T,   observer<T, Observer>>(std::move(id), composite_subscription(), o);
+}
+template<class T, class Observer>
+auto make_subscriber(trace_id id, const composite_subscription& cs, const Observer& o)
+    -> typename std::enable_if<
+        !detail::is_on_next_of<T, Observer>::value &&
+        !is_subscriber<Observer>::value &&
+        !is_subscription<Observer>::value &&
+        !is_observer<Observer>::value,
+            subscriber<T,   observer<T, Observer>>>::type {
+    return  subscriber<T,   observer<T, Observer>>(std::move(id), cs, o);
+}
+template<class T, class OnNext>
+auto make_subscriber(trace_id id, const OnNext& on)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value,
+            subscriber<T,   observer<T, static_observer<T, OnNext>>>>::type {
+    return  subscriber<T,   observer<T, static_observer<T, OnNext>>>(std::move(id), composite_subscription(),
+                            observer<T, static_observer<T, OnNext>>(
+                                        static_observer<T, OnNext>(on)));
+}
+template<class T, class OnNext>
+auto make_subscriber(trace_id id, const composite_subscription& cs, const OnNext& on)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value,
+            subscriber<T,   observer<T, static_observer<T, OnNext>>>>::type {
+    return  subscriber<T,   observer<T, static_observer<T, OnNext>>>(std::move(id), cs,
+                            observer<T, static_observer<T, OnNext>>(
+                                        static_observer<T, OnNext>(on)));
+}
+template<class T, class OnNext, class OnError>
+auto make_subscriber(trace_id id, const OnNext& on, const OnError& oe)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value &&
+        detail::is_on_error<OnError>::value,
+            subscriber<T,   observer<T, static_observer<T, OnNext, OnError>>>>::type {
+    return  subscriber<T,   observer<T, static_observer<T, OnNext, OnError>>>(std::move(id), composite_subscription(),
+                            observer<T, static_observer<T, OnNext, OnError>>(
+                                        static_observer<T, OnNext, OnError>(on, oe)));
+}
+template<class T, class OnNext, class OnError>
+auto make_subscriber(trace_id id, const composite_subscription& cs, const OnNext& on, const OnError& oe)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value &&
+        detail::is_on_error<OnError>::value,
+            subscriber<T,   observer<T, static_observer<T, OnNext, OnError>>>>::type {
+    return  subscriber<T,   observer<T, static_observer<T, OnNext, OnError>>>(std::move(id), cs,
+                            observer<T, static_observer<T, OnNext, OnError>>(
+                                        static_observer<T, OnNext, OnError>(on, oe)));
+}
+template<class T, class OnNext, class OnCompleted>
+auto make_subscriber(trace_id id, const OnNext& on, const OnCompleted& oc)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value &&
+        detail::is_on_completed<OnCompleted>::value,
+            subscriber<T,   observer<T, static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>>>>::type {
+    return  subscriber<T,   observer<T, static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>>>(std::move(id), composite_subscription(),
+                            observer<T, static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>>(
+                                        static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>(on, detail::OnErrorEmpty(), oc)));
+}
+template<class T, class OnNext, class OnCompleted>
+auto make_subscriber(trace_id id, const composite_subscription& cs, const OnNext& on, const OnCompleted& oc)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value &&
+        detail::is_on_completed<OnCompleted>::value,
+            subscriber<T,   observer<T, static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>>>>::type {
+    return  subscriber<T,   observer<T, static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>>>(std::move(id), cs,
+                            observer<T, static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>>(
+                                        static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>(on, detail::OnErrorEmpty(), oc)));
+}
+template<class T, class OnNext, class OnError, class OnCompleted>
+auto make_subscriber(trace_id id, const OnNext& on, const OnError& oe, const OnCompleted& oc)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value &&
+        detail::is_on_error<OnError>::value &&
+        detail::is_on_completed<OnCompleted>::value,
+            subscriber<T,   observer<T, static_observer<T, OnNext, OnError, OnCompleted>>>>::type {
+    return  subscriber<T,   observer<T, static_observer<T, OnNext, OnError, OnCompleted>>>(std::move(id), composite_subscription(),
+                            observer<T, static_observer<T, OnNext, OnError, OnCompleted>>(
+                                        static_observer<T, OnNext, OnError, OnCompleted>(on, oe, oc)));
+}
+template<class T, class OnNext, class OnError, class OnCompleted>
+auto make_subscriber(trace_id id, const composite_subscription& cs, const OnNext& on, const OnError& oe, const OnCompleted& oc)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value &&
+        detail::is_on_error<OnError>::value &&
+        detail::is_on_completed<OnCompleted>::value,
+            subscriber<T,   observer<T, static_observer<T, OnNext, OnError, OnCompleted>>>>::type {
+    return  subscriber<T,   observer<T, static_observer<T, OnNext, OnError, OnCompleted>>>(std::move(id), cs,
+                            observer<T, static_observer<T, OnNext, OnError, OnCompleted>>(
+                                        static_observer<T, OnNext, OnError, OnCompleted>(on, oe, oc)));
+}
+
+// chain defaults from subscriber
+//
+
+template<class T, class OtherT, class OtherObserver, class I>
+auto make_subscriber(const subscriber<OtherT, OtherObserver>& scbr,
+    const                   observer<T, I>& o)
+    ->       subscriber<T,   observer<T, I>> {
+    auto r = subscriber<T,   observer<T, I>>(trace_id::make_next_id_subscriber(), scbr.get_subscription(), o);
+    trace_activity().connect(r, scbr);
+    return r;
+}
+template<class T, class OtherT, class OtherObserver, class I>
+auto make_subscriber(const subscriber<OtherT, OtherObserver>& scbr, trace_id id,
+    const                   observer<T, I>& o)
+    ->       subscriber<T,   observer<T, I>> {
+    auto r = subscriber<T,   observer<T, I>>(std::move(id), scbr.get_subscription(), o);
+    trace_activity().connect(r, scbr);
+    return r;
+}
+template<class T, class OtherT, class OtherObserver, class Observer>
+auto make_subscriber(const subscriber<OtherT, OtherObserver>& scbr, trace_id id, const Observer& o)
+    -> typename std::enable_if<
+        is_observer<Observer>::value,
+             subscriber<T,   Observer>>::type {
+    auto r = subscriber<T,   Observer>(std::move(id), scbr.get_subscription(), o);
+    trace_activity().connect(r, scbr);
+    return r;
+}
+template<class T, class OtherT, class OtherObserver, class Observer>
+auto make_subscriber(const subscriber<OtherT, OtherObserver>& scbr, const Observer& o)
+    -> typename std::enable_if<
+        !is_subscription<Observer>::value &&
+        is_observer<Observer>::value,
+             subscriber<T,   Observer>>::type {
+    auto r = subscriber<T,   Observer>(trace_id::make_next_id_subscriber(), scbr.get_subscription(), o);
+    trace_activity().connect(r, scbr);
+    return r;
+}
+template<class T, class OtherT, class OtherObserver, class Observer>
+auto make_subscriber(const subscriber<OtherT, OtherObserver>& scbr, const Observer& o)
+    -> typename std::enable_if<
+        !detail::is_on_next_of<T, Observer>::value &&
+        !is_subscriber<Observer>::value &&
+        !is_subscription<Observer>::value &&
+        !is_observer<Observer>::value,
+             subscriber<T,   observer<T, Observer>>>::type {
+    auto r = subscriber<T,   observer<T, Observer>>(trace_id::make_next_id_subscriber(), scbr.get_subscription(), make_observer<T>(o));
+    trace_activity().connect(r, scbr);
+    return r;
+}
+template<class T, class OtherT, class OtherObserver, class Observer>
+auto make_subscriber(const subscriber<OtherT, OtherObserver>& scbr, trace_id id, const Observer& o)
+    -> typename std::enable_if<
+        !detail::is_on_next_of<T, Observer>::value &&
+        !is_subscriber<Observer>::value &&
+        !is_subscription<Observer>::value &&
+        !is_observer<Observer>::value,
+             subscriber<T,   observer<T, Observer>>>::type {
+    auto r = subscriber<T,   observer<T, Observer>>(std::move(id), scbr.get_subscription(), o);
+    trace_activity().connect(r, scbr);
+    return r;
+}
+template<class T, class OtherT, class OtherObserver, class OnNext>
+auto make_subscriber(const subscriber<OtherT, OtherObserver>& scbr, const OnNext& on)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value,
+             subscriber<T,   observer<T, static_observer<T, OnNext>>>>::type {
+    auto r = subscriber<T,   observer<T, static_observer<T, OnNext>>>(trace_id::make_next_id_subscriber(), scbr.get_subscription(),
+                            observer<T, static_observer<T, OnNext>>(
+                                        static_observer<T, OnNext>(on)));
+    trace_activity().connect(r, scbr);
+    return r;
+}
+template<class T, class OtherT, class OtherObserver, class OnNext>
+auto make_subscriber(const subscriber<OtherT, OtherObserver>& scbr, trace_id id, const OnNext& on)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value,
+             subscriber<T,   observer<T, static_observer<T, OnNext>>>>::type {
+    auto r = subscriber<T,   observer<T, static_observer<T, OnNext>>>(std::move(id), scbr.get_subscription(),
+                            observer<T, static_observer<T, OnNext>>(
+                                        static_observer<T, OnNext>(on)));
+    trace_activity().connect(r, scbr);
+    return r;
+}
+template<class T, class OtherT, class OtherObserver, class OnNext, class OnError>
+auto make_subscriber(const subscriber<OtherT, OtherObserver>& scbr, const OnNext& on, const OnError& oe)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value &&
+        detail::is_on_error<OnError>::value,
+             subscriber<T,   observer<T, static_observer<T, OnNext, OnError>>>>::type {
+    auto r = subscriber<T,   observer<T, static_observer<T, OnNext, OnError>>>(trace_id::make_next_id_subscriber(), scbr.get_subscription(),
+                            observer<T, static_observer<T, OnNext, OnError>>(
+                                        static_observer<T, OnNext, OnError>(on, oe)));
+    trace_activity().connect(r, scbr);
+    return r;
+}
+template<class T, class OtherT, class OtherObserver, class OnNext, class OnError>
+auto make_subscriber(const subscriber<OtherT, OtherObserver>& scbr, trace_id id, const OnNext& on, const OnError& oe)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value &&
+        detail::is_on_error<OnError>::value,
+             subscriber<T,   observer<T, static_observer<T, OnNext, OnError>>>>::type {
+    auto r = subscriber<T,   observer<T, static_observer<T, OnNext, OnError>>>(std::move(id), scbr.get_subscription(),
+                            observer<T, static_observer<T, OnNext, OnError>>(
+                                        static_observer<T, OnNext, OnError>(on, oe)));
+    trace_activity().connect(r, scbr);
+    return r;
+}
+template<class T, class OtherT, class OtherObserver, class OnNext, class OnCompleted>
+auto make_subscriber(const subscriber<OtherT, OtherObserver>& scbr, const OnNext& on, const OnCompleted& oc)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value &&
+        detail::is_on_completed<OnCompleted>::value,
+             subscriber<T,   observer<T, static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>>>>::type {
+    auto r = subscriber<T,   observer<T, static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>>>(trace_id::make_next_id_subscriber(), scbr.get_subscription(),
+                            observer<T, static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>>(
+                                        static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>(on, detail::OnErrorEmpty(), oc)));
+    trace_activity().connect(r, scbr);
+    return r;
+}
+template<class T, class OtherT, class OtherObserver, class OnNext, class OnCompleted>
+auto make_subscriber(const subscriber<OtherT, OtherObserver>& scbr, trace_id id, const OnNext& on, const OnCompleted& oc)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value &&
+        detail::is_on_completed<OnCompleted>::value,
+             subscriber<T,   observer<T, static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>>>>::type {
+    auto r = subscriber<T,   observer<T, static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>>>(std::move(id), scbr.get_subscription(),
+                            observer<T, static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>>(
+                                        static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>(on, detail::OnErrorEmpty(), oc)));
+    trace_activity().connect(r, scbr);
+    return r;
+}
+template<class T, class OtherT, class OtherObserver, class OnNext, class OnError, class OnCompleted>
+auto make_subscriber(const subscriber<OtherT, OtherObserver>& scbr, const OnNext& on, const OnError& oe, const OnCompleted& oc)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value &&
+        detail::is_on_error<OnError>::value &&
+        detail::is_on_completed<OnCompleted>::value,
+             subscriber<T,   observer<T, static_observer<T, OnNext, OnError, OnCompleted>>>>::type {
+    auto r = subscriber<T,   observer<T, static_observer<T, OnNext, OnError, OnCompleted>>>(trace_id::make_next_id_subscriber(), scbr.get_subscription(),
+                            observer<T, static_observer<T, OnNext, OnError, OnCompleted>>(
+                                        static_observer<T, OnNext, OnError, OnCompleted>(on, oe, oc)));
+    trace_activity().connect(r, scbr);
+    return r;
+}
+template<class T, class OtherT, class OtherObserver, class OnNext, class OnError, class OnCompleted>
+auto make_subscriber(const subscriber<OtherT, OtherObserver>& scbr, trace_id id, const OnNext& on, const OnError& oe, const OnCompleted& oc)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value &&
+        detail::is_on_error<OnError>::value &&
+        detail::is_on_completed<OnCompleted>::value,
+             subscriber<T,   observer<T, static_observer<T, OnNext, OnError, OnCompleted>>>>::type {
+    auto r = subscriber<T,   observer<T, static_observer<T, OnNext, OnError, OnCompleted>>>(std::move(id), scbr.get_subscription(),
+                            observer<T, static_observer<T, OnNext, OnError, OnCompleted>>(
+                                        static_observer<T, OnNext, OnError, OnCompleted>(on, oe, oc)));
+    trace_activity().connect(r, scbr);
+    return r;
+}
+
+template<class T, class OtherT, class OtherObserver, class I>
+auto make_subscriber(const subscriber<OtherT, OtherObserver>& scbr, const composite_subscription& cs,
+    const                   observer<T, I>& o)
+    ->      subscriber<T,   observer<T, I>> {
+    return  subscriber<T,   observer<T, I>>(trace_id::make_next_id_subscriber(), cs, o);
+}
+template<class T, class OtherT, class OtherObserver, class I>
+auto make_subscriber(const subscriber<OtherT, OtherObserver>& scbr, trace_id id, const composite_subscription& cs,
+    const                   observer<T, I>& o)
+    ->      subscriber<T,   observer<T, I>> {
+    return  subscriber<T,   observer<T, I>>(std::move(id), cs, o);
+}
+template<class T, class OtherT, class OtherObserver, class Observer>
+auto make_subscriber(const subscriber<OtherT, OtherObserver>& scbr, const composite_subscription& cs, const Observer& o)
+    -> typename std::enable_if<
+        is_observer<Observer>::value,
+             subscriber<T,   Observer>>::type {
+    auto r = subscriber<T,   Observer>(trace_id::make_next_id_subscriber(), cs, o);
+    trace_activity().connect(r, scbr);
+    return r;
+}
+template<class T, class OtherT, class OtherObserver, class Observer>
+auto make_subscriber(const subscriber<OtherT, OtherObserver>& scbr, trace_id id, const composite_subscription& cs, const Observer& o)
+    -> typename std::enable_if<
+        is_observer<Observer>::value,
+             subscriber<T,   Observer>>::type {
+    auto r = subscriber<T,   Observer>(std::move(id), cs, o);
+    trace_activity().connect(r, scbr);
+    return r;
+}
+template<class T, class OtherT, class OtherObserver, class Observer>
+auto make_subscriber(const subscriber<OtherT, OtherObserver>& scbr, const composite_subscription& cs, const Observer& o)
+    -> typename std::enable_if<
+        !detail::is_on_next_of<T, Observer>::value &&
+        !is_subscriber<Observer>::value &&
+        !is_subscription<Observer>::value &&
+        !is_observer<Observer>::value,
+             subscriber<T,   observer<T, Observer>>>::type {
+    auto r = subscriber<T,   observer<T, Observer>>(trace_id::make_next_id_subscriber(), cs, o);
+    trace_activity().connect(r, scbr);
+    return r;
+}
+template<class T, class OtherT, class OtherObserver, class Observer>
+auto make_subscriber(const subscriber<OtherT, OtherObserver>& scbr, trace_id id, const composite_subscription& cs, const Observer& o)
+    -> typename std::enable_if<
+        !detail::is_on_next_of<T, Observer>::value &&
+        !is_subscriber<Observer>::value &&
+        !is_subscription<Observer>::value &&
+        !is_observer<Observer>::value,
+             subscriber<T,   observer<T, Observer>>>::type {
+    auto r = subscriber<T,   observer<T, Observer>>(std::move(id), cs, o);
+    trace_activity().connect(r, scbr);
+    return r;
+}
+template<class T, class OtherT, class OtherObserver, class OnNext>
+auto make_subscriber(const subscriber<OtherT, OtherObserver>& scbr, const composite_subscription& cs, const OnNext& on)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value,
+             subscriber<T,   observer<T, static_observer<T, OnNext>>>>::type {
+    auto r = subscriber<T,   observer<T, static_observer<T, OnNext>>>(trace_id::make_next_id_subscriber(), cs,
+                            observer<T, static_observer<T, OnNext>>(
+                                        static_observer<T, OnNext>(on)));
+    trace_activity().connect(r, scbr);
+    return r;
+}
+template<class T, class OtherT, class OtherObserver, class OnNext>
+auto make_subscriber(const subscriber<OtherT, OtherObserver>& scbr, trace_id id, const composite_subscription& cs, const OnNext& on)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value,
+             subscriber<T,   observer<T, static_observer<T, OnNext>>>>::type {
+    auto r = subscriber<T,   observer<T, static_observer<T, OnNext>>>(std::move(id), cs,
+                            observer<T, static_observer<T, OnNext>>(
+                                        static_observer<T, OnNext>(on)));
+    trace_activity().connect(r, scbr);
+    return r;
+}
+template<class T, class OtherT, class OtherObserver, class OnNext, class OnError>
+auto make_subscriber(const subscriber<OtherT, OtherObserver>& scbr, const composite_subscription& cs, const OnNext& on, const OnError& oe)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value &&
+        detail::is_on_error<OnError>::value,
+             subscriber<T,   observer<T, static_observer<T, OnNext, OnError>>>>::type {
+    auto r = subscriber<T,   observer<T, static_observer<T, OnNext, OnError>>>(trace_id::make_next_id_subscriber(), cs,
+                            observer<T, static_observer<T, OnNext, OnError>>(
+                                        static_observer<T, OnNext, OnError>(on, oe)));
+    trace_activity().connect(r, scbr);
+    return r;
+}
+template<class T, class OtherT, class OtherObserver, class OnNext, class OnError>
+auto make_subscriber(const subscriber<OtherT, OtherObserver>& scbr, trace_id id, const composite_subscription& cs, const OnNext& on, const OnError& oe)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value &&
+        detail::is_on_error<OnError>::value,
+             subscriber<T,   observer<T, static_observer<T, OnNext, OnError>>>>::type {
+    auto r = subscriber<T,   observer<T, static_observer<T, OnNext, OnError>>>(std::move(id), cs,
+                            observer<T, static_observer<T, OnNext, OnError>>(
+                                        static_observer<T, OnNext, OnError>(on, oe)));
+    trace_activity().connect(r, scbr);
+    return r;
+}
+template<class T, class OtherT, class OtherObserver, class OnNext, class OnCompleted>
+auto make_subscriber(const subscriber<OtherT, OtherObserver>& scbr, const composite_subscription& cs, const OnNext& on, const OnCompleted& oc)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value &&
+        detail::is_on_completed<OnCompleted>::value,
+             subscriber<T,   observer<T, static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>>>>::type {
+    auto r = subscriber<T,   observer<T, static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>>>(trace_id::make_next_id_subscriber(), cs,
+                            observer<T, static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>>(
+                                        static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>(on, detail::OnErrorEmpty(), oc)));
+    trace_activity().connect(r, scbr);
+    return r;
+}
+template<class T, class OtherT, class OtherObserver, class OnNext, class OnCompleted>
+auto make_subscriber(const subscriber<OtherT, OtherObserver>& scbr, trace_id id, const composite_subscription& cs, const OnNext& on, const OnCompleted& oc)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value &&
+        detail::is_on_completed<OnCompleted>::value,
+             subscriber<T,   observer<T, static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>>>>::type {
+    auto r = subscriber<T,   observer<T, static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>>>(std::move(id), cs,
+                            observer<T, static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>>(
+                                        static_observer<T, OnNext, detail::OnErrorEmpty, OnCompleted>(on, detail::OnErrorEmpty(), oc)));
+    trace_activity().connect(r, scbr);
+    return r;
+}
+template<class T, class OtherT, class OtherObserver, class OnNext, class OnError, class OnCompleted>
+auto make_subscriber(const subscriber<OtherT, OtherObserver>& scbr, const composite_subscription& cs, const OnNext& on, const OnError& oe, const OnCompleted& oc)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value &&
+        detail::is_on_error<OnError>::value &&
+        detail::is_on_completed<OnCompleted>::value,
+             subscriber<T,   observer<T, static_observer<T, OnNext, OnError, OnCompleted>>>>::type {
+    auto r = subscriber<T,   observer<T, static_observer<T, OnNext, OnError, OnCompleted>>>(trace_id::make_next_id_subscriber(), cs,
+                            observer<T, static_observer<T, OnNext, OnError, OnCompleted>>(
+                                        static_observer<T, OnNext, OnError, OnCompleted>(on, oe, oc)));
+    trace_activity().connect(r, scbr);
+    return r;
+}
+template<class T, class OtherT, class OtherObserver, class OnNext, class OnError, class OnCompleted>
+auto make_subscriber(const subscriber<OtherT, OtherObserver>& scbr, trace_id id, const composite_subscription& cs, const OnNext& on, const OnError& oe, const OnCompleted& oc)
+    -> typename std::enable_if<
+        detail::is_on_next_of<T, OnNext>::value &&
+        detail::is_on_error<OnError>::value &&
+        detail::is_on_completed<OnCompleted>::value,
+             subscriber<T,   observer<T, static_observer<T, OnNext, OnError, OnCompleted>>>>::type {
+    auto r = subscriber<T,   observer<T, static_observer<T, OnNext, OnError, OnCompleted>>>(std::move(id), cs,
+                            observer<T, static_observer<T, OnNext, OnError, OnCompleted>>(
+                                        static_observer<T, OnNext, OnError, OnCompleted>(on, oe, oc)));
+    trace_activity().connect(r, scbr);
+    return r;
+}
+
+template<class T, class Observer>
+auto make_subscriber(const subscriber<T, Observer>& scbr, const composite_subscription& cs)
+    ->      subscriber<T,   Observer> {
+    auto r = subscriber<T,   Observer>(scbr.get_id(), cs, scbr.get_observer());
+    trace_activity().connect(r, scbr);
+    return r;
+}
+template<class T, class Observer>
+auto make_subscriber(const subscriber<T, Observer>& scbr, trace_id id, const composite_subscription& cs)
+    ->      subscriber<T,   Observer> {
+    auto r = subscriber<T,   Observer>(std::move(id), cs, scbr.get_observer());
+    trace_activity().connect(r, scbr);
+    return r;
+}
+
+template<class T, class Observer>
+auto make_subscriber(const subscriber<T, Observer>& scbr, trace_id id)
+    ->      subscriber<T,   Observer> {
+    auto r = subscriber<T,   Observer>(std::move(id), scbr.get_subscription(), scbr.get_observer());
+    trace_activity().connect(r, scbr);
+    return r;
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/rx-subscription.hpp b/dependencies64/RxCpp/include/rxcpp/rx-subscription.hpp
new file mode 100644 (file)
index 0000000..6263a1f
--- /dev/null
@@ -0,0 +1,504 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_RX_SUBSCRIPTION_HPP)
+#define RXCPP_RX_SUBSCRIPTION_HPP
+
+#include "rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace detail {
+
+template<class F>
+struct is_unsubscribe_function
+{
+    struct not_void {};
+    template<class CF>
+    static auto check(int) -> decltype((*(CF*)nullptr)());
+    template<class CF>
+    static not_void check(...);
+
+    static const bool value = std::is_same<decltype(check<typename std::decay<F>::type>(0)), void>::value;
+};
+
+}
+
+struct tag_subscription {};
+struct subscription_base {typedef tag_subscription subscription_tag;};
+template<class T>
+class is_subscription
+{
+    template<class C>
+    static typename C::subscription_tag* check(int);
+    template<class C>
+    static void check(...);
+public:
+    static const bool value = std::is_convertible<decltype(check<typename std::decay<T>::type>(0)), tag_subscription*>::value;
+};
+
+template<class Unsubscribe>
+class static_subscription
+{
+    typedef typename std::decay<Unsubscribe>::type unsubscribe_call_type;
+    unsubscribe_call_type unsubscribe_call;
+    static_subscription()
+    {
+    }
+public:
+    static_subscription(const static_subscription& o)
+        : unsubscribe_call(o.unsubscribe_call)
+    {
+    }
+    static_subscription(static_subscription&& o)
+        : unsubscribe_call(std::move(o.unsubscribe_call))
+    {
+    }
+    static_subscription(unsubscribe_call_type s)
+        : unsubscribe_call(std::move(s))
+    {
+    }
+    void unsubscribe() const {
+        unsubscribe_call();
+    }
+};
+
+class subscription : public subscription_base
+{
+    class base_subscription_state : public std::enable_shared_from_this<base_subscription_state>
+    {
+        base_subscription_state();
+    public:
+
+        explicit base_subscription_state(bool initial)
+            : issubscribed(initial)
+        {
+        }
+        virtual void unsubscribe() {
+        }
+        std::atomic<bool> issubscribed;
+    };
+public:
+    typedef std::weak_ptr<base_subscription_state> weak_state_type;
+
+private:
+    template<class I>
+    struct subscription_state : public base_subscription_state
+    {
+        typedef typename std::decay<I>::type inner_t;
+        subscription_state(inner_t i)
+            : base_subscription_state(true)
+            , inner(std::move(i))
+        {
+        }
+        virtual void unsubscribe() {
+            if (issubscribed.exchange(false)) {
+                trace_activity().unsubscribe_enter(*this);
+                inner.unsubscribe();
+                trace_activity().unsubscribe_return(*this);
+            }
+        }
+        inner_t inner;
+    };
+
+protected:
+    std::shared_ptr<base_subscription_state> state;
+
+    friend bool operator<(const subscription&, const subscription&);
+    friend bool operator==(const subscription&, const subscription&);
+
+private:
+    subscription(weak_state_type w)
+        : state(w.lock())
+    {
+        if (!state) {
+            abort();
+        }
+    }
+public:
+
+    subscription()
+        : state(std::make_shared<base_subscription_state>(false))
+    {
+        if (!state) {
+            abort();
+        }
+    }
+    template<class U>
+    explicit subscription(U u, typename std::enable_if<!is_subscription<U>::value, void**>::type = nullptr)
+        : state(std::make_shared<subscription_state<U>>(std::move(u)))
+    {
+        if (!state) {
+            abort();
+        }
+    }
+    template<class U>
+    explicit subscription(U u, typename std::enable_if<!std::is_same<subscription, U>::value && is_subscription<U>::value, void**>::type = nullptr)
+        // intentionally slice
+        : state(std::move((*static_cast<subscription*>(&u)).state))
+    {
+        if (!state) {
+            abort();
+        }
+    }
+    subscription(const subscription& o)
+        : state(o.state)
+    {
+        if (!state) {
+            abort();
+        }
+    }
+    subscription(subscription&& o)
+        : state(std::move(o.state))
+    {
+        if (!state) {
+            abort();
+        }
+    }
+    subscription& operator=(subscription o) {
+        state = std::move(o.state);
+        return *this;
+    }
+    bool is_subscribed() const {
+        if (!state) {
+            abort();
+        }
+        return state->issubscribed;
+    }
+    void unsubscribe() const {
+        if (!state) {
+            abort();
+        }
+        auto keepAlive = state;
+        state->unsubscribe();
+    }
+
+    weak_state_type get_weak() {
+        return state;
+    }
+    static subscription lock(weak_state_type w) {
+        return subscription(w);
+    }
+};
+
+inline bool operator<(const subscription& lhs, const subscription& rhs) {
+    return lhs.state < rhs.state;
+}
+inline bool operator==(const subscription& lhs, const subscription& rhs) {
+    return lhs.state == rhs.state;
+}
+inline bool operator!=(const subscription& lhs, const subscription& rhs) {
+    return !(lhs == rhs);
+}
+
+
+inline auto make_subscription()
+    ->      subscription {
+    return  subscription();
+}
+template<class I>
+auto make_subscription(I&& i)
+    -> typename std::enable_if<!is_subscription<I>::value && !detail::is_unsubscribe_function<I>::value,
+            subscription>::type {
+    return  subscription(std::forward<I>(i));
+}
+template<class Unsubscribe>
+auto make_subscription(Unsubscribe&& u)
+    -> typename std::enable_if<detail::is_unsubscribe_function<Unsubscribe>::value,
+            subscription>::type {
+    return  subscription(static_subscription<Unsubscribe>(std::forward<Unsubscribe>(u)));
+}
+
+namespace detail {
+
+struct tag_composite_subscription_empty {};
+
+class composite_subscription_inner
+{
+private:
+    typedef subscription::weak_state_type weak_subscription;
+    struct composite_subscription_state : public std::enable_shared_from_this<composite_subscription_state>
+    {
+        std::set<subscription> subscriptions;
+        std::mutex lock;
+        std::atomic<bool> issubscribed;
+
+        ~composite_subscription_state()
+        {
+            std::unique_lock<decltype(lock)> guard(lock);
+            subscriptions.clear();
+        }
+
+        composite_subscription_state()
+            : issubscribed(true)
+        {
+        }
+        composite_subscription_state(tag_composite_subscription_empty)
+            : issubscribed(false)
+        {
+        }
+
+        inline weak_subscription add(subscription s) {
+            if (!issubscribed) {
+                s.unsubscribe();
+            } else if (s.is_subscribed()) {
+                std::unique_lock<decltype(lock)> guard(lock);
+                subscriptions.insert(s);
+            }
+            return s.get_weak();
+        }
+
+        inline void remove(weak_subscription w) {
+            if (issubscribed && !w.expired()) {
+                auto s = subscription::lock(w);
+                std::unique_lock<decltype(lock)> guard(lock);
+                subscriptions.erase(std::move(s));
+            }
+        }
+
+        inline void clear() {
+            if (issubscribed) {
+                std::unique_lock<decltype(lock)> guard(lock);
+
+                std::set<subscription> v(std::move(subscriptions));
+                guard.unlock();
+                std::for_each(v.begin(), v.end(),
+                              [](const subscription& s) {
+                                s.unsubscribe(); });
+            }
+        }
+
+        inline void unsubscribe() {
+            if (issubscribed.exchange(false)) {
+                std::unique_lock<decltype(lock)> guard(lock);
+
+                std::set<subscription> v(std::move(subscriptions));
+                guard.unlock();
+                std::for_each(v.begin(), v.end(),
+                              [](const subscription& s) {
+                                s.unsubscribe(); });
+            }
+        }
+    };
+
+public:
+    typedef std::shared_ptr<composite_subscription_state> shared_state_type;
+
+protected:
+    mutable shared_state_type state;
+
+public:
+    composite_subscription_inner()
+        : state(std::make_shared<composite_subscription_state>())
+    {
+    }
+    composite_subscription_inner(tag_composite_subscription_empty et)
+        : state(std::make_shared<composite_subscription_state>(et))
+    {
+    }
+
+    composite_subscription_inner(const composite_subscription_inner& o)
+        : state(o.state)
+    {
+        if (!state) {
+            abort();
+        }
+    }
+    composite_subscription_inner(composite_subscription_inner&& o)
+        : state(std::move(o.state))
+    {
+        if (!state) {
+            abort();
+        }
+    }
+
+    composite_subscription_inner& operator=(composite_subscription_inner o)
+    {
+        state = std::move(o.state);
+        if (!state) {
+            abort();
+        }
+        return *this;
+    }
+
+    inline weak_subscription add(subscription s) const {
+        if (!state) {
+            abort();
+        }
+        return state->add(std::move(s));
+    }
+    inline void remove(weak_subscription w) const {
+        if (!state) {
+            abort();
+        }
+        state->remove(std::move(w));
+    }
+    inline void clear() const {
+        if (!state) {
+            abort();
+        }
+        state->clear();
+    }
+    inline void unsubscribe() {
+        if (!state) {
+            abort();
+        }
+        state->unsubscribe();
+    }
+};
+
+}
+
+class composite_subscription
+    : protected detail::composite_subscription_inner
+    , public subscription
+{
+    typedef detail::composite_subscription_inner inner_type;
+public:
+    typedef subscription::weak_state_type weak_subscription;
+
+    static composite_subscription shared_empty;
+
+    composite_subscription(detail::tag_composite_subscription_empty et)
+        : inner_type(et)
+        , subscription() // use empty base
+    {
+    }
+
+public:
+
+    composite_subscription()
+        : inner_type()
+        , subscription(*static_cast<const inner_type* const>(this))
+    {
+    }
+
+    composite_subscription(const composite_subscription& o)
+        : inner_type(o)
+        , subscription(static_cast<const subscription&>(o))
+    {
+    }
+    composite_subscription(composite_subscription&& o)
+        : inner_type(std::move(o))
+        , subscription(std::move(static_cast<subscription&>(o)))
+    {
+    }
+
+    composite_subscription& operator=(composite_subscription o)
+    {
+        inner_type::operator=(std::move(o));
+        subscription::operator=(std::move(*static_cast<subscription*>(&o)));
+        return *this;
+    }
+
+    static inline composite_subscription empty() {
+        return shared_empty;
+    }
+
+    using subscription::is_subscribed;
+    using subscription::unsubscribe;
+
+    using inner_type::clear;
+
+    inline weak_subscription add(subscription s) const {
+        if (s == static_cast<const subscription&>(*this)) {
+            // do not nest the same subscription
+            abort();
+            //return s.get_weak();
+        }
+        auto that = this->subscription::state.get();
+        trace_activity().subscription_add_enter(*that, s);
+        auto w = inner_type::add(std::move(s));
+        trace_activity().subscription_add_return(*that);
+        return w;
+    }
+
+    template<class F>
+    auto add(F f) const
+    -> typename std::enable_if<detail::is_unsubscribe_function<F>::value, weak_subscription>::type {
+        return add(make_subscription(std::move(f)));
+    }
+
+    inline void remove(weak_subscription w) const {
+        auto that = this->subscription::state.get();
+        trace_activity().subscription_remove_enter(*that, w);
+        inner_type::remove(w);
+        trace_activity().subscription_remove_return(*that);
+    }
+};
+
+inline bool operator<(const composite_subscription& lhs, const composite_subscription& rhs) {
+    return static_cast<const subscription&>(lhs) < static_cast<const subscription&>(rhs);
+}
+inline bool operator==(const composite_subscription& lhs, const composite_subscription& rhs) {
+    return static_cast<const subscription&>(lhs) == static_cast<const subscription&>(rhs);
+}
+inline bool operator!=(const composite_subscription& lhs, const composite_subscription& rhs) {
+    return !(lhs == rhs);
+}
+
+//static
+RXCPP_SELECT_ANY composite_subscription composite_subscription::shared_empty = composite_subscription(detail::tag_composite_subscription_empty());
+
+
+template<class T>
+class resource : public subscription_base
+{
+public:
+    typedef typename composite_subscription::weak_subscription weak_subscription;
+
+    resource()
+        : lifetime(composite_subscription())
+        , value(std::make_shared<rxu::detail::maybe<T>>())
+    {
+    }
+
+    explicit resource(T t, composite_subscription cs = composite_subscription())
+        : lifetime(std::move(cs))
+        , value(std::make_shared<rxu::detail::maybe<T>>(rxu::detail::maybe<T>(std::move(t))))
+    {
+        auto localValue = value;
+        lifetime.add(
+            [localValue](){
+                localValue->reset();
+            }
+        );
+    }
+
+    T& get() {
+        return value.get()->get();
+    }
+    composite_subscription& get_subscription() {
+        return lifetime;
+    }
+
+    bool is_subscribed() const {
+        return lifetime.is_subscribed();
+    }
+    weak_subscription add(subscription s) const {
+        return lifetime.add(std::move(s));
+    }
+    template<class F>
+    auto add(F f) const
+    -> typename std::enable_if<detail::is_unsubscribe_function<F>::value, weak_subscription>::type {
+        return lifetime.add(make_subscription(std::move(f)));
+    }
+    void remove(weak_subscription w) const {
+        return lifetime.remove(std::move(w));
+    }
+    void clear() const {
+        return lifetime.clear();
+    }
+    void unsubscribe() const {
+        return lifetime.unsubscribe();
+    }
+
+protected:
+    composite_subscription lifetime;
+    std::shared_ptr<rxu::detail::maybe<T>> value;
+};
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/rx-test.hpp b/dependencies64/RxCpp/include/rxcpp/rx-test.hpp
new file mode 100644 (file)
index 0000000..542c55b
--- /dev/null
@@ -0,0 +1,130 @@
+#pragma once
+
+#if !defined(RXCPP_RX_TEST_HPP)
+#define RXCPP_RX_TEST_HPP
+
+#include "rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace test {
+
+namespace detail {
+
+template<class T>
+struct test_subject_base
+    : public std::enable_shared_from_this<test_subject_base<T>>
+{
+    typedef rxn::recorded<typename rxn::notification<T>::type> recorded_type;
+    typedef std::shared_ptr<test_subject_base<T>> type;
+
+    virtual void on_subscribe(subscriber<T>) const =0;
+    virtual std::vector<recorded_type> messages() const =0;
+    virtual std::vector<rxn::subscription> subscriptions() const =0;
+};
+
+template<class T>
+struct test_source
+    : public rxs::source_base<T>
+{
+    explicit test_source(typename test_subject_base<T>::type ts)
+        : ts(std::move(ts))
+    {
+        if (!this->ts) abort();
+    }
+    typename test_subject_base<T>::type ts;
+    void on_subscribe(subscriber<T> o) const {
+        ts->on_subscribe(std::move(o));
+    }
+    template<class Subscriber>
+    typename std::enable_if<!std::is_same<Subscriber, subscriber<T>>::value, void>::type
+    on_subscribe(Subscriber o) const {
+
+        static_assert(is_subscriber<Subscriber>::value, "on_subscribe must be passed a subscriber.");
+
+        ts->on_subscribe(o.as_dynamic());
+    }
+};
+
+}
+
+template<class T>
+class testable_observer
+    : public observer<T>
+{
+    typedef observer<T> observer_base;
+    typedef typename detail::test_subject_base<T>::type test_subject;
+    test_subject ts;
+
+public:
+    typedef typename detail::test_subject_base<T>::recorded_type recorded_type;
+
+    testable_observer(test_subject ts, observer_base ob)
+        : observer_base(std::move(ob))
+        , ts(std::move(ts))
+    {
+    }
+
+    std::vector<recorded_type> messages() const {
+        return ts->messages();
+    }
+};
+
+//struct tag_test_observable : public tag_observable {};
+
+template<class T>
+class testable_observable
+    : public observable<T, typename detail::test_source<T>>
+{
+    typedef observable<T, typename detail::test_source<T>> observable_base;
+    typedef typename detail::test_subject_base<T>::type test_subject;
+    test_subject ts;
+
+    //typedef tag_test_observable observable_tag;
+
+public:
+    typedef typename detail::test_subject_base<T>::recorded_type recorded_type;
+
+    explicit testable_observable(test_subject ts)
+        : observable_base(detail::test_source<T>(ts))
+        , ts(ts)
+    {
+    }
+
+    std::vector<rxn::subscription> subscriptions() const {
+        return ts->subscriptions();
+    }
+
+    std::vector<recorded_type> messages() const {
+        return ts->messages();
+    }
+};
+
+}
+namespace rxt=test;
+
+}
+
+//
+// support range() >> filter() >> subscribe() syntax
+// '>>' is spelled 'stream'
+//
+template<class T, class OperatorFactory>
+auto operator >> (const rxcpp::test::testable_observable<T>& source, OperatorFactory&& of)
+    -> decltype(source.op(std::forward<OperatorFactory>(of))) {
+    return      source.op(std::forward<OperatorFactory>(of));
+}
+
+//
+// support range() | filter() | subscribe() syntax
+// '|' is spelled 'pipe'
+//
+template<class T, class OperatorFactory>
+auto operator | (const rxcpp::test::testable_observable<T>& source, OperatorFactory&& of)
+    -> decltype(source.op(std::forward<OperatorFactory>(of))) {
+    return      source.op(std::forward<OperatorFactory>(of));
+}
+
+#include "schedulers/rx-test.hpp"
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/rx-trace.hpp b/dependencies64/RxCpp/include/rxcpp/rx-trace.hpp
new file mode 100644 (file)
index 0000000..e72caaf
--- /dev/null
@@ -0,0 +1,114 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_RX_TRACE_HPP)
+#define RXCPP_RX_TRACE_HPP
+
+#include <iostream>
+#include <exception>
+#include <atomic>
+
+namespace rxcpp {
+
+struct trace_id
+{
+    static inline trace_id make_next_id_subscriber() {
+        static std::atomic<unsigned long> id(0xB0000000);
+        return trace_id{++id};
+    }
+    unsigned long id;
+};
+
+inline bool operator==(const trace_id& lhs, const trace_id& rhs) {
+    return lhs.id == rhs.id;
+}
+inline bool operator!=(const trace_id& lhs, const trace_id& rhs) {
+    return !(lhs==rhs);
+}
+
+inline bool operator<(const trace_id& lhs, const trace_id& rhs) {
+    if ((lhs.id & 0xF0000000) != (rhs.id & 0xF0000000)) std::terminate();
+    return lhs.id < rhs.id;
+}
+inline bool operator>(const trace_id& lhs, const trace_id& rhs) {
+    return rhs<lhs;
+}
+
+inline std::ostream& operator<< (std::ostream& os, const trace_id& id) {
+    return os << std::hex << id.id << std::dec;
+}
+
+struct trace_noop
+{
+    template<class Worker, class Schedulable>
+    inline void schedule_enter(const Worker&, const Schedulable&) {}
+    template<class Worker>
+    inline void schedule_return(const Worker&) {}
+    template<class Worker, class When, class Schedulable>
+    inline void schedule_when_enter(const Worker&, const When&, const Schedulable&) {}
+    template<class Worker>
+    inline void schedule_when_return(const Worker&) {}
+
+    template<class Schedulable>
+    inline void action_enter(const Schedulable&) {}
+    template<class Schedulable>
+    inline void action_return(const Schedulable&) {}
+    template<class Schedulable>
+    inline void action_recurse(const Schedulable&) {}
+
+    template<class Observable, class Subscriber>
+    inline void subscribe_enter(const Observable& o, const Subscriber& s) {}
+    template<class Observable>
+    inline void subscribe_return(const Observable& o) {}
+
+    template<class SubscriberFrom, class SubscriberTo>
+    inline void connect(const SubscriberFrom&, const SubscriberTo&) {}
+
+    template<class OperatorSource, class OperatorChain, class Subscriber, class SubscriberLifted>
+    inline void lift_enter(const OperatorSource&, const OperatorChain&, const Subscriber&, const SubscriberLifted&) {}
+    template<class OperatorSource, class OperatorChain>
+    inline void lift_return(const OperatorSource&, const OperatorChain&) {}
+
+    template<class SubscriptionState>
+    inline void unsubscribe_enter(const SubscriptionState&) {}
+    template<class SubscriptionState>
+    inline void unsubscribe_return(const SubscriptionState&) {}
+
+    template<class SubscriptionState, class Subscription>
+    inline void subscription_add_enter(const SubscriptionState&, const Subscription&) {}
+    template<class SubscriptionState>
+    inline void subscription_add_return(const SubscriptionState&) {}
+
+    template<class SubscriptionState, class WeakSubscription>
+    inline void subscription_remove_enter(const SubscriptionState&, const WeakSubscription&) {}
+    template<class SubscriptionState>
+    inline void subscription_remove_return(const SubscriptionState&) {}
+
+    template<class Subscriber>
+    inline void create_subscriber(const Subscriber&) {}
+
+    template<class Subscriber, class T>
+    inline void on_next_enter(const Subscriber&, const T&) {}
+    template<class Subscriber>
+    inline void on_next_return(const Subscriber&) {}
+
+    template<class Subscriber>
+    inline void on_error_enter(const Subscriber&, const std::exception_ptr&) {}
+    template<class Subscriber>
+    inline void on_error_return(const Subscriber&) {}
+
+    template<class Subscriber>
+    inline void on_completed_enter(const Subscriber&) {}
+    template<class Subscriber>
+    inline void on_completed_return(const Subscriber&) {}
+};
+
+struct trace_tag {};
+
+}
+
+inline auto rxcpp_trace_activity(...) -> rxcpp::trace_noop;
+
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/rx-util.hpp b/dependencies64/RxCpp/include/rxcpp/rx-util.hpp
new file mode 100644 (file)
index 0000000..470b532
--- /dev/null
@@ -0,0 +1,559 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_RX_UTIL_HPP)
+#define RXCPP_RX_UTIL_HPP
+
+#include "rx-includes.hpp"
+
+#if !defined(RXCPP_THREAD_LOCAL)
+#if defined(_MSC_VER)
+#define RXCPP_THREAD_LOCAL __declspec(thread)
+#else
+#define RXCPP_THREAD_LOCAL __thread
+#endif
+#endif
+
+#if !defined(RXCPP_SELECT_ANY)
+#if defined(_MSC_VER)
+#define RXCPP_SELECT_ANY __declspec(selectany)
+#else
+#define RXCPP_SELECT_ANY __attribute__((weak))
+#endif
+#endif
+
+#define RXCPP_CONCAT(Prefix, Suffix) Prefix ## Suffix
+#define RXCPP_CONCAT_EVALUATE(Prefix, Suffix) RXCPP_CONCAT(Prefix, Suffix)
+
+#define RXCPP_MAKE_IDENTIFIER(Prefix) RXCPP_CONCAT_EVALUATE(Prefix, __LINE__)
+
+namespace rxcpp {
+
+namespace util {
+
+template<class T, size_t size>
+std::vector<T> to_vector(const T (&arr) [size]) {
+    return std::vector<T>(std::begin(arr), std::end(arr));
+}
+
+template<class T>
+std::vector<T> to_vector(std::initializer_list<T> il) {
+    return std::vector<T>(il);
+}
+
+template<class T0, class... TN>
+typename std::enable_if<!std::is_array<T0>::value && std::is_pod<T0>::value, std::vector<T0>>::type to_vector(T0 t0, TN... tn) {
+    return to_vector({t0, tn...});
+}
+
+template<class T, T... ValueN>
+struct values {};
+
+template<class T, int Remaining, T Step = 1, T Cursor = 0, T... ValueN>
+struct values_from;
+
+template<class T, T Step, T Cursor, T... ValueN>
+struct values_from<T, 0, Step, Cursor, ValueN...>
+{
+    typedef values<T, ValueN...> type;
+};
+
+template<class T, int Remaining, T Step, T Cursor, T... ValueN>
+struct values_from
+{
+    typedef typename values_from<T, Remaining - 1, Step, Cursor + Step, ValueN..., Cursor>::type type;
+};
+
+template<bool... BN>
+struct all_true;
+
+template<bool B0>
+struct all_true<B0>
+{
+    static const bool value = B0;
+};
+template<bool B0, bool... BN>
+struct all_true<B0, BN...>
+{
+    static const bool value = B0 && all_true<BN...>::value;
+};
+
+namespace detail {
+
+template<class F, class... ParamN, int... IndexN>
+auto apply(std::tuple<ParamN...> p, values<int, IndexN...>, F& f)
+    -> decltype(f(std::forward<ParamN>(std::get<IndexN>(p))...)) {
+    return      f(std::forward<ParamN>(std::get<IndexN>(p))...);
+}
+template<class F, class... ParamN, int... IndexN>
+auto apply(std::tuple<ParamN...> p, values<int, IndexN...>, const F& f)
+    -> decltype(f(std::forward<ParamN>(std::get<IndexN>(p))...)) {
+    return      f(std::forward<ParamN>(std::get<IndexN>(p))...);
+}
+
+}
+
+template<class F, class... ParamN>
+auto apply(std::tuple<ParamN...> p, F& f)
+    -> decltype(detail::apply(std::move(p), typename values_from<int, sizeof...(ParamN)>::type(), f)) {
+    return      detail::apply(std::move(p), typename values_from<int, sizeof...(ParamN)>::type(), f);
+}
+template<class F, class... ParamN>
+auto apply(std::tuple<ParamN...> p, const F& f)
+    -> decltype(detail::apply(std::move(p), typename values_from<int, sizeof...(ParamN)>::type(), f)) {
+    return      detail::apply(std::move(p), typename values_from<int, sizeof...(ParamN)>::type(), f);
+}
+
+namespace detail {
+
+template<class F>
+struct apply_to
+{
+    F to;
+
+    explicit apply_to(F f)
+        : to(std::move(f))
+    {
+    }
+
+    template<class... ParamN>
+    auto operator()(std::tuple<ParamN...> p)
+        -> decltype(rxcpp::util::apply(std::move(p), to)) {
+        return      rxcpp::util::apply(std::move(p), to);
+    }
+    template<class... ParamN>
+    auto operator()(std::tuple<ParamN...> p) const
+        -> decltype(rxcpp::util::apply(std::move(p), to)) {
+        return      rxcpp::util::apply(std::move(p), to);
+    }
+};
+
+}
+
+template<class F>
+auto apply_to(F f)
+    ->      detail::apply_to<F> {
+    return  detail::apply_to<F>(std::move(f));
+}
+
+namespace detail {
+
+struct pack
+{
+    template<class... ParamN>
+    auto operator()(ParamN... pn)
+        -> decltype(std::make_tuple(std::move(pn)...)) {
+        return      std::make_tuple(std::move(pn)...);
+    }
+    template<class... ParamN>
+    auto operator()(ParamN... pn) const
+        -> decltype(std::make_tuple(std::move(pn)...)) {
+        return      std::make_tuple(std::move(pn)...);
+    }
+};
+
+}
+
+inline auto pack()
+    ->      detail::pack {
+    return  detail::pack();
+}
+
+template <class D>
+struct resolve_type;
+
+template <template<class... TN> class Deferred, class... AN>
+struct defer_trait
+{
+    template<bool R>
+    struct tag_valid {static const bool valid = true; static const bool value = R;};
+    struct tag_not_valid {static const bool valid = false; static const bool value = false;};
+    typedef Deferred<typename resolve_type<AN>::type...> resolved_type;
+    template<class... CN>
+    static auto check(int) -> tag_valid<resolved_type::value>;
+    template<class... CN>
+    static tag_not_valid check(...);
+
+    typedef decltype(check<AN...>(0)) tag_type;
+    static const bool valid = tag_type::valid;
+    static const bool value = tag_type::value;
+    static const bool not_value = valid && !value;
+};
+
+template <template<class... TN> class Deferred, class... AN>
+struct defer_type
+{
+    template<class R>
+    struct tag_valid {typedef R type; static const bool value = true;};
+    struct tag_not_valid {typedef void type; static const bool value = false;};
+    typedef Deferred<typename resolve_type<AN>::type...> resolved_type;
+    template<class... CN>
+    static auto check(int) -> tag_valid<resolved_type>;
+    template<class... CN>
+    static tag_not_valid check(...);
+
+    typedef decltype(check<AN...>(0)) tag_type;
+    typedef typename tag_type::type type;
+    static const bool value = tag_type::value;
+};
+
+template <template<class... TN> class Deferred, class... AN>
+struct defer_value_type
+{
+    template<class R>
+    struct tag_valid {typedef R type; static const bool value = true;};
+    struct tag_not_valid {typedef void type; static const bool value = false;};
+    typedef Deferred<typename resolve_type<AN>::type...> resolved_type;
+    template<class... CN>
+    static auto check(int) -> tag_valid<typename resolved_type::value_type>;
+    template<class... CN>
+    static tag_not_valid check(...);
+
+    typedef decltype(check<AN...>(0)) tag_type;
+    typedef typename tag_type::type type;
+    static const bool value = tag_type::value;
+};
+
+template <template<class... TN> class Deferred, class... AN>
+struct defer_seed_type
+{
+    template<class R>
+    struct tag_valid {typedef R type; static const bool value = true;};
+    struct tag_not_valid {typedef void type; static const bool value = false;};
+    typedef Deferred<typename resolve_type<AN>::type...> resolved_type;
+    template<class... CN>
+    static auto check(int) -> tag_valid<typename resolved_type::seed_type>;
+    template<class... CN>
+    static tag_not_valid check(...);
+
+    typedef decltype(check<AN...>(0)) tag_type;
+    typedef typename tag_type::type type;
+    static const bool value = tag_type::value;
+};
+
+template <class D>
+struct resolve_type
+{
+    typedef D type;
+};
+template <template<class... TN> class Deferred, class... AN>
+struct resolve_type<defer_type<Deferred, AN...>>
+{
+    typedef typename defer_type<Deferred, AN...>::type type;
+};
+template <template<class... TN> class Deferred, class... AN>
+struct resolve_type<defer_value_type<Deferred, AN...>>
+{
+    typedef typename defer_value_type<Deferred, AN...>::type type;
+};
+template <template<class... TN> class Deferred, class... AN>
+struct resolve_type<defer_seed_type<Deferred, AN...>>
+{
+    typedef typename defer_seed_type<Deferred, AN...>::type type;
+};
+
+struct plus
+{
+    template <class LHS, class RHS>
+    auto operator()(LHS&& lhs, RHS&& rhs) const
+        -> decltype(std::forward<LHS>(lhs) + std::forward<RHS>(rhs))
+        { return std::forward<LHS>(lhs) + std::forward<RHS>(rhs); }
+};
+
+struct less
+{
+    template <class LHS, class RHS>
+    auto operator()(LHS&& lhs, RHS&& rhs) const
+        -> decltype(std::forward<LHS>(lhs) < std::forward<RHS>(rhs))
+        { return std::forward<LHS>(lhs) < std::forward<RHS>(rhs); }
+};
+
+namespace detail {
+template<class OStream, class Delimit>
+struct print_function
+{
+    OStream& os;
+    Delimit delimit;
+    print_function(OStream& os, Delimit d) : os(os), delimit(std::move(d)) {}
+
+    template<class... TN>
+    void operator()(const TN&... tn) const {
+        bool inserts[] = {(os << tn, true)...};
+        delimit();
+    }
+
+    template<class... TN>
+    void operator()(const std::tuple<TN...>& tpl) const {
+        rxcpp::util::apply(tpl, *this);
+    }
+};
+
+template<class OStream>
+struct endline
+{
+    OStream& os;
+    endline(OStream& os) : os(os) {}
+    void operator()() const {
+        os << std::endl;
+    }
+};
+
+template<class OStream, class ValueType>
+struct insert_value
+{
+    OStream& os;
+    ValueType value;
+    insert_value(OStream& os, ValueType v) : os(os), value(std::move(v)) {}
+    void operator()() const {
+        os << value;
+    }
+};
+
+template<class OStream, class Function>
+struct insert_function
+{
+    OStream& os;
+    Function call;
+    insert_function(OStream& os, Function f) : os(os), call(std::move(f)) {}
+    void operator()() const {
+        call(os);
+    }
+};
+
+template<class OStream, class Delimit>
+auto print_followed_with(OStream& os, Delimit d)
+    ->      detail::print_function<OStream, Delimit> {
+    return  detail::print_function<OStream, Delimit>(os, std::move(d));
+}
+
+}
+
+template<class OStream>
+auto endline(OStream& os)
+    -> detail::endline<OStream> {
+    return detail::endline<OStream>(os);
+}
+
+template<class OStream>
+auto println(OStream& os)
+    -> decltype(detail::print_followed_with(os, endline(os))) {
+    return      detail::print_followed_with(os, endline(os));
+}
+template<class OStream, class Delimit>
+auto print_followed_with(OStream& os, Delimit d)
+    -> decltype(detail::print_followed_with(os, detail::insert_function<OStream, Delimit>(os, std::move(d)))) {
+    return      detail::print_followed_with(os, detail::insert_function<OStream, Delimit>(os, std::move(d)));
+}
+template<class OStream, class DelimitValue>
+auto print_followed_by(OStream& os, DelimitValue dv)
+    -> decltype(detail::print_followed_with(os, detail::insert_value<OStream, DelimitValue>(os, std::move(dv)))) {
+    return      detail::print_followed_with(os, detail::insert_value<OStream, DelimitValue>(os, std::move(dv)));
+}
+
+namespace detail {
+
+template <class T>
+class maybe
+{
+    bool is_set;
+    typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type
+        storage;
+public:
+    maybe()
+    : is_set(false)
+    {
+    }
+
+    maybe(T value)
+    : is_set(false)
+    {
+        new (reinterpret_cast<T*>(&storage)) T(value);
+        is_set = true;
+    }
+
+    maybe(const maybe& other)
+    : is_set(false)
+    {
+        if (other.is_set) {
+            new (reinterpret_cast<T*>(&storage)) T(other.get());
+            is_set = true;
+        }
+    }
+    maybe(maybe&& other)
+    : is_set(false)
+    {
+        if (other.is_set) {
+            new (reinterpret_cast<T*>(&storage)) T(std::move(other.get()));
+            is_set = true;
+            other.reset();
+        }
+    }
+
+    ~maybe()
+    {
+        reset();
+    }
+
+    typedef T value_type;
+    typedef T* iterator;
+    typedef const T* const_iterator;
+
+    bool empty() const {
+        return !is_set;
+    }
+
+    size_t size() const {
+        return is_set ? 1 : 0;
+    }
+
+    iterator begin() {
+        return reinterpret_cast<T*>(&storage);
+    }
+    const_iterator begin() const {
+        return reinterpret_cast<T*>(&storage);
+    }
+
+    iterator end() {
+        return reinterpret_cast<T*>(&storage) + size();
+    }
+    const_iterator end() const {
+        return reinterpret_cast<T*>(&storage) + size();
+    }
+
+    T* operator->() {
+        if (!is_set) abort();
+        return reinterpret_cast<T*>(&storage);
+    }
+    const T* operator->() const {
+        if (!is_set) abort();
+        return reinterpret_cast<T*>(&storage);
+    }
+
+    T& operator*() {
+        if (!is_set) abort();
+        return *reinterpret_cast<T*>(&storage);
+    }
+    const T& operator*() const {
+        if (!is_set) abort();
+        return *reinterpret_cast<T*>(&storage);
+    }
+
+    T& get() {
+        if (!is_set) abort();
+        return *reinterpret_cast<T*>(&storage);
+    }
+    const T& get() const {
+        if (!is_set) abort();
+        return *reinterpret_cast<const T*>(&storage);
+    }
+
+    void reset()
+    {
+        if (is_set) {
+            is_set = false;
+            reinterpret_cast<T*>(&storage)->~T();
+            //std::fill_n(reinterpret_cast<char*>(&storage), sizeof(T), 0);
+        }
+    }
+
+    template<class U>
+    void reset(U&& value) {
+        reset();
+        new (reinterpret_cast<T*>(&storage)) T(std::forward<U>(value));
+        is_set = true;
+    }
+
+    maybe& operator=(const T& other) {
+        reset(other);
+        return *this;
+    }
+    maybe& operator=(const maybe& other) {
+        if (!other.empty()) {
+            reset(other.get());
+        } else {
+            reset();
+        }
+        return *this;
+    }
+};
+
+}
+using detail::maybe;
+
+namespace detail {
+    struct surely
+    {
+        template<class... T>
+        auto operator()(T... t)
+            -> decltype(std::make_tuple(t.get()...)) {
+            return      std::make_tuple(t.get()...);
+        }
+        template<class... T>
+        auto operator()(T... t) const
+            -> decltype(std::make_tuple(t.get()...)) {
+            return      std::make_tuple(t.get()...);
+        }
+    };
+}
+
+template<class... T>
+inline auto surely(const std::tuple<T...>& tpl)
+    -> decltype(apply(tpl, detail::surely())) {
+    return      apply(tpl, detail::surely());
+}
+
+namespace detail {
+
+template<typename Function>
+class unwinder
+{
+public:
+    ~unwinder()
+    {
+        if (!!function)
+        {
+            try {
+                (*function)();
+            } catch (...) {
+                std::unexpected();
+            }
+        }
+    }
+
+    explicit unwinder(Function* functionArg)
+        : function(functionArg)
+    {
+    }
+
+    void dismiss()
+    {
+        function = nullptr;
+    }
+
+private:
+    unwinder();
+    unwinder(const unwinder&);
+    unwinder& operator=(const unwinder&);
+
+    Function* function;
+};
+
+}
+
+}
+namespace rxu=util;
+
+}
+
+#define RXCPP_UNWIND(Name, Function) \
+    RXCPP_UNWIND_EXPLICIT(uwfunc_ ## Name, Name, Function)
+
+#define RXCPP_UNWIND_AUTO(Function) \
+    RXCPP_UNWIND_EXPLICIT(RXCPP_MAKE_IDENTIFIER(uwfunc_), RXCPP_MAKE_IDENTIFIER(unwind_), Function)
+
+#define RXCPP_UNWIND_EXPLICIT(FunctionName, UnwinderName, Function) \
+    auto FunctionName = (Function); \
+    rxcpp::util::detail::unwinder<decltype(FunctionName)> UnwinderName(std::addressof(FunctionName))
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/rx.hpp b/dependencies64/RxCpp/include/rxcpp/rx.hpp
new file mode 100644 (file)
index 0000000..79bd4fd
--- /dev/null
@@ -0,0 +1,10 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_RX_HPP)
+#define RXCPP_RX_HPP
+
+#include "rx-includes.hpp"
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/schedulers/rx-currentthread.hpp b/dependencies64/RxCpp/include/rxcpp/schedulers/rx-currentthread.hpp
new file mode 100644 (file)
index 0000000..3c7bb90
--- /dev/null
@@ -0,0 +1,262 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_RX_SCHEDULER_CURRENT_THREAD_HPP)
+#define RXCPP_RX_SCHEDULER_CURRENT_THREAD_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace schedulers {
+
+namespace detail {
+
+struct action_queue
+{
+    typedef action_queue this_type;
+
+    typedef scheduler_base::clock_type clock;
+    typedef time_schedulable<clock::time_point> item_type;
+
+private:
+    typedef schedulable_queue<item_type::time_point_type> queue_item_time;
+
+public:
+    struct current_thread_queue_type {
+        std::shared_ptr<worker_interface> w;
+        recursion r;
+        queue_item_time queue;
+    };
+
+private:
+    static current_thread_queue_type*& current_thread_queue() {
+        static RXCPP_THREAD_LOCAL current_thread_queue_type* queue;
+        return queue;
+    }
+
+public:
+
+    static bool owned() {
+        return !!current_thread_queue();
+    }
+    static const std::shared_ptr<worker_interface>& get_worker_interface() {
+        return current_thread_queue()->w;
+    }
+    static recursion& get_recursion() {
+        return current_thread_queue()->r;
+    }
+    static bool empty() {
+        if (!current_thread_queue()) {
+            abort();
+        }
+        return current_thread_queue()->queue.empty();
+    }
+    static queue_item_time::const_reference top() {
+        if (!current_thread_queue()) {
+            abort();
+        }
+        return current_thread_queue()->queue.top();
+    }
+    static void pop() {
+        auto state = current_thread_queue();
+        if (!state) {
+            abort();
+        }
+        state->queue.pop();
+        if (state->queue.empty()) {
+            // allow recursion
+            state->r.reset(true);
+        }
+    }
+    static void push(item_type item) {
+        auto state = current_thread_queue();
+        if (!state) {
+            abort();
+        }
+        if (!item.what.is_subscribed()) {
+            return;
+        }
+        state->queue.push(std::move(item));
+        // disallow recursion
+        state->r.reset(false);
+    }
+    static std::shared_ptr<worker_interface> ensure(std::shared_ptr<worker_interface> w) {
+        if (!!current_thread_queue()) {
+            abort();
+        }
+        // create and publish new queue
+        current_thread_queue() = new current_thread_queue_type();
+        current_thread_queue()->w = w;
+        return w;
+    }
+    static std::unique_ptr<current_thread_queue_type> create(std::shared_ptr<worker_interface> w) {
+        std::unique_ptr<current_thread_queue_type> result(new current_thread_queue_type());
+        result->w = std::move(w);
+        return result;
+    }
+    static void set(current_thread_queue_type* queue) {
+        if (!!current_thread_queue()) {
+            abort();
+        }
+        // publish new queue
+        current_thread_queue() = queue;
+    }
+    static void destroy(current_thread_queue_type* queue) {
+        delete queue;
+    }
+    static void destroy() {
+        if (!current_thread_queue()) {
+            abort();
+        }
+        destroy(current_thread_queue());
+        current_thread_queue() = nullptr;
+    }
+};
+
+
+}
+
+struct current_thread : public scheduler_interface
+{
+private:
+    typedef current_thread this_type;
+    current_thread(const this_type&);
+
+    typedef detail::action_queue queue;
+
+    struct derecurser : public worker_interface
+    {
+    private:
+        typedef current_thread this_type;
+        derecurser(const this_type&);
+    public:
+        derecurser()
+        {
+        }
+        virtual ~derecurser()
+        {
+        }
+
+        virtual clock_type::time_point now() const {
+            return clock_type::now();
+        }
+
+        virtual void schedule(const schedulable& scbl) const {
+            queue::push(queue::item_type(now(), scbl));
+        }
+
+        virtual void schedule(clock_type::time_point when, const schedulable& scbl) const {
+            queue::push(queue::item_type(when, scbl));
+        }
+    };
+
+    struct current_worker : public worker_interface
+    {
+    private:
+        typedef current_thread this_type;
+        current_worker(const this_type&);
+    public:
+        current_worker()
+        {
+        }
+        virtual ~current_worker()
+        {
+        }
+
+        virtual clock_type::time_point now() const {
+            return clock_type::now();
+        }
+
+        virtual void schedule(const schedulable& scbl) const {
+            schedule(now(), scbl);
+        }
+
+        virtual void schedule(clock_type::time_point when, const schedulable& scbl) const {
+            if (!scbl.is_subscribed()) {
+                return;
+            }
+
+            {
+                // check ownership
+                if (queue::owned()) {
+                    // already has an owner - delegate
+                    queue::get_worker_interface()->schedule(when, scbl);
+                    return;
+                }
+
+                // take ownership
+                queue::ensure(std::make_shared<derecurser>());
+            }
+            // release ownership
+            RXCPP_UNWIND_AUTO([]{
+                queue::destroy();
+            });
+
+            const auto& recursor = queue::get_recursion().get_recurse();
+            std::this_thread::sleep_until(when);
+            if (scbl.is_subscribed()) {
+                scbl(recursor);
+            }
+            if (queue::empty()) {
+                return;
+            }
+
+            // loop until queue is empty
+            for (
+                auto next = queue::top().when;
+                (std::this_thread::sleep_until(next), true);
+                next = queue::top().when
+            ) {
+                auto what = queue::top().what;
+
+                queue::pop();
+
+                if (what.is_subscribed()) {
+                    what(recursor);
+                }
+
+                if (queue::empty()) {
+                    break;
+                }
+            }
+        }
+    };
+
+    std::shared_ptr<current_worker> wi;
+
+public:
+    current_thread()
+        : wi(new current_worker())
+    {
+    }
+    virtual ~current_thread()
+    {
+    }
+
+    static bool is_schedule_required() { return !queue::owned(); }
+
+    inline bool is_tail_recursion_allowed() const {
+        return queue::empty();
+    }
+
+    virtual clock_type::time_point now() const {
+        return clock_type::now();
+    }
+
+    virtual worker create_worker(composite_subscription cs) const {
+        return worker(std::move(cs), wi);
+    }
+};
+
+inline const scheduler& make_current_thread() {
+    static auto ct = make_scheduler<current_thread>();
+    return ct;
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/schedulers/rx-eventloop.hpp b/dependencies64/RxCpp/include/rxcpp/schedulers/rx-eventloop.hpp
new file mode 100644 (file)
index 0000000..fc8deb7
--- /dev/null
@@ -0,0 +1,110 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_RX_SCHEDULER_EVENT_LOOP_HPP)
+#define RXCPP_RX_SCHEDULER_EVENT_LOOP_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace schedulers {
+
+struct event_loop : public scheduler_interface
+{
+private:
+    typedef event_loop this_type;
+    event_loop(const this_type&);
+
+    struct loop_worker : public worker_interface
+    {
+    private:
+        typedef loop_worker this_type;
+        loop_worker(const this_type&);
+
+        typedef detail::schedulable_queue<
+            typename clock_type::time_point> queue_item_time;
+
+        typedef queue_item_time::item_type item_type;
+
+        composite_subscription lifetime;
+        worker controller;
+
+    public:
+        virtual ~loop_worker()
+        {
+        }
+        loop_worker(composite_subscription cs, worker w)
+            : lifetime(cs)
+            , controller(w)
+        {
+        }
+
+        virtual clock_type::time_point now() const {
+            return clock_type::now();
+        }
+
+        virtual void schedule(const schedulable& scbl) const {
+            controller.schedule(lifetime, scbl.get_action());
+        }
+
+        virtual void schedule(clock_type::time_point when, const schedulable& scbl) const {
+            controller.schedule(when, lifetime, scbl.get_action());
+        }
+    };
+
+    mutable thread_factory factory;
+    scheduler newthread;
+    mutable std::atomic<size_t> count;
+    std::vector<worker> loops;
+
+public:
+    event_loop()
+        : factory([](std::function<void()> start){
+            return std::thread(std::move(start));
+        })
+        , newthread(make_new_thread())
+        , count(0)
+    {
+        auto remaining = std::max(std::thread::hardware_concurrency(), unsigned(4));
+        while (--remaining) {
+            loops.push_back(newthread.create_worker());
+        }
+    }
+    explicit event_loop(thread_factory tf)
+        : factory(tf)
+        , newthread(make_new_thread(tf))
+        , count(0)
+    {
+        auto remaining = std::max(std::thread::hardware_concurrency(), unsigned(4));
+        while (--remaining) {
+            loops.push_back(newthread.create_worker());
+        }
+    }
+    virtual ~event_loop()
+    {
+    }
+
+    virtual clock_type::time_point now() const {
+        return clock_type::now();
+    }
+
+    virtual worker create_worker(composite_subscription cs) const {
+        return worker(cs, std::shared_ptr<loop_worker>(new loop_worker(cs, loops[++count % loops.size()])));
+    }
+};
+
+inline scheduler make_event_loop() {
+    static auto loop = make_scheduler<event_loop>();
+    return loop;
+}
+inline scheduler make_event_loop(thread_factory tf) {
+    return make_scheduler<event_loop>(tf);
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/schedulers/rx-immediate.hpp b/dependencies64/RxCpp/include/rxcpp/schedulers/rx-immediate.hpp
new file mode 100644 (file)
index 0000000..73592ec
--- /dev/null
@@ -0,0 +1,84 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_RX_SCHEDULER_IMMEDIATE_HPP)
+#define RXCPP_RX_SCHEDULER_IMMEDIATE_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace schedulers {
+
+struct immediate : public scheduler_interface
+{
+private:
+    typedef immediate this_type;
+    immediate(const this_type&);
+
+    struct immediate_worker : public worker_interface
+    {
+    private:
+        typedef immediate_worker this_type;
+        immediate_worker(const this_type&);
+    public:
+        virtual ~immediate_worker()
+        {
+        }
+        immediate_worker()
+        {
+        }
+
+        virtual clock_type::time_point now() const {
+            return clock_type::now();
+        }
+
+        virtual void schedule(const schedulable& scbl) const {
+            if (scbl.is_subscribed()) {
+                // allow recursion
+                recursion r(true);
+                scbl(r.get_recurse());
+            }
+        }
+
+        virtual void schedule(clock_type::time_point when, const schedulable& scbl) const {
+            std::this_thread::sleep_until(when);
+            if (scbl.is_subscribed()) {
+                // allow recursion
+                recursion r(true);
+                scbl(r.get_recurse());
+            }
+        }
+    };
+
+    std::shared_ptr<immediate_worker> wi;
+
+public:
+    immediate()
+        : wi(new immediate_worker())
+    {
+    }
+    virtual ~immediate()
+    {
+    }
+
+    virtual clock_type::time_point now() const {
+        return clock_type::now();
+    }
+
+    virtual worker create_worker(composite_subscription cs) const {
+        return worker(std::move(cs), wi);
+    }
+};
+
+inline const scheduler& make_immediate() {
+    static auto i = make_scheduler<immediate>();
+    return i;
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/schedulers/rx-newthread.hpp b/dependencies64/RxCpp/include/rxcpp/schedulers/rx-newthread.hpp
new file mode 100644 (file)
index 0000000..4144053
--- /dev/null
@@ -0,0 +1,179 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_RX_SCHEDULER_NEW_THREAD_HPP)
+#define RXCPP_RX_SCHEDULER_NEW_THREAD_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace schedulers {
+
+typedef std::function<std::thread(std::function<void()>)> thread_factory;
+
+struct new_thread : public scheduler_interface
+{
+private:
+    typedef new_thread this_type;
+    new_thread(const this_type&);
+
+    struct new_worker : public worker_interface
+    {
+    private:
+        typedef new_worker this_type;
+
+        typedef detail::action_queue queue;
+
+        new_worker(const this_type&);
+
+        struct new_worker_state : public std::enable_shared_from_this<new_worker_state>
+        {
+            typedef detail::schedulable_queue<
+                typename clock_type::time_point> queue_item_time;
+
+            typedef queue_item_time::item_type item_type;
+
+            virtual ~new_worker_state()
+            {
+                std::unique_lock<std::mutex> guard(lock);
+                if (worker.joinable() && worker.get_id() != std::this_thread::get_id()) {
+                    lifetime.unsubscribe();
+                    guard.unlock();
+                    worker.join();
+                }
+                else {
+                    lifetime.unsubscribe();
+                    worker.detach();
+                }
+            }
+
+            explicit new_worker_state(composite_subscription cs)
+                : lifetime(cs)
+            {
+            }
+
+            composite_subscription lifetime;
+            mutable std::mutex lock;
+            mutable std::condition_variable wake;
+            mutable queue_item_time queue;
+            std::thread worker;
+            recursion r;
+        };
+
+        std::shared_ptr<new_worker_state> state;
+
+    public:
+        virtual ~new_worker()
+        {
+        }
+
+        explicit new_worker(std::shared_ptr<new_worker_state> ws)
+            : state(ws)
+        {
+        }
+
+        new_worker(composite_subscription cs, thread_factory& tf)
+            : state(std::make_shared<new_worker_state>(cs))
+        {
+            auto keepAlive = state;
+
+            state->lifetime.add([keepAlive](){
+                keepAlive->wake.notify_one();
+            });
+
+            state->worker = tf([keepAlive](){
+
+                // take ownership
+                queue::ensure(std::make_shared<new_worker>(keepAlive));
+                // release ownership
+                RXCPP_UNWIND_AUTO([]{
+                    queue::destroy();
+                });
+
+                for(;;) {
+                    std::unique_lock<std::mutex> guard(keepAlive->lock);
+                    if (keepAlive->queue.empty()) {
+                        keepAlive->wake.wait(guard, [keepAlive](){
+                            return !keepAlive->lifetime.is_subscribed() || !keepAlive->queue.empty();
+                        });
+                    }
+                    if (!keepAlive->lifetime.is_subscribed()) {
+                        break;
+                    }
+                    auto& peek = keepAlive->queue.top();
+                    if (!peek.what.is_subscribed()) {
+                        keepAlive->queue.pop();
+                        continue;
+                    }
+                    if (clock_type::now() < peek.when) {
+                        keepAlive->wake.wait_until(guard, peek.when);
+                        continue;
+                    }
+                    auto what = peek.what;
+                    keepAlive->queue.pop();
+                    keepAlive->r.reset(keepAlive->queue.empty());
+                    guard.unlock();
+                    what(keepAlive->r.get_recurse());
+                }
+            });
+        }
+
+        virtual clock_type::time_point now() const {
+            return clock_type::now();
+        }
+
+        virtual void schedule(const schedulable& scbl) const {
+            schedule(now(), scbl);
+        }
+
+        virtual void schedule(clock_type::time_point when, const schedulable& scbl) const {
+            if (scbl.is_subscribed()) {
+                std::unique_lock<std::mutex> guard(state->lock);
+                state->queue.push(new_worker_state::item_type(when, scbl));
+                state->r.reset(false);
+            }
+            state->wake.notify_one();
+        }
+    };
+
+    mutable thread_factory factory;
+
+public:
+    new_thread()
+        : factory([](std::function<void()> start){
+            return std::thread(std::move(start));
+        })
+    {
+    }
+    explicit new_thread(thread_factory tf)
+        : factory(tf)
+    {
+    }
+    virtual ~new_thread()
+    {
+    }
+
+    virtual clock_type::time_point now() const {
+        return clock_type::now();
+    }
+
+    virtual worker create_worker(composite_subscription cs) const {
+        return worker(cs, std::shared_ptr<new_worker>(new new_worker(cs, factory)));
+    }
+};
+
+inline scheduler make_new_thread() {
+    static auto nt = make_scheduler<new_thread>();
+    return nt;
+}
+inline scheduler make_new_thread(thread_factory tf) {
+    return make_scheduler<new_thread>(tf);
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/schedulers/rx-sameworker.hpp b/dependencies64/RxCpp/include/rxcpp/schedulers/rx-sameworker.hpp
new file mode 100644 (file)
index 0000000..5b3ff4e
--- /dev/null
@@ -0,0 +1,53 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_RX_SCHEDULER_SAME_WORKER_HPP)
+#define RXCPP_RX_SCHEDULER_SAME_WORKER_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace schedulers {
+
+struct same_worker : public scheduler_interface
+{
+private:
+    typedef same_worker this_type;
+    same_worker(const this_type&);
+
+    rxsc::worker controller;
+
+public:
+    explicit same_worker(rxsc::worker w)
+        : controller(std::move(w))
+    {
+    }
+    virtual ~same_worker()
+    {
+    }
+
+    virtual clock_type::time_point now() const {
+        return controller.now();
+    }
+
+    virtual worker create_worker(composite_subscription cs) const {
+        // use different lifetime
+        auto inner_lifetime = controller.get_subscription();
+        auto token = inner_lifetime.add(cs);
+        cs.add([inner_lifetime, token](){inner_lifetime.remove(token);});
+        return worker(cs, controller);
+    }
+};
+
+inline scheduler make_same_worker(rxsc::worker w) {
+    auto i = make_scheduler<same_worker>(std::move(w));
+    return i;
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/schedulers/rx-test.hpp b/dependencies64/RxCpp/include/rxcpp/schedulers/rx-test.hpp
new file mode 100644 (file)
index 0000000..ec77c40
--- /dev/null
@@ -0,0 +1,614 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_RX_SCHEDULER_TEST_HPP)
+#define RXCPP_RX_SCHEDULER_TEST_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace schedulers {
+
+namespace detail {
+
+class test_type : public scheduler_interface
+{
+public:
+
+    typedef scheduler_interface::clock_type clock_type;
+
+    struct test_type_state : public virtual_time<long, long>
+    {
+        typedef virtual_time<long, long> base;
+
+        using base::schedule_absolute;
+        using base::schedule_relative;
+
+        clock_type::time_point now() const {
+            return to_time_point(clock_now);
+        }
+
+        virtual void schedule_absolute(long when, const schedulable& a) const
+        {
+            if (when <= base::clock_now)
+                when = base::clock_now + 1;
+
+            return base::schedule_absolute(when, a);
+        }
+
+        virtual long add(long absolute, long relative) const
+        {
+            return absolute + relative;
+        }
+
+        virtual clock_type::time_point to_time_point(long absolute) const
+        {
+            return clock_type::time_point(std::chrono::milliseconds(absolute));
+        }
+
+        virtual long to_relative(clock_type::duration d) const
+        {
+            return static_cast<long>(std::chrono::duration_cast<std::chrono::milliseconds>(d).count());
+        }
+    };
+
+private:
+    mutable std::shared_ptr<test_type_state> state;
+
+public:
+    struct test_type_worker : public worker_interface
+    {
+        mutable std::shared_ptr<test_type_state> state;
+
+        typedef test_type_state::absolute absolute;
+        typedef test_type_state::relative relative;
+
+        test_type_worker(std::shared_ptr<test_type_state> st)
+            : state(std::move(st))
+        {
+        }
+
+        virtual clock_type::time_point now() const {
+            return state->now();
+        }
+
+        virtual void schedule(const schedulable& scbl) const {
+            state->schedule_absolute(state->clock(), scbl);
+        }
+
+        virtual void schedule(clock_type::time_point when, const schedulable& scbl) const {
+            state->schedule_relative(state->to_relative(when - now()), scbl);
+        }
+
+        void schedule_absolute(absolute when, const schedulable& scbl) const {
+            state->schedule_absolute(when, scbl);
+        }
+
+        void schedule_relative(relative when, const schedulable& scbl) const {
+            state->schedule_relative(when, scbl);
+        }
+
+        bool is_enabled() const {return state->is_enabled();}
+        absolute clock() const {return state->clock();}
+
+        void start() const
+        {
+            state->start();
+        }
+
+        void stop() const
+        {
+            state->stop();
+        }
+
+        void advance_to(absolute time) const
+        {
+            state->advance_to(time);
+        }
+
+        void advance_by(relative time) const
+        {
+            state->advance_by(time);
+        }
+
+        void sleep(relative time) const
+        {
+            state->sleep(time);
+        }
+
+        template<class T>
+        subscriber<T, rxt::testable_observer<T>> make_subscriber() const;
+    };
+
+public:
+    test_type()
+        : state(new test_type_state())
+    {
+    }
+
+    virtual clock_type::time_point now() const {
+        return state->now();
+    }
+
+    virtual worker create_worker(composite_subscription cs) const {
+        std::shared_ptr<test_type_worker> wi(new test_type_worker(state));
+        return worker(cs, wi);
+    }
+
+    bool is_enabled() const {return state->is_enabled();}
+    long clock() {
+        return state->clock();
+    }
+
+    std::shared_ptr<test_type_worker> create_test_type_worker_interface() const {
+        std::shared_ptr<test_type_worker> wi(new test_type_worker(state));
+        return wi;
+    }
+
+    template<class T>
+    rxt::testable_observable<T> make_hot_observable(std::vector<rxn::recorded<std::shared_ptr<rxn::detail::notification_base<T>>>> messages) const;
+
+    template<class T>
+    rxt::testable_observable<T> make_cold_observable(std::vector<rxn::recorded<std::shared_ptr<rxn::detail::notification_base<T>>>> messages) const;
+};
+
+template<class T>
+class mock_observer
+    : public rxt::detail::test_subject_base<T>
+{
+    typedef typename rxn::notification<T> notification_type;
+    typedef rxn::recorded<typename notification_type::type> recorded_type;
+
+public:
+    explicit mock_observer(std::shared_ptr<test_type::test_type_state> sc)
+        : sc(sc)
+    {
+    }
+
+    std::shared_ptr<test_type::test_type_state> sc;
+    std::vector<recorded_type> m;
+
+    virtual void on_subscribe(subscriber<T>) const {
+        abort();
+    }
+    virtual std::vector<rxn::subscription> subscriptions() const {
+        abort(); return std::vector<rxn::subscription>();
+    }
+
+    virtual std::vector<recorded_type> messages() const {
+        return m;
+    }
+};
+
+template<class T>
+subscriber<T, rxt::testable_observer<T>> test_type::test_type_worker::make_subscriber() const
+{
+    typedef typename rxn::notification<T> notification_type;
+    typedef rxn::recorded<typename notification_type::type> recorded_type;
+
+    std::shared_ptr<mock_observer<T>> ts(new mock_observer<T>(state));
+
+    return rxcpp::make_subscriber<T>(rxt::testable_observer<T>(ts, make_observer_dynamic<T>(
+          // on_next
+          [ts](T value)
+          {
+              ts->m.push_back(
+                              recorded_type(ts->sc->clock(), notification_type::on_next(value)));
+          },
+          // on_error
+          [ts](std::exception_ptr e)
+          {
+              ts->m.push_back(
+                              recorded_type(ts->sc->clock(), notification_type::on_error(e)));
+          },
+          // on_completed
+          [ts]()
+          {
+              ts->m.push_back(
+                              recorded_type(ts->sc->clock(), notification_type::on_completed()));
+          })));
+}
+
+template<class T>
+class cold_observable
+    : public rxt::detail::test_subject_base<T>
+{
+    typedef cold_observable<T> this_type;
+    std::shared_ptr<test_type::test_type_state> sc;
+    typedef rxn::recorded<typename rxn::notification<T>::type> recorded_type;
+    mutable std::vector<recorded_type> mv;
+    mutable std::vector<rxn::subscription> sv;
+    mutable worker controller;
+
+public:
+
+    cold_observable(std::shared_ptr<test_type::test_type_state> sc, worker w, std::vector<recorded_type> mv)
+        : sc(sc)
+        , mv(std::move(mv))
+        , controller(w)
+    {
+    }
+
+    template<class Iterator>
+    cold_observable(std::shared_ptr<test_type::test_type_state> sc, worker w, Iterator begin, Iterator end)
+        : sc(sc)
+        , mv(begin, end)
+        , controller(w)
+    {
+    }
+
+    virtual void on_subscribe(subscriber<T> o) const {
+        sv.push_back(rxn::subscription(sc->clock()));
+        auto index = sv.size() - 1;
+
+        for (auto& message : mv) {
+            auto n = message.value();
+            sc->schedule_relative(message.time(), make_schedulable(
+                controller,
+                [n, o](const schedulable& scbl) {
+                    if (o.is_subscribed()) {
+                        n->accept(o);
+                    }
+                }));
+        }
+
+        auto sharedThis = std::static_pointer_cast<const this_type>(this->shared_from_this());
+        o.add([sharedThis, index]() {
+            sharedThis->sv[index] = rxn::subscription(sharedThis->sv[index].subscribe(), sharedThis->sc->clock());
+        });
+    }
+
+    virtual std::vector<rxn::subscription> subscriptions() const {
+        return sv;
+    }
+
+    virtual std::vector<recorded_type> messages() const {
+        return mv;
+    }
+};
+
+template<class T>
+rxt::testable_observable<T> test_type::make_cold_observable(std::vector<rxn::recorded<std::shared_ptr<rxn::detail::notification_base<T>>>> messages) const
+{
+    auto co = std::shared_ptr<cold_observable<T>>(new cold_observable<T>(state, create_worker(composite_subscription()), std::move(messages)));
+    return rxt::testable_observable<T>(co);
+}
+
+template<class T>
+class hot_observable
+    : public rxt::detail::test_subject_base<T>
+{
+    typedef hot_observable<T> this_type;
+    std::shared_ptr<test_type::test_type_state> sc;
+    typedef rxn::recorded<typename rxn::notification<T>::type> recorded_type;
+    typedef subscriber<T> observer_type;
+    mutable std::vector<recorded_type> mv;
+    mutable std::vector<rxn::subscription> sv;
+    mutable std::vector<observer_type> observers;
+    mutable worker controller;
+
+public:
+
+    hot_observable(std::shared_ptr<test_type::test_type_state> sc, worker w, std::vector<recorded_type> mv)
+        : sc(sc)
+        , mv(mv)
+        , controller(w)
+    {
+        for (auto& message : mv) {
+            auto n = message.value();
+            sc->schedule_absolute(message.time(), make_schedulable(
+                controller,
+                [this, n](const schedulable& scbl) {
+                    auto local = this->observers;
+                    for (auto& o : local) {
+                        if (o.is_subscribed()) {
+                            n->accept(o);
+                        }
+                    }
+                }));
+        }
+    }
+
+    virtual void on_subscribe(observer_type o) const {
+        observers.push_back(o);
+        sv.push_back(rxn::subscription(sc->clock()));
+        auto index = sv.size() - 1;
+
+        auto sharedThis = std::static_pointer_cast<const this_type>(this->shared_from_this());
+        o.add([sharedThis, index]() {
+            sharedThis->sv[index] = rxn::subscription(sharedThis->sv[index].subscribe(), sharedThis->sc->clock());
+        });
+    }
+
+    virtual std::vector<rxn::subscription> subscriptions() const {
+        return sv;
+    }
+
+    virtual std::vector<recorded_type> messages() const {
+        return mv;
+    }
+};
+
+template<class T>
+rxt::testable_observable<T> test_type::make_hot_observable(std::vector<rxn::recorded<std::shared_ptr<rxn::detail::notification_base<T>>>> messages) const
+{
+    return rxt::testable_observable<T>(
+        std::make_shared<hot_observable<T>>(state, create_worker(composite_subscription()), std::move(messages)));
+}
+
+template<class F>
+struct is_create_source_function
+{
+    struct not_void {};
+    template<class CF>
+    static auto check(int) -> decltype((*(CF*)nullptr)());
+    template<class CF>
+    static not_void check(...);
+
+    static const bool value = is_observable<decltype(check<typename std::decay<F>::type>(0))>::value;
+};
+
+}
+
+class test : public scheduler
+{
+    std::shared_ptr<detail::test_type> tester;
+public:
+
+    explicit test(std::shared_ptr<detail::test_type> t)
+        : scheduler(std::static_pointer_cast<scheduler_interface>(t))
+        , tester(t)
+    {
+    }
+
+    typedef detail::test_type::clock_type clock_type;
+
+    static const long created_time = 100;
+    static const long subscribed_time = 200;
+    static const long unsubscribed_time = 1000;
+
+    template<class T>
+    struct messages
+    {
+        typedef typename rxn::notification<T> notification_type;
+        typedef rxn::recorded<typename notification_type::type> recorded_type;
+        typedef rxn::subscription subscription_type;
+
+        messages() {}
+
+        struct on_next_factory
+        {
+            recorded_type operator()(long ticks, T value) const {
+                return recorded_type(ticks, notification_type::on_next(value));
+            }
+        };
+        struct on_completed_factory
+        {
+            recorded_type operator()(long ticks) const {
+                return recorded_type(ticks, notification_type::on_completed());
+            }
+        };
+        struct on_error_factory
+        {
+            template<class Exception>
+            recorded_type operator()(long ticks, Exception&& e) const {
+                return recorded_type(ticks, notification_type::on_error(std::forward<Exception>(e)));
+            }
+        };
+
+        static const on_next_factory next;
+        static const on_completed_factory completed;
+        static const on_error_factory error;
+
+        struct subscribe_factory
+        {
+            rxn::subscription operator()(long subscribe, long unsubscribe) const {
+                return rxn::subscription(subscribe, unsubscribe);
+            }
+        };
+        static const subscribe_factory subscribe;
+    };
+
+    class test_worker : public worker
+    {
+        std::shared_ptr<detail::test_type::test_type_worker> tester;
+    public:
+
+        explicit test_worker(composite_subscription cs, std::shared_ptr<detail::test_type::test_type_worker> t)
+            : worker(cs, std::static_pointer_cast<worker_interface>(t))
+            , tester(t)
+        {
+        }
+
+        bool is_enabled() const {return tester->is_enabled();}
+        long clock() const {return tester->clock();}
+
+        void schedule_absolute(long when, const schedulable& a) const {
+            tester->schedule_absolute(when, a);
+        }
+
+        void schedule_relative(long when, const schedulable& a) const {
+            tester->schedule_relative(when, a);
+        }
+
+        template<class Arg0, class... ArgN>
+        auto schedule_absolute(long when, Arg0&& a0, ArgN&&... an) const
+            -> typename std::enable_if<
+                (detail::is_action_function<Arg0>::value ||
+                is_subscription<Arg0>::value) &&
+                !is_schedulable<Arg0>::value>::type {
+            tester->schedule_absolute(when, make_schedulable(*this, std::forward<Arg0>(a0), std::forward<ArgN>(an)...));
+        }
+
+        template<class Arg0, class... ArgN>
+        auto schedule_relative(long when, Arg0&& a0, ArgN&&... an) const
+            -> typename std::enable_if<
+                (detail::is_action_function<Arg0>::value ||
+                is_subscription<Arg0>::value) &&
+                !is_schedulable<Arg0>::value>::type {
+            tester->schedule_relative(when, make_schedulable(*this, std::forward<Arg0>(a0), std::forward<ArgN>(an)...));
+        }
+
+        template<class T, class F>
+        auto start(F createSource, long created, long subscribed, long unsubscribed) const
+            -> subscriber<T, rxt::testable_observer<T>>
+        {
+            struct state_type
+            : public std::enable_shared_from_this<state_type>
+            {
+                typedef decltype(createSource()) source_type;
+
+                std::unique_ptr<source_type> source;
+                subscriber<T, rxt::testable_observer<T>> o;
+
+                explicit state_type(subscriber<T, rxt::testable_observer<T>> o)
+                : source()
+                , o(o)
+                {
+                }
+            };
+            std::shared_ptr<state_type> state(new state_type(this->make_subscriber<T>()));
+
+            schedule_absolute(created, [createSource, state](const schedulable& scbl) {
+                state->source.reset(new typename state_type::source_type(createSource()));
+            });
+            schedule_absolute(subscribed, [state](const schedulable& scbl) {
+                state->source->subscribe(state->o);
+            });
+            schedule_absolute(unsubscribed, [state](const schedulable& scbl) {
+                state->o.unsubscribe();
+            });
+
+            tester->start();
+
+            return state->o;
+        }
+
+        template<class T, class F>
+        auto start(F&& createSource, long unsubscribed) const
+            -> subscriber<T, rxt::testable_observer<T>>
+        {
+            return start<T>(std::forward<F>(createSource), created_time, subscribed_time, unsubscribed);
+        }
+
+        template<class T, class F>
+        auto start(F&& createSource) const
+            -> subscriber<T, rxt::testable_observer<T>>
+        {
+            return start<T>(std::forward<F>(createSource), created_time, subscribed_time, unsubscribed_time);
+        }
+
+        template<class F>
+        struct start_traits
+        {
+            typedef decltype((*(F*)nullptr)()) source_type;
+            typedef typename source_type::value_type value_type;
+            typedef subscriber<value_type, rxt::testable_observer<value_type>> subscriber_type;
+        };
+
+        template<class F>
+        auto start(F createSource, long created, long subscribed, long unsubscribed) const
+            -> typename std::enable_if<detail::is_create_source_function<F>::value, start_traits<F>>::type::subscriber_type
+        {
+            return start<typename start_traits<F>::value_type>(std::move(createSource), created, subscribed, unsubscribed);
+        }
+
+        template<class F>
+        auto start(F createSource, long unsubscribed) const
+            -> typename std::enable_if<detail::is_create_source_function<F>::value, start_traits<F>>::type::subscriber_type
+        {
+            return start<typename start_traits<F>::value_type>(std::move(createSource), created_time, subscribed_time, unsubscribed);
+        }
+
+        template<class F>
+        auto start(F createSource) const
+            -> typename std::enable_if<detail::is_create_source_function<F>::value, start_traits<F>>::type::subscriber_type
+        {
+            return start<typename start_traits<F>::value_type>(std::move(createSource), created_time, subscribed_time, unsubscribed_time);
+        }
+
+        void start() const {
+            tester->start();
+        }
+
+        template<class T>
+        subscriber<T, rxt::testable_observer<T>> make_subscriber() const {
+            return tester->make_subscriber<T>();
+        }
+    };
+
+    clock_type::time_point now() const {
+        return tester->now();
+    }
+
+    test_worker create_worker(composite_subscription cs = composite_subscription()) const {
+        return test_worker(cs, tester->create_test_type_worker_interface());
+    }
+
+    bool is_enabled() const {return tester->is_enabled();}
+    long clock() const {return tester->clock();}
+
+    template<class T>
+    rxt::testable_observable<T> make_hot_observable(std::vector<rxn::recorded<std::shared_ptr<rxn::detail::notification_base<T>>>> messages) const{
+        return tester->make_hot_observable(std::move(messages));
+    }
+
+    template<class T, size_t size>
+    auto make_hot_observable(const T (&arr) [size]) const
+        -> decltype(tester->make_hot_observable(std::vector<T>())) {
+        return      tester->make_hot_observable(rxu::to_vector(arr));
+    }
+
+    template<class T>
+    auto make_hot_observable(std::initializer_list<T> il) const
+        -> decltype(tester->make_hot_observable(std::vector<T>())) {
+        return      tester->make_hot_observable(std::vector<T>(il));
+    }
+
+    template<class T>
+    rxt::testable_observable<T> make_cold_observable(std::vector<rxn::recorded<std::shared_ptr<rxn::detail::notification_base<T>>>> messages) const {
+        return tester->make_cold_observable(std::move(messages));
+    }
+
+    template<class T, size_t size>
+    auto make_cold_observable(const T (&arr) [size]) const
+        -> decltype(tester->make_cold_observable(std::vector<T>())) {
+        return      tester->make_cold_observable(rxu::to_vector(arr));
+    }
+
+    template<class T>
+    auto make_cold_observable(std::initializer_list<T> il) const
+        -> decltype(tester->make_cold_observable(std::vector<T>())) {
+        return      tester->make_cold_observable(std::vector<T>(il));
+    }
+};
+
+template<class T>
+//static
+RXCPP_SELECT_ANY const typename test::messages<T>::on_next_factory test::messages<T>::next = test::messages<T>::on_next_factory();
+
+template<class T>
+//static
+RXCPP_SELECT_ANY const typename test::messages<T>::on_completed_factory test::messages<T>::completed = test::messages<T>::on_completed_factory();
+
+template<class T>
+//static
+RXCPP_SELECT_ANY const typename test::messages<T>::on_error_factory test::messages<T>::error = test::messages<T>::on_error_factory();
+
+template<class T>
+//static
+RXCPP_SELECT_ANY const typename test::messages<T>::subscribe_factory test::messages<T>::subscribe = test::messages<T>::subscribe_factory();
+
+
+
+inline test make_test() {
+    return test(std::make_shared<detail::test_type>());
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/schedulers/rx-virtualtime.hpp b/dependencies64/RxCpp/include/rxcpp/schedulers/rx-virtualtime.hpp
new file mode 100644 (file)
index 0000000..bc42e5c
--- /dev/null
@@ -0,0 +1,229 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_RX_SCHEDULER_VIRTUAL_TIME_HPP)
+#define RXCPP_RX_SCHEDULER_VIRTUAL_TIME_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace schedulers {
+
+namespace detail {
+
+template<class Absolute, class Relative>
+struct virtual_time_base : std::enable_shared_from_this<virtual_time_base<Absolute, Relative>>
+{
+private:
+    typedef virtual_time_base<Absolute, Relative> this_type;
+    virtual_time_base(const virtual_time_base&);
+
+    mutable bool isenabled;
+
+public:
+    typedef Absolute absolute;
+    typedef Relative relative;
+
+    virtual ~virtual_time_base()
+    {
+    }
+
+protected:
+    virtual_time_base()
+        : isenabled(false)
+        , clock_now(0)
+    {
+    }
+    explicit virtual_time_base(absolute initialClock)
+        : isenabled(false)
+        , clock_now(initialClock)
+    {
+    }
+
+    mutable absolute clock_now;
+
+    typedef time_schedulable<long> item_type;
+
+    virtual absolute add(absolute, relative) const =0;
+
+    virtual typename scheduler_base::clock_type::time_point to_time_point(absolute) const =0;
+    virtual relative to_relative(typename scheduler_base::clock_type::duration) const =0;
+
+    virtual item_type top() const =0;
+    virtual void pop() const =0;
+    virtual bool empty() const =0;
+
+public:
+
+    virtual void schedule_absolute(absolute, const schedulable&) const =0;
+
+    virtual void schedule_relative(relative when, const schedulable& a) const {
+        auto at = add(clock_now, when);
+        return schedule_absolute(at, a);
+    }
+
+    bool is_enabled() const {return isenabled;}
+    absolute clock() const {return clock_now;}
+
+    void start() const
+    {
+        if (!isenabled) {
+            isenabled = true;
+            rxsc::recursion r;
+            r.reset(false);
+            while (!empty() && isenabled) {
+                auto next = top();
+                pop();
+                if (next.what.is_subscribed()) {
+                    if (next.when > clock_now) {
+                        clock_now = next.when;
+                    }
+                    next.what(r.get_recurse());
+                }
+                else {
+                    isenabled = false;
+                }
+            }
+        }
+    }
+
+    void stop() const
+    {
+        isenabled = false;
+    }
+
+    void advance_to(absolute time) const
+    {
+        if (time < clock_now) {
+            abort();
+        }
+
+        if (time == clock_now) {
+            return;
+        }
+
+        if (!isenabled) {
+            isenabled = true;
+            rxsc::recursion r;
+            while (!empty() && isenabled) {
+                auto next = top();
+                pop();
+                if (next.what.is_subscribed() && next.when <= time) {
+                    if (next.when > clock_now) {
+                        clock_now = next.when;
+                    }
+                    next.what(r.get_recurse());
+                }
+                else {
+                    isenabled = false;
+                }
+            }
+
+            clock_now = time;
+        }
+        else {
+            abort();
+        }
+    }
+
+    void advance_by(relative time) const
+    {
+        auto dt = add(clock_now, time);
+
+        if (dt < clock_now) {
+            abort();
+        }
+
+        if (dt == clock_now) {
+            return;
+        }
+
+        if (!isenabled) {
+            advance_to(dt);
+        }
+        else {
+            abort();
+        }
+    }
+
+    void sleep(relative time) const
+    {
+        auto dt = add(clock_now, time);
+
+        if (dt < clock_now) {
+            abort();
+        }
+
+        clock_now = dt;
+    }
+
+};
+
+}
+
+template<class Absolute, class Relative>
+struct virtual_time : public detail::virtual_time_base<Absolute, Relative>
+{
+    typedef detail::virtual_time_base<Absolute, Relative> base;
+
+    typedef typename base::item_type item_type;
+
+    typedef detail::schedulable_queue<
+        typename item_type::time_point_type> queue_item_time;
+
+    mutable queue_item_time queue;
+
+public:
+    virtual ~virtual_time()
+    {
+    }
+
+protected:
+    virtual_time()
+    {
+    }
+    explicit virtual_time(typename base::absolute initialClock)
+        : base(initialClock)
+    {
+    }
+
+    virtual item_type top() const {
+        return queue.top();
+    }
+    virtual void pop() const {
+        queue.pop();
+    }
+    virtual bool empty() const {
+        return queue.empty();
+    }
+
+    using base::schedule_absolute;
+    using base::schedule_relative;
+
+    virtual void schedule_absolute(typename base::absolute when, const schedulable& a) const
+    {
+        // use a separate subscription here so that a's subscription is not affected
+        auto run = make_schedulable(
+            a.get_worker(),
+            composite_subscription(),
+            [a](const schedulable& scbl) {
+                rxsc::recursion r;
+                r.reset(false);
+                if (scbl.is_subscribed()) {
+                    scbl.unsubscribe(); // unsubscribe() run, not a;
+                    a(r.get_recurse());
+                }
+            });
+        queue.push(item_type(when, run));
+    }
+};
+
+
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/sources/rx-create.hpp b/dependencies64/RxCpp/include/rxcpp/sources/rx-create.hpp
new file mode 100644 (file)
index 0000000..2c50e98
--- /dev/null
@@ -0,0 +1,55 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_SOURCES_RX_CREATE_HPP)
+#define RXCPP_SOURCES_RX_CREATE_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace sources {
+
+namespace detail {
+
+template<class T, class OnSubscribe>
+struct create : public source_base<T>
+{
+    typedef create<T, OnSubscribe> this_type;
+
+    typedef typename std::decay<OnSubscribe>::type on_subscribe_type;
+
+    on_subscribe_type on_subscribe_function;
+
+    create(on_subscribe_type os)
+        : on_subscribe_function(std::move(os))
+    {
+    }
+
+    template<class Subscriber>
+    void on_subscribe(Subscriber o) const {
+
+        on_exception(
+            [&](){
+                this->on_subscribe_function(o);
+                return true;
+            },
+            o);
+    }
+};
+
+}
+
+template<class T, class OnSubscribe>
+auto create(OnSubscribe os)
+    ->      observable<T,   detail::create<T, OnSubscribe>> {
+    return  observable<T,   detail::create<T, OnSubscribe>>(
+                            detail::create<T, OnSubscribe>(std::move(os)));
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/sources/rx-defer.hpp b/dependencies64/RxCpp/include/rxcpp/sources/rx-defer.hpp
new file mode 100644 (file)
index 0000000..5aef7ef
--- /dev/null
@@ -0,0 +1,66 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_SOURCES_RX_DEFER_HPP)
+#define RXCPP_SOURCES_RX_DEFER_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace sources {
+
+namespace detail {
+
+template<class ObservableFactory>
+struct defer_traits
+{
+    typedef typename std::decay<ObservableFactory>::type observable_factory_type;
+    typedef decltype((*(observable_factory_type*)nullptr)()) collection_type;
+    typedef typename collection_type::value_type value_type;
+};
+
+template<class ObservableFactory>
+struct defer : public source_base<typename defer_traits<ObservableFactory>::value_type>
+{
+    typedef defer<ObservableFactory> this_type;
+    typedef defer_traits<ObservableFactory> traits;
+
+    typedef typename traits::observable_factory_type observable_factory_type;
+    typedef typename traits::collection_type collection_type;
+
+    observable_factory_type observable_factory;
+
+    defer(observable_factory_type of)
+        : observable_factory(std::move(of))
+    {
+    }
+    template<class Subscriber>
+    void on_subscribe(Subscriber o) const {
+
+        auto selectedCollection = on_exception(
+            [this](){return this->observable_factory();},
+            o);
+        if (selectedCollection.empty()) {
+            return;
+        }
+
+        selectedCollection->subscribe(o);
+    }
+};
+
+}
+
+template<class ObservableFactory>
+auto defer(ObservableFactory of)
+    ->      observable<typename detail::defer_traits<ObservableFactory>::value_type,    detail::defer<ObservableFactory>> {
+    return  observable<typename detail::defer_traits<ObservableFactory>::value_type,    detail::defer<ObservableFactory>>(
+                                                                                        detail::defer<ObservableFactory>(std::move(of)));
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/sources/rx-error.hpp b/dependencies64/RxCpp/include/rxcpp/sources/rx-error.hpp
new file mode 100644 (file)
index 0000000..5014c7c
--- /dev/null
@@ -0,0 +1,104 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_SOURCES_RX_ERROR_HPP)
+#define RXCPP_SOURCES_RX_ERROR_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace sources {
+
+namespace detail {
+
+template<class T, class Coordination>
+struct error : public source_base<T>
+{
+    typedef error<T, Coordination> this_type;
+
+    typedef typename std::decay<Coordination>::type coordination_type;
+
+    typedef typename coordination_type::coordinator_type coordinator_type;
+
+    struct error_initial_type
+    {
+        error_initial_type(std::exception_ptr e, coordination_type cn)
+            : exception(e)
+            , coordination(std::move(cn))
+        {
+        }
+        std::exception_ptr exception;
+        coordination_type coordination;
+    };
+    error_initial_type initial;
+
+    error(std::exception_ptr e, coordination_type cn)
+        : initial(e, std::move(cn))
+    {
+    }
+
+    template<class Subscriber>
+    void on_subscribe(Subscriber o) const {
+
+        // creates a worker whose lifetime is the same as this subscription
+        auto coordinator = initial.coordination.create_coordinator(o.get_subscription());
+        auto controller = coordinator.get_worker();
+        auto exception = initial.exception;
+
+        auto producer = [=](const rxsc::schedulable&){
+            auto& dest = o;
+            if (!dest.is_subscribed()) {
+                // terminate loop
+                return;
+            }
+
+            dest.on_error(exception);
+            // o is unsubscribed
+        };
+        auto selectedProducer = on_exception(
+            [&](){return coordinator.act(producer);},
+            o);
+        if (selectedProducer.empty()) {
+            return;
+        }
+        controller.schedule(selectedProducer.get());
+    }
+};
+
+struct throw_ptr_tag{};
+struct throw_instance_tag{};
+
+template <class T, class Coordination>
+auto make_error(throw_ptr_tag&&, std::exception_ptr exception, Coordination cn)
+    ->      observable<T, error<T, Coordination>> {
+    return  observable<T, error<T, Coordination>>(error<T, Coordination>(std::move(exception), std::move(cn)));
+}
+
+template <class T, class E, class Coordination>
+auto make_error(throw_instance_tag&&, E e, Coordination cn)
+    ->      observable<T, error<T, Coordination>> {
+    std::exception_ptr exception;
+    try {throw e;} catch(...) {exception = std::current_exception();}
+    return  observable<T, error<T, Coordination>>(error<T, Coordination>(std::move(exception), std::move(cn)));
+}
+
+}
+
+template<class T, class E>
+auto error(E e)
+    -> decltype(detail::make_error<T>(typename std::conditional<std::is_same<std::exception_ptr, typename std::decay<E>::type>::value, detail::throw_ptr_tag, detail::throw_instance_tag>::type(), std::move(e), identity_immediate())) {
+    return      detail::make_error<T>(typename std::conditional<std::is_same<std::exception_ptr, typename std::decay<E>::type>::value, detail::throw_ptr_tag, detail::throw_instance_tag>::type(), std::move(e), identity_immediate());
+}
+template<class T, class E, class Coordination>
+auto error(E e, Coordination cn)
+    -> decltype(detail::make_error<T>(typename std::conditional<std::is_same<std::exception_ptr, typename std::decay<E>::type>::value, detail::throw_ptr_tag, detail::throw_instance_tag>::type(), std::move(e), std::move(cn))) {
+    return      detail::make_error<T>(typename std::conditional<std::is_same<std::exception_ptr, typename std::decay<E>::type>::value, detail::throw_ptr_tag, detail::throw_instance_tag>::type(), std::move(e), std::move(cn));
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/sources/rx-interval.hpp b/dependencies64/RxCpp/include/rxcpp/sources/rx-interval.hpp
new file mode 100644 (file)
index 0000000..0bb62f5
--- /dev/null
@@ -0,0 +1,119 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_SOURCES_RX_INTERVAL_HPP)
+#define RXCPP_SOURCES_RX_INTERVAL_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace sources {
+
+namespace detail {
+
+template<class Coordination>
+struct interval : public source_base<long>
+{
+    typedef interval<Coordination> this_type;
+
+    typedef typename std::decay<Coordination>::type coordination_type;
+    typedef typename coordination_type::coordinator_type coordinator_type;
+
+    struct interval_initial_type
+    {
+        interval_initial_type(rxsc::scheduler::clock_type::time_point i, rxsc::scheduler::clock_type::duration p, coordination_type cn)
+            : initial(i)
+            , period(p)
+            , coordination(std::move(cn))
+        {
+        }
+        rxsc::scheduler::clock_type::time_point initial;
+        rxsc::scheduler::clock_type::duration period;
+        coordination_type coordination;
+    };
+    interval_initial_type initial;
+
+    interval(rxsc::scheduler::clock_type::time_point i, rxsc::scheduler::clock_type::duration p, coordination_type cn)
+        : initial(i, p, std::move(cn))
+    {
+    }
+    template<class Subscriber>
+    void on_subscribe(Subscriber o) const {
+        static_assert(is_subscriber<Subscriber>::value, "subscribe must be passed a subscriber");
+
+        typedef typename coordinator_type::template get<Subscriber>::type output_type;
+
+        // creates a worker whose lifetime is the same as this subscription
+        auto coordinator = initial.coordination.create_coordinator(o.get_subscription());
+
+        auto controller = coordinator.get_worker();
+
+        auto counter = std::make_shared<long>(0);
+
+        auto producer = [o, counter](const rxsc::schedulable&) {
+            // send next value
+            o.on_next(++(*counter));
+        };
+
+        auto selectedProducer = on_exception(
+            [&](){return coordinator.act(producer);},
+            o);
+        if (selectedProducer.empty()) {
+            return;
+        }
+
+        controller.schedule_periodically(initial.initial, initial.period, selectedProducer.get());
+    }
+};
+
+template<class TimePoint, class Coordination>
+struct defer_interval : public defer_observable<
+    rxu::all_true<
+        std::is_convertible<TimePoint, rxsc::scheduler::clock_type::time_point>::value,
+        is_coordination<Coordination>::value>,
+    void,
+    interval, Coordination>
+{
+};
+
+}
+
+template<class TimePoint>
+auto interval(TimePoint when)
+    ->  typename std::enable_if<
+                    detail::defer_interval<TimePoint, identity_one_worker>::value,
+        typename    detail::defer_interval<TimePoint, identity_one_worker>::observable_type>::type {
+    return          detail::defer_interval<TimePoint, identity_one_worker>::make(when, rxsc::scheduler::clock_type::duration::max(), identity_current_thread());
+}
+
+template<class Coordination>
+auto interval(rxsc::scheduler::clock_type::time_point when, Coordination cn)
+    ->  typename std::enable_if<
+                    detail::defer_interval<rxsc::scheduler::clock_type::time_point, Coordination>::value,
+        typename    detail::defer_interval<rxsc::scheduler::clock_type::time_point, Coordination>::observable_type>::type {
+    return          detail::defer_interval<rxsc::scheduler::clock_type::time_point, Coordination>::make(when, rxsc::scheduler::clock_type::duration::max(), std::move(cn));
+}
+
+template<class TimePoint>
+auto interval(TimePoint when, rxsc::scheduler::clock_type::duration period)
+    ->  typename std::enable_if<
+                    detail::defer_interval<TimePoint, identity_one_worker>::value,
+        typename    detail::defer_interval<TimePoint, identity_one_worker>::observable_type>::type {
+    return          detail::defer_interval<TimePoint, identity_one_worker>::make(when, period, identity_current_thread());
+}
+
+template<class Coordination>
+auto interval(rxsc::scheduler::clock_type::time_point when, rxsc::scheduler::clock_type::duration period, Coordination cn)
+    ->  typename std::enable_if<
+                    detail::defer_interval<rxsc::scheduler::clock_type::time_point, Coordination>::value,
+        typename    detail::defer_interval<rxsc::scheduler::clock_type::time_point, Coordination>::observable_type>::type {
+    return          detail::defer_interval<rxsc::scheduler::clock_type::time_point, Coordination>::make(when, period, std::move(cn));
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/sources/rx-iterate.hpp b/dependencies64/RxCpp/include/rxcpp/sources/rx-iterate.hpp
new file mode 100644 (file)
index 0000000..19aa84e
--- /dev/null
@@ -0,0 +1,178 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_SOURCES_RX_ITERATE_HPP)
+#define RXCPP_SOURCES_RX_ITERATE_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace sources {
+
+namespace detail {
+
+template<class Collection>
+struct is_iterable
+{
+    typedef typename std::decay<Collection>::type collection_type;
+
+    struct not_void {};
+    template<class CC>
+    static auto check(int) -> decltype(std::begin(*(CC*)nullptr));
+    template<class CC>
+    static not_void check(...);
+
+    static const bool value = !std::is_same<decltype(check<collection_type>(0)), not_void>::value;
+};
+
+template<class Collection>
+struct iterate_traits
+{
+    typedef typename std::decay<Collection>::type collection_type;
+    typedef decltype(std::begin(*(collection_type*)nullptr)) iterator_type;
+    typedef typename std::iterator_traits<iterator_type>::value_type value_type;
+};
+
+template<class Collection, class Coordination>
+struct iterate : public source_base<typename iterate_traits<Collection>::value_type>
+{
+    typedef iterate<Collection, Coordination> this_type;
+    typedef iterate_traits<Collection> traits;
+
+    typedef typename std::decay<Coordination>::type coordination_type;
+    typedef typename coordination_type::coordinator_type coordinator_type;
+
+    typedef typename traits::collection_type collection_type;
+    typedef typename traits::iterator_type iterator_type;
+
+    struct iterate_initial_type
+    {
+        iterate_initial_type(collection_type c, coordination_type cn)
+            : collection(std::move(c))
+            , coordination(std::move(cn))
+        {
+        }
+        collection_type collection;
+        coordination_type coordination;
+    };
+    iterate_initial_type initial;
+
+    iterate(collection_type c, coordination_type cn)
+        : initial(std::move(c), std::move(cn))
+    {
+    }
+    template<class Subscriber>
+    void on_subscribe(Subscriber o) const {
+        static_assert(is_subscriber<Subscriber>::value, "subscribe must be passed a subscriber");
+
+        typedef typename coordinator_type::template get<Subscriber>::type output_type;
+
+        struct iterate_state_type
+            : public iterate_initial_type
+        {
+            iterate_state_type(const iterate_initial_type& i, output_type o)
+                : iterate_initial_type(i)
+                , cursor(std::begin(iterate_initial_type::collection))
+                , end(std::end(iterate_initial_type::collection))
+                , out(std::move(o))
+            {
+            }
+            iterate_state_type(const iterate_state_type& o)
+                : iterate_initial_type(o)
+                , cursor(std::begin(iterate_initial_type::collection))
+                , end(std::end(iterate_initial_type::collection))
+                , out(std::move(o.out)) // since lambda capture does not yet support move
+            {
+            }
+            mutable iterator_type cursor;
+            iterator_type end;
+            mutable output_type out;
+        };
+
+        // creates a worker whose lifetime is the same as this subscription
+        auto coordinator = initial.coordination.create_coordinator(o.get_subscription());
+
+        iterate_state_type state(initial, o);
+
+        auto controller = coordinator.get_worker();
+
+        auto producer = [state](const rxsc::schedulable& self){
+            if (!state.out.is_subscribed()) {
+                // terminate loop
+                return;
+            }
+
+            if (state.cursor != state.end) {
+                // send next value
+                state.out.on_next(*state.cursor);
+                ++state.cursor;
+            }
+
+            if (state.cursor == state.end) {
+                state.out.on_completed();
+                // o is unsubscribed
+                return;
+            }
+
+            // tail recurse this same action to continue loop
+            self();
+        };
+        auto selectedProducer = on_exception(
+            [&](){return coordinator.act(producer);},
+            o);
+        if (selectedProducer.empty()) {
+            return;
+        }
+        controller.schedule(selectedProducer.get());
+
+    }
+};
+
+}
+
+template<class Collection>
+auto iterate(Collection c)
+    ->      observable<typename detail::iterate_traits<Collection>::value_type, detail::iterate<Collection, identity_one_worker>> {
+    return  observable<typename detail::iterate_traits<Collection>::value_type, detail::iterate<Collection, identity_one_worker>>(
+                                                                                detail::iterate<Collection, identity_one_worker>(std::move(c), identity_immediate()));
+}
+template<class Collection, class Coordination>
+auto iterate(Collection c, Coordination cn)
+    ->      observable<typename detail::iterate_traits<Collection>::value_type, detail::iterate<Collection, Coordination>> {
+    return  observable<typename detail::iterate_traits<Collection>::value_type, detail::iterate<Collection, Coordination>>(
+                                                                                detail::iterate<Collection, Coordination>(std::move(c), std::move(cn)));
+}
+
+template<class T>
+auto from()
+    -> decltype(iterate(std::array<T, 0>(), identity_immediate())) {
+    return      iterate(std::array<T, 0>(), identity_immediate());
+}
+template<class T, class Coordination>
+auto from(Coordination cn)
+    -> typename std::enable_if<is_coordination<Coordination>::value,
+        decltype(   iterate(std::array<T, 0>(), std::move(cn)))>::type {
+    return          iterate(std::array<T, 0>(), std::move(cn));
+}
+template<class Value0, class... ValueN>
+auto from(Value0 v0, ValueN... vn)
+    -> typename std::enable_if<!is_coordination<Value0>::value,
+        decltype(iterate(*(std::array<Value0, sizeof...(ValueN) + 1>*)nullptr, identity_immediate()))>::type {
+    std::array<Value0, sizeof...(ValueN) + 1> c = {v0, vn...};
+    return iterate(std::move(c), identity_immediate());
+}
+template<class Coordination, class Value0, class... ValueN>
+auto from(Coordination cn, Value0 v0, ValueN... vn)
+    -> typename std::enable_if<is_coordination<Coordination>::value,
+        decltype(iterate(*(std::array<Value0, sizeof...(ValueN) + 1>*)nullptr, std::move(cn)))>::type {
+    std::array<Value0, sizeof...(ValueN) + 1> c = {v0, vn...};
+    return iterate(std::move(c), std::move(cn));
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/sources/rx-never.hpp b/dependencies64/RxCpp/include/rxcpp/sources/rx-never.hpp
new file mode 100644 (file)
index 0000000..22b6c24
--- /dev/null
@@ -0,0 +1,36 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_SOURCES_RX_NEVER_HPP)
+#define RXCPP_SOURCES_RX_NEVER_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace sources {
+
+namespace detail {
+
+template<class T>
+struct never : public source_base<T>
+{
+    template<class Subscriber>
+    void on_subscribe(Subscriber o) const {
+    }
+};
+
+}
+
+template<class T>
+auto never()
+    ->      observable<T, detail::never<T>> {
+    return  observable<T, detail::never<T>>(detail::never<T>());
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/sources/rx-range.hpp b/dependencies64/RxCpp/include/rxcpp/sources/rx-range.hpp
new file mode 100644 (file)
index 0000000..ec7ddf5
--- /dev/null
@@ -0,0 +1,126 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_SOURCES_RX_RANGE_HPP)
+#define RXCPP_SOURCES_RX_RANGE_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace sources {
+
+namespace detail {
+
+template<class T, class Coordination>
+struct range : public source_base<T>
+{
+    typedef typename std::decay<Coordination>::type coordination_type;
+    typedef typename coordination_type::coordinator_type coordinator_type;
+
+    struct range_state_type
+    {
+        range_state_type(T f, T l, ptrdiff_t s, coordination_type cn)
+            : next(f)
+            , last(l)
+            , step(s)
+            , coordination(std::move(cn))
+        {
+        }
+        mutable T next;
+        T last;
+        ptrdiff_t step;
+        coordination_type coordination;
+    };
+    range_state_type initial;
+    range(T f, T l, ptrdiff_t s, coordination_type cn)
+        : initial(f, l, s, std::move(cn))
+    {
+    }
+    template<class Subscriber>
+    void on_subscribe(Subscriber o) const {
+        static_assert(is_subscriber<Subscriber>::value, "subscribe must be passed a subscriber");
+
+        typedef Subscriber output_type;
+
+        // creates a worker whose lifetime is the same as this subscription
+        auto coordinator = initial.coordination.create_coordinator(o.get_subscription());
+
+        auto controller = coordinator.get_worker();
+
+        auto state = initial;
+
+        auto producer = [=](const rxsc::schedulable& self){
+                auto& dest = o;
+                if (!dest.is_subscribed()) {
+                    // terminate loop
+                    return;
+                }
+
+                // send next value
+                dest.on_next(state.next);
+                if (!dest.is_subscribed()) {
+                    // terminate loop
+                    return;
+                }
+
+                if (std::abs(state.last - state.next) < std::abs(state.step)) {
+                    if (state.last != state.next) {
+                        dest.on_next(state.last);
+                    }
+                    dest.on_completed();
+                    // o is unsubscribed
+                    return;
+                }
+                state.next = static_cast<T>(state.step + state.next);
+
+                // tail recurse this same action to continue loop
+                self();
+            };
+
+        auto selectedProducer = on_exception(
+            [&](){return coordinator.act(producer);},
+            o);
+        if (selectedProducer.empty()) {
+            return;
+        }
+
+        controller.schedule(selectedProducer.get());
+    }
+};
+
+}
+
+template<class T>
+auto range(T first = 0, T last = std::numeric_limits<T>::max(), ptrdiff_t step = 1)
+    ->      observable<T,   detail::range<T, identity_one_worker>> {
+    return  observable<T,   detail::range<T, identity_one_worker>>(
+                            detail::range<T, identity_one_worker>(first, last, step, identity_current_thread()));
+}
+template<class T, class Coordination>
+auto range(T first, T last, ptrdiff_t step, Coordination cn)
+    ->      observable<T,   detail::range<T, Coordination>> {
+    return  observable<T,   detail::range<T, Coordination>>(
+                            detail::range<T, Coordination>(first, last, step, std::move(cn)));
+}
+template<class T, class Coordination>
+auto range(T first, T last, Coordination cn)
+    -> typename std::enable_if<is_coordination<Coordination>::value,
+            observable<T,   detail::range<T, Coordination>>>::type {
+    return  observable<T,   detail::range<T, Coordination>>(
+                            detail::range<T, Coordination>(first, last, 1, std::move(cn)));
+}
+template<class T, class Coordination>
+auto range(T first, Coordination cn)
+    -> typename std::enable_if<is_coordination<Coordination>::value,
+            observable<T,   detail::range<T, Coordination>>>::type {
+    return  observable<T,   detail::range<T, Coordination>>(
+                            detail::range<T, Coordination>(first, std::numeric_limits<T>::max(), 1, std::move(cn)));
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/sources/rx-scope.hpp b/dependencies64/RxCpp/include/rxcpp/sources/rx-scope.hpp
new file mode 100644 (file)
index 0000000..1b7a26d
--- /dev/null
@@ -0,0 +1,105 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_SOURCES_RX_SCOPE_HPP)
+#define RXCPP_SOURCES_RX_SCOPE_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace sources {
+
+namespace detail {
+
+template<class ResourceFactory, class ObservableFactory>
+struct scope_traits
+{
+    typedef typename std::decay<ResourceFactory>::type resource_factory_type;
+    typedef typename std::decay<ObservableFactory>::type observable_factory_type;
+    typedef decltype((*(resource_factory_type*)nullptr)()) resource_type;
+    typedef decltype((*(observable_factory_type*)nullptr)(resource_type())) collection_type;
+    typedef typename collection_type::value_type value_type;
+
+    static_assert(is_subscription<resource_type>::value, "ResourceFactory must return a subscription");
+};
+
+template<class ResourceFactory, class ObservableFactory>
+struct scope : public source_base<typename scope_traits<ResourceFactory, ObservableFactory>::value_type>
+{
+    typedef scope_traits<ResourceFactory, ObservableFactory> traits;
+    typedef typename traits::resource_factory_type resource_factory_type;
+    typedef typename traits::observable_factory_type observable_factory_type;
+    typedef typename traits::resource_type resource_type;
+    typedef typename traits::value_type value_type;
+
+    struct values
+    {
+        values(resource_factory_type rf, observable_factory_type of)
+            : resource_factory(std::move(rf))
+            , observable_factory(std::move(of))
+        {
+        }
+        resource_factory_type resource_factory;
+        observable_factory_type observable_factory;
+    };
+    values initial;
+
+
+    scope(resource_factory_type rf, observable_factory_type of)
+        : initial(std::move(rf), std::move(of))
+    {
+    }
+
+    template<class Subscriber>
+    void on_subscribe(Subscriber o) const {
+
+        struct state_type
+            : public std::enable_shared_from_this<state_type>
+            , public values
+        {
+            state_type(values i, Subscriber o)
+                : values(i)
+                , out(std::move(o))
+            {
+            }
+            Subscriber out;
+            rxu::detail::maybe<resource_type> resource;
+        };
+
+        auto state = std::make_shared<state_type>(state_type(initial, std::move(o)));
+
+        state->resource = on_exception(
+            [&](){return state->resource_factory(); },
+            state->out);
+        if (state->resource.empty()) {
+            return;
+        }
+        state->out.add(state->resource->get_subscription());
+        
+        auto selectedCollection = on_exception(
+            [state](){return state->observable_factory(state->resource.get()); },
+            state->out);
+        if (selectedCollection.empty()) {
+            return;
+        }
+
+        selectedCollection->subscribe(state->out);
+    }
+};
+
+}
+
+template<class ResourceFactory, class ObservableFactory>
+auto scope(ResourceFactory rf, ObservableFactory of)
+    ->      observable<typename detail::scope_traits<ResourceFactory, ObservableFactory>::value_type, detail::scope<ResourceFactory, ObservableFactory>> {
+    return  observable<typename detail::scope_traits<ResourceFactory, ObservableFactory>::value_type, detail::scope<ResourceFactory, ObservableFactory>>(
+                                                                                                      detail::scope<ResourceFactory, ObservableFactory>(std::move(rf), std::move(of)));
+}
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/subjects/rx-behavior.hpp b/dependencies64/RxCpp/include/rxcpp/subjects/rx-behavior.hpp
new file mode 100644 (file)
index 0000000..ff3becb
--- /dev/null
@@ -0,0 +1,107 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_RX_BEHAVIOR_HPP)
+#define RXCPP_RX_BEHAVIOR_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace subjects {
+
+namespace detail {
+
+template<class T>
+class behavior_observer : public detail::multicast_observer<T>
+{
+    typedef behavior_observer<T> this_type;
+    typedef detail::multicast_observer<T> base_type;
+
+    class behavior_observer_state : public std::enable_shared_from_this<behavior_observer_state>
+    {
+        mutable std::mutex lock;
+        mutable T value;
+
+    public:
+        behavior_observer_state(T first)
+            : value(first)
+        {
+        }
+
+        void reset(T v) const {
+            std::unique_lock<std::mutex> guard(lock);
+            value = std::move(v);
+        }
+        T get() const {
+            std::unique_lock<std::mutex> guard(lock);
+            return value;
+        }
+    };
+
+    std::shared_ptr<behavior_observer_state> state;
+
+public:
+    behavior_observer(T f, composite_subscription l)
+        : base_type(l)
+        , state(std::make_shared<behavior_observer_state>(std::move(f)))
+    {
+    }
+
+    subscriber<T> get_subscriber() const {
+        return make_subscriber<T>(this->get_id(), this->get_subscription(), observer<T, detail::behavior_observer<T>>(*this)).as_dynamic();
+    }
+
+    T get_value() const {
+        return state->get();
+    }
+
+    template<class V>
+    void on_next(V v) const {
+        state->reset(v);
+        base_type::on_next(std::move(v));
+    }
+};
+
+}
+
+template<class T>
+class behavior
+{
+    detail::behavior_observer<T> s;
+
+public:
+    explicit behavior(T f, composite_subscription cs = composite_subscription())
+        : s(std::move(f), cs)
+    {
+    }
+
+    bool has_observers() const {
+        return s.has_observers();
+    }
+
+    T get_value() const {
+        return s.get_value();
+    }
+
+    subscriber<T> get_subscriber() const {
+        return s.get_subscriber();
+    }
+
+    observable<T> get_observable() const {
+        auto keepAlive = s;
+        return make_observable_dynamic<T>([=](subscriber<T> o){
+            if (keepAlive.get_subscription().is_subscribed()) {
+                o.on_next(get_value());
+            }
+            keepAlive.add(s.get_subscriber(), std::move(o));
+        });
+    }
+};
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/subjects/rx-subject.hpp b/dependencies64/RxCpp/include/rxcpp/subjects/rx-subject.hpp
new file mode 100644 (file)
index 0000000..f94f8f9
--- /dev/null
@@ -0,0 +1,248 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_RX_SUBJECT_HPP)
+#define RXCPP_RX_SUBJECT_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace subjects {
+
+namespace detail {
+
+template<class T>
+class multicast_observer
+    : public observer_base<T>
+{
+    typedef observer_base<T> base;
+    typedef subscriber<T> observer_type;
+    typedef std::vector<observer_type> list_type;
+
+    struct mode
+    {
+        enum type {
+            Invalid = 0,
+            Casting,
+            Completed,
+            Errored
+        };
+    };
+
+    struct state_type
+        : public std::enable_shared_from_this<state_type>
+    {
+        explicit state_type(composite_subscription cs)
+            : generation(0)
+            , current(mode::Casting)
+            , lifetime(cs)
+        {
+        }
+        std::atomic<int> generation;
+        std::mutex lock;
+        typename mode::type current;
+        std::exception_ptr error;
+        composite_subscription lifetime;
+    };
+
+    struct completer_type
+        : public std::enable_shared_from_this<completer_type>
+    {
+        ~completer_type()
+        {
+        }
+        completer_type(std::shared_ptr<state_type> s, const std::shared_ptr<completer_type>& old, observer_type o)
+            : state(s)
+        {
+            if (old) {
+                observers.reserve(old->observers.size() + 1);
+                std::copy_if(
+                    old->observers.begin(), old->observers.end(),
+                    std::inserter(observers, observers.end()),
+                    [](const observer_type& o){
+                        return o.is_subscribed();
+                    });
+            }
+            observers.push_back(o);
+        }
+        std::shared_ptr<state_type> state;
+        list_type observers;
+    };
+
+    // this type prevents a circular ref between state and completer
+    struct binder_type
+        : public std::enable_shared_from_this<binder_type>
+    {
+        explicit binder_type(composite_subscription cs)
+            : state(std::make_shared<state_type>(cs))
+            , id(trace_id::make_next_id_subscriber())
+            , current_generation(0)
+        {
+        }
+
+        std::shared_ptr<state_type> state;
+
+        trace_id id;
+
+        // used to avoid taking lock in on_next
+        mutable int current_generation;
+        mutable std::shared_ptr<completer_type> current_completer;
+
+        // must only be accessed under state->lock
+        mutable std::shared_ptr<completer_type> completer;
+    };
+
+    std::shared_ptr<binder_type> b;
+
+public:
+    typedef subscriber<T, observer<T, detail::multicast_observer<T>>> input_subscriber_type;
+
+    explicit multicast_observer(composite_subscription cs)
+        : b(std::make_shared<binder_type>(cs))
+    {
+    }
+    trace_id get_id() const {
+        return b->id;
+    }
+    composite_subscription get_subscription() const {
+        return b->state->lifetime;
+    }
+    input_subscriber_type get_subscriber() const {
+        return make_subscriber<T>(get_id(), get_subscription(), observer<T, detail::multicast_observer<T>>(*this));
+    }
+    bool has_observers() const {
+        std::unique_lock<std::mutex> guard(b->state->lock);
+        return b->current_completer && !b->current_completer->observers.empty();
+    }
+    template<class SubscriberFrom>
+    void add(const SubscriberFrom& sf, observer_type o) const {
+        trace_activity().connect(sf, o);
+        std::unique_lock<std::mutex> guard(b->state->lock);
+        switch (b->state->current) {
+        case mode::Casting:
+            {
+                if (o.is_subscribed()) {
+                    b->completer = std::make_shared<completer_type>(b->state, b->completer, o);
+                    ++b->state->generation;
+                }
+            }
+            break;
+        case mode::Completed:
+            {
+                guard.unlock();
+                o.on_completed();
+                return;
+            }
+            break;
+        case mode::Errored:
+            {
+                auto e = b->state->error;
+                guard.unlock();
+                o.on_error(e);
+                return;
+            }
+            break;
+        default:
+            abort();
+        }
+    }
+    template<class V>
+    void on_next(V v) const {
+        if (b->current_generation != b->state->generation) {
+            std::unique_lock<std::mutex> guard(b->state->lock);
+            b->current_generation = b->state->generation;
+            b->current_completer = b->completer;
+        }
+        if (!b->current_completer || b->current_completer->observers.empty()) {
+            return;
+        }
+        for (auto& o : b->current_completer->observers) {
+            if (o.is_subscribed()) {
+                o.on_next(v);
+            }
+        }
+    }
+    void on_error(std::exception_ptr e) const {
+        std::unique_lock<std::mutex> guard(b->state->lock);
+        if (b->state->current == mode::Casting) {
+            b->state->error = e;
+            b->state->current = mode::Errored;
+            auto s = b->state->lifetime;
+            auto c = std::move(b->completer);
+            b->current_completer.reset();
+            ++b->state->generation;
+            guard.unlock();
+            if (c) {
+                for (auto& o : c->observers) {
+                    if (o.is_subscribed()) {
+                        o.on_error(e);
+                    }
+                }
+            }
+            s.unsubscribe();
+        }
+    }
+    void on_completed() const {
+        std::unique_lock<std::mutex> guard(b->state->lock);
+        if (b->state->current == mode::Casting) {
+            b->state->current = mode::Completed;
+            auto s = b->state->lifetime;
+            auto c = std::move(b->completer);
+            b->current_completer.reset();
+            ++b->state->generation;
+            guard.unlock();
+            if (c) {
+                for (auto& o : c->observers) {
+                    if (o.is_subscribed()) {
+                        o.on_completed();
+                    }
+                }
+            }
+            s.unsubscribe();
+        }
+    }
+};
+
+
+}
+
+template<class T>
+class subject
+{
+    detail::multicast_observer<T> s;
+
+public:
+    typedef subscriber<T, observer<T, detail::multicast_observer<T>>> subscriber_type;
+    typedef observable<T> observable_type;
+    subject()
+        : s(composite_subscription())
+    {
+    }
+    explicit subject(composite_subscription cs)
+        : s(cs)
+    {
+    }
+
+    bool has_observers() const {
+        return s.has_observers();
+    }
+
+    subscriber_type get_subscriber() const {
+        return s.get_subscriber();
+    }
+
+    observable<T> get_observable() const {
+        auto keepAlive = s;
+        return make_observable_dynamic<T>([=](subscriber<T> o){
+            keepAlive.add(s.get_subscriber(), std::move(o));
+        });
+    }
+};
+
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/include/rxcpp/subjects/rx-synchronize.hpp b/dependencies64/RxCpp/include/rxcpp/subjects/rx-synchronize.hpp
new file mode 100644 (file)
index 0000000..564f564
--- /dev/null
@@ -0,0 +1,263 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#pragma once
+
+#if !defined(RXCPP_RX_SYNCHRONIZE_HPP)
+#define RXCPP_RX_SYNCHRONIZE_HPP
+
+#include "../rx-includes.hpp"
+
+namespace rxcpp {
+
+namespace subjects {
+
+namespace detail {
+
+template<class T, class Coordination>
+class synchronize_observer : public detail::multicast_observer<T>
+{
+    typedef synchronize_observer<T, Coordination> this_type;
+    typedef detail::multicast_observer<T> base_type;
+
+    typedef typename std::decay<Coordination>::type coordination_type;
+    typedef typename coordination_type::coordinator_type coordinator_type;
+    typedef typename coordinator_type::template get<subscriber<T>>::type output_type;
+
+    struct synchronize_observer_state : public std::enable_shared_from_this<synchronize_observer_state>
+    {
+        typedef rxn::notification<T> notification_type;
+        typedef typename notification_type::type base_notification_type;
+        typedef std::deque<base_notification_type> queue_type;
+
+        struct mode
+        {
+            enum type {
+                Invalid = 0,
+                Processing,
+                Empty,
+                Disposed
+            };
+        };
+
+        mutable std::mutex lock;
+        mutable std::condition_variable wake;
+        mutable queue_type queue;
+        composite_subscription lifetime;
+        rxsc::worker processor;
+        mutable typename mode::type current;
+        coordinator_type coordinator;
+        output_type destination;
+
+        void ensure_processing(std::unique_lock<std::mutex>& guard) const {
+            if (!guard.owns_lock()) {
+                abort();
+            }
+            if (current == mode::Empty) {
+                current = mode::Processing;
+                auto keepAlive = this->shared_from_this();
+
+                auto drain_queue = [keepAlive, this](const rxsc::schedulable& self){
+                    try {
+                        std::unique_lock<std::mutex> guard(lock);
+                        if (!destination.is_subscribed()) {
+                            current = mode::Disposed;
+                            queue.clear();
+                            guard.unlock();
+                            lifetime.unsubscribe();
+                            return;
+                        }
+                        if (queue.empty()) {
+                            current = mode::Empty;
+                            return;
+                        }
+                        auto notification = std::move(queue.front());
+                        queue.pop_front();
+                        guard.unlock();
+                        notification->accept(destination);
+                        self();
+                    } catch(...) {
+                        destination.on_error(std::current_exception());
+                        std::unique_lock<std::mutex> guard(lock);
+                        current = mode::Empty;
+                    }
+                };
+
+                auto selectedDrain = on_exception(
+                    [&](){return coordinator.act(drain_queue);},
+                    destination);
+                if (selectedDrain.empty()) {
+                    return;
+                }
+
+                auto processor = coordinator.get_worker();
+                processor.schedule(lifetime, selectedDrain.get());
+            }
+        }
+
+        synchronize_observer_state(coordinator_type coor, composite_subscription cs, output_type scbr)
+            : lifetime(std::move(cs))
+            , current(mode::Empty)
+            , coordinator(std::move(coor))
+            , destination(std::move(scbr))
+        {
+        }
+
+        template<class V>
+        void on_next(V v) const {
+            if (lifetime.is_subscribed()) {
+                std::unique_lock<std::mutex> guard(lock);
+                queue.push_back(notification_type::on_next(std::move(v)));
+                ensure_processing(guard);
+            }
+            wake.notify_one();
+        }
+        void on_error(std::exception_ptr e) const {
+            if (lifetime.is_subscribed()) {
+                std::unique_lock<std::mutex> guard(lock);
+                queue.push_back(notification_type::on_error(e));
+                ensure_processing(guard);
+            }
+            wake.notify_one();
+        }
+        void on_completed() const {
+            if (lifetime.is_subscribed()) {
+                std::unique_lock<std::mutex> guard(lock);
+                queue.push_back(notification_type::on_completed());
+                ensure_processing(guard);
+            }
+            wake.notify_one();
+        }
+    };
+
+    std::shared_ptr<synchronize_observer_state> state;
+
+public:
+    synchronize_observer(coordination_type cn, composite_subscription dl, composite_subscription il)
+        : base_type(dl)
+    {
+        auto o = make_subscriber<T>(dl, make_observer_dynamic<T>( *static_cast<base_type*>(this) ));
+
+        // creates a worker whose lifetime is the same as the destination subscription
+        auto coordinator = cn.create_coordinator(dl);
+
+        state = std::make_shared<synchronize_observer_state>(std::move(coordinator), std::move(il), std::move(o));
+    }
+
+    subscriber<T> get_subscriber() const {
+        return make_subscriber<T>(this->get_id(), state->lifetime, observer<T, detail::synchronize_observer<T, Coordination>>(*this)).as_dynamic();
+    }
+
+    template<class V>
+    void on_next(V v) const {
+        state->on_next(std::move(v));
+    }
+    void on_error(std::exception_ptr e) const {
+        state->on_error(e);
+    }
+    void on_completed() const {
+        state->on_completed();
+    }
+};
+
+}
+
+template<class T, class Coordination>
+class synchronize
+{
+    detail::synchronize_observer<T, Coordination> s;
+
+public:
+    explicit synchronize(Coordination cn, composite_subscription cs = composite_subscription())
+        : s(std::move(cn), std::move(cs), composite_subscription())
+    {
+    }
+
+    bool has_observers() const {
+        return s.has_observers();
+    }
+
+    subscriber<T> get_subscriber() const {
+        return s.get_subscriber();
+    }
+
+    observable<T> get_observable() const {
+        auto keepAlive = s;
+        return make_observable_dynamic<T>([=](subscriber<T> o){
+            keepAlive.add(s.get_subscriber(), std::move(o));
+        });
+    }
+};
+
+}
+
+class synchronize_in_one_worker : public coordination_base
+{
+    rxsc::scheduler factory;
+
+    class input_type
+    {
+        rxsc::worker controller;
+        rxsc::scheduler factory;
+        identity_one_worker coordination;
+    public:
+        explicit input_type(rxsc::worker w)
+            : controller(w)
+            , factory(rxsc::make_same_worker(w))
+            , coordination(factory)
+        {
+        }
+        inline rxsc::worker get_worker() const {
+            return controller;
+        }
+        inline rxsc::scheduler get_scheduler() const {
+            return factory;
+        }
+        inline rxsc::scheduler::clock_type::time_point now() const {
+            return factory.now();
+        }
+        template<class Observable>
+        auto in(Observable o) const
+            -> decltype(o.publish_synchronized(coordination).ref_count()) {
+            return      o.publish_synchronized(coordination).ref_count();
+        }
+        template<class Subscriber>
+        auto out(Subscriber s) const
+            -> Subscriber {
+            return std::move(s);
+        }
+        template<class F>
+        auto act(F f) const
+            -> F {
+            return std::move(f);
+        }
+    };
+
+public:
+
+    explicit synchronize_in_one_worker(rxsc::scheduler sc) : factory(sc) {}
+
+    typedef coordinator<input_type> coordinator_type;
+
+    inline rxsc::scheduler::clock_type::time_point now() const {
+        return factory.now();
+    }
+
+    inline coordinator_type create_coordinator(composite_subscription cs = composite_subscription()) const {
+        auto w = factory.create_worker(std::move(cs));
+        return coordinator_type(input_type(std::move(w)));
+    }
+};
+
+inline synchronize_in_one_worker synchronize_event_loop() {
+    static synchronize_in_one_worker r(rxsc::make_event_loop());
+    return r;
+}
+
+inline synchronize_in_one_worker synchronize_new_thread() {
+    static synchronize_in_one_worker r(rxsc::make_new_thread());
+    return r;
+}
+
+}
+
+#endif
diff --git a/dependencies64/RxCpp/license.txt b/dependencies64/RxCpp/license.txt
new file mode 100644 (file)
index 0000000..5b47fbd
--- /dev/null
@@ -0,0 +1,15 @@
+Copyright (c) Microsoft Open Technologies, Inc.  All rights reserved.
+Microsoft Open Technologies would like to thank its contributors, a list
+of whom are at http://rx.codeplex.com/wikipage?title=Contributors.
+
+Licensed under the Apache License, Version 2.0 (the "License"); you
+may not use this file except in compliance with the License. You may
+obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+implied. See the License for the specific language governing permissions
+and limitations under the License.
\ No newline at end of file
index c488deec3936df2c5ca5025f282c09ab2b8c2fbb..5c78bccf15cecc7b800bfe93546a0a93fbd2ced6 100644 (file)
@@ -37,8 +37,8 @@
   <PropertyGroup>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)tmp\$(Configuration)\</IntDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)tmp\$(Configuration)\</IntDir>\r
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\;..\..\dependencies64\bluefish\include\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include\;..\..\dependencies64\asmlib;$(IncludePath)</IncludePath>\r
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\;..\..\dependencies64\bluefish\include\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include\;..\..\dependencies64\asmlib;$(IncludePath)</IncludePath>\r
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\dependencies64\RxCpp\include\;..\..\;..\..\dependencies64\bluefish\include\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include\;..\..\dependencies64\asmlib;$(IncludePath)</IncludePath>\r
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\dependencies64\RxCpp\include\;..\..\;..\..\dependencies64\bluefish\include\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include\;..\..\dependencies64\asmlib;$(IncludePath)</IncludePath>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)bin\$(Configuration)\</OutDir>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)bin\$(Configuration)\</OutDir>\r
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectName)</TargetName>\r
index 9789a999e96946ca37c11d56032cce99255a9ad6..bb42ef29f640ff2b13d3ee5d071b1c2c9799ec24 100644 (file)
@@ -45,8 +45,8 @@
   <PropertyGroup>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)tmp\$(Configuration)\</IntDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)tmp\$(Configuration)\</IntDir>\r
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\;..\..\dependencies64\bluefish\include\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include\;..\..\dependencies64\ffmpeg\include\;$(IncludePath)</IncludePath>\r
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\;..\..\dependencies64\bluefish\include\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include\;..\..\dependencies64\ffmpeg\include\;$(IncludePath)</IncludePath>\r
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\dependencies64\RxCpp\include\;..\..\;..\..\dependencies64\bluefish\include\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include\;..\..\dependencies64\ffmpeg\include\;$(IncludePath)</IncludePath>\r
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\dependencies64\RxCpp\include\;..\..\;..\..\dependencies64\bluefish\include\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include\;..\..\dependencies64\ffmpeg\include\;$(IncludePath)</IncludePath>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)bin\$(Configuration)\</OutDir>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)bin\$(Configuration)\</OutDir>\r
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectName)</TargetName>\r
index 70ac4abd98052dfafa2af31464c6000f42ca0458..c8b1d5f771ebfb3bd820fb99d0d9e066e89854b4 100644 (file)
@@ -37,8 +37,8 @@
   <PropertyGroup>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)tmp\$(Configuration)\</IntDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)tmp\$(Configuration)\</IntDir>\r
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\;..\..\dependencies64\bluefish\include\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include\;..\..\dependencies64\ffmpeg\include\;..\..\dependencies64\asmlib\;$(IncludePath)</IncludePath>\r
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\;..\..\dependencies64\bluefish\include\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include\;..\..\dependencies64\ffmpeg\include\;..\..\dependencies64\asmlib\;$(IncludePath)</IncludePath>\r
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\dependencies64\RxCpp\include\;..\..\;..\..\dependencies64\bluefish\include\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include\;..\..\dependencies64\ffmpeg\include\;..\..\dependencies64\asmlib\;$(IncludePath)</IncludePath>\r
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\dependencies64\RxCpp\include\;..\..\;..\..\dependencies64\bluefish\include\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include\;..\..\dependencies64\ffmpeg\include\;..\..\dependencies64\asmlib\;$(IncludePath)</IncludePath>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)bin\$(Configuration)\</OutDir>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)bin\$(Configuration)\</OutDir>\r
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectName)</TargetName>\r
index f316fb1103f3c667c596ed445901666d518653d1..2041beaef063307af5e0421b911d58578621f508 100644 (file)
@@ -48,8 +48,6 @@
 #include <common/assert.h>
 #include <boost/timer.hpp>
 #include <boost/filesystem.hpp>
-#include <boost/range/algorithm/find_if.hpp>
-#include <boost/range/algorithm/find.hpp>
 #include <boost/property_tree/ptree.hpp>
 #include <boost/regex.hpp>
 #include <boost/thread/future.hpp>
index 2df066439f6edb48f02c5d04b19b7dcc99ed9990..dac2eef3dfbe4438524af646176a3afa7fb50ab3 100644 (file)
@@ -28,8 +28,6 @@
 #include <common/assert.h>
 #include <common/except.h>
 
-#include <boost/range/iterator_range.hpp>
-#include <boost/range/adaptors.hpp>
 #include <boost/algorithm/string.hpp>
 #include <boost/thread.hpp>
 #include <boost/format.hpp>
index 855d6c8ec709ff01c2916beee737144992a9e0d8..dd6c5cf4c4b613209bc63001c7d020652ac73a95 100644 (file)
@@ -38,7 +38,6 @@
 #include <tbb/atomic.h>
 #include <tbb/recursive_mutex.h>
 
-#include <boost/range/algorithm.hpp>
 #include <boost/thread/condition_variable.hpp>
 #include <boost/thread/mutex.hpp>
 #include <boost/thread/thread.hpp>
index 215dc906dcbb338f094a1a6092ce85ce50426295..bc09717392efdadfe7aa750816413aedc5718620 100644 (file)
@@ -395,7 +395,7 @@ double read_fps(AVFormatContext& context, double fail_value)
 
                double closest_fps = 0.0;
 
-               for (auto video_mode : iterate_enum<core::video_format>())
+               for (auto video_mode : enum_constants<core::video_format>())
                {
                        auto format = core::video_format_desc(core::video_format(video_mode));
 
index 89fb0c24c18570cce24a8207d0dc8dfe3d5f5b99..db83a5633d7bfac7e9873dee0755b16aa674ef29 100644 (file)
@@ -32,7 +32,6 @@
 #include <core/frame/frame_transform.h>
 #include <core/frame/frame_factory.h>
 
-#include <boost/range/algorithm_ext/push_back.hpp>
 #include <boost/filesystem.hpp>
 
 #include <queue>
index f484252b9fcefd581fd3364cf86b615cff8fe416..4401bb18542490c9f3dc6d9716b4a6ae0c07f080 100644 (file)
@@ -37,8 +37,8 @@
   <PropertyGroup>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)tmp\$(Configuration)\</IntDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)tmp\$(Configuration)\</IntDir>\r
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\;..\..\dependencies64\bluefish\include\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include\;..\..\dependencies64\freeimage\include\;..\..\dependencies64\asmlib\;$(IncludePath)</IncludePath>\r
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\;..\..\dependencies64\bluefish\include\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include\;..\..\dependencies64\freeimage\include\;..\..\dependencies64\asmlib\;$(IncludePath)</IncludePath>\r
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\dependencies64\RxCpp\include\;..\..\;..\..\dependencies64\bluefish\include\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include\;..\..\dependencies64\freeimage\include\;..\..\dependencies64\asmlib\;$(IncludePath)</IncludePath>\r
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\dependencies64\RxCpp\include\;..\..\;..\..\dependencies64\bluefish\include\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include\;..\..\dependencies64\freeimage\include\;..\..\dependencies64\asmlib\;$(IncludePath)</IncludePath>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)bin\$(Configuration)\</OutDir>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)bin\$(Configuration)\</OutDir>\r
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectName)</TargetName>\r
index d74ed440fbb4baf45b7c5875dabb47b1748b25b4..3502d648a5577338a600b7070c0f84ff9710b5c1 100644 (file)
@@ -37,8 +37,8 @@
   <PropertyGroup>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)tmp\$(Configuration)\</IntDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)tmp\$(Configuration)\</IntDir>\r
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\;..\..\dependencies64\bluefish\include\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include\;..\..\dependencies64\freeimage\include\;..\..\dependencies64\asmlib\;$(IncludePath)</IncludePath>\r
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\;..\..\dependencies64\bluefish\include\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include\;..\..\dependencies64\freeimage\include\;..\..\dependencies64\asmlib\;$(IncludePath)</IncludePath>\r
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\dependencies64\RxCpp\include\;..\..\;..\..\dependencies64\bluefish\include\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include\;..\..\dependencies64\freeimage\include\;..\..\dependencies64\asmlib\;$(IncludePath)</IncludePath>\r
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\dependencies64\RxCpp\include\;..\..\;..\..\dependencies64\bluefish\include\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include\;..\..\dependencies64\freeimage\include\;..\..\dependencies64\asmlib\;$(IncludePath)</IncludePath>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)bin\$(Configuration)\</OutDir>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)bin\$(Configuration)\</OutDir>\r
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectName)</TargetName>\r
index 57c6a44129a6d8be54b13bdebfc1ff93cd4fc4eb..8b57526335171c524508b4543c9366f93fd8f9e9 100644 (file)
@@ -37,8 +37,8 @@
   <PropertyGroup>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)tmp\$(Configuration)\</IntDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)tmp\$(Configuration)\</IntDir>\r
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\;..\..\dependencies64\bluefish\include\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include\;..\..\dependencies64\sfml\include\;..\..\dependencies64\openal\include;$(IncludePath)</IncludePath>\r
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\;..\..\dependencies64\bluefish\include\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include\;..\..\dependencies64\sfml\include\;..\..\dependencies64\openal\include;$(IncludePath)</IncludePath>\r
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\dependencies64\RxCpp\include\;..\..\;..\..\dependencies64\bluefish\include\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include\;..\..\dependencies64\sfml\include\;..\..\dependencies64\openal\include;$(IncludePath)</IncludePath>\r
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\dependencies64\RxCpp\include\;..\..\;..\..\dependencies64\bluefish\include\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include\;..\..\dependencies64\sfml\include\;..\..\dependencies64\openal\include;$(IncludePath)</IncludePath>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)bin\$(Configuration)\</OutDir>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)bin\$(Configuration)\</OutDir>\r
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectName)</TargetName>\r
index 295cfca26d9154864970f7ff74d0f95fd068f303..e9a77f7c8ec5cf75437a86c6d3b7656c42a44675 100644 (file)
   </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <IncludePath>..\..\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include;$(IncludePath)</IncludePath>
+    <IncludePath>..\..\dependencies64\RxCpp\include\;..\..\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include;$(IncludePath)</IncludePath>
     <OutDir>$(ProjectDir)bin\$(Configuration)\</OutDir>
     <IntDir>$(ProjectDir)tmp\$(Configuration)\</IntDir>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <OutDir>$(ProjectDir)bin\$(Configuration)\</OutDir>
     <IntDir>$(ProjectDir)tmp\$(Configuration)\</IntDir>
-    <IncludePath>..\..\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include;$(IncludePath)</IncludePath>
+    <IncludePath>..\..\dependencies64\RxCpp\include\;..\..\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include;$(IncludePath)</IncludePath>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
index 30147a4608730d303f010d94cb47e57187889e95..a53ab2203feede259f4761fe111b07a50450e0ef 100644 (file)
@@ -35,6 +35,7 @@
 #include <common/diagnostics/graph.h>
 #include <common/log.h>
 #include <common/reactive.h>
+#include <common/linq.h>
 
 #include <asmlib.h>
 
@@ -42,9 +43,6 @@
 
 #include <boost/property_tree/ptree.hpp>
 #include <boost/optional.hpp>
-#include <boost/range/algorithm_ext/push_back.hpp>
-#include <boost/range/numeric.hpp>
-#include <boost/range/adaptor/map.hpp>
 
 #include <queue>
 
@@ -89,7 +87,9 @@ public:
                        return core::draw_frame::late();                
                }
 
-               return boost::accumulate(frames | boost::adaptors::map_values, core::draw_frame::empty(), core::draw_frame::over);
+               return cpplinq::from(frames)
+                       .select(values())
+                       .aggregate(core::draw_frame::empty(), core::draw_frame::over);
        }
 
        core::constraints& pixel_constraints() override
index 9fc3c24f5ea05af47400a9ba47875548dc65bc4b..cd48a84e967b965064db9e5d7ac562e25f0334fb 100644 (file)
@@ -45,8 +45,8 @@
   <PropertyGroup>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)tmp\$(Configuration)\</IntDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)tmp\$(Configuration)\</IntDir>\r
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\;..\..\dependencies64\bluefish\include\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include\;..\..\dependencies64\glew\include\;..\..\dependencies64\sfml\include\;..\..\dependencies64\ffmpeg\include\;..\..\dependencies64\asmlib\;$(IncludePath)</IncludePath>\r
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\;..\..\dependencies64\bluefish\include\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include\;..\..\dependencies64\glew\include\;..\..\dependencies64\sfml\include\;..\..\dependencies64\ffmpeg\include\;..\..\dependencies64\asmlib\;$(IncludePath)</IncludePath>\r
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\dependencies64\RxCpp\include\;..\..\;..\..\dependencies64\bluefish\include\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include\;..\..\dependencies64\glew\include\;..\..\dependencies64\sfml\include\;..\..\dependencies64\ffmpeg\include\;..\..\dependencies64\asmlib\;$(IncludePath)</IncludePath>\r
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\dependencies64\RxCpp\include\;..\..\;..\..\dependencies64\bluefish\include\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include\;..\..\dependencies64\glew\include\;..\..\dependencies64\sfml\include\;..\..\dependencies64\ffmpeg\include\;..\..\dependencies64\asmlib\;$(IncludePath)</IncludePath>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)bin\$(Configuration)\</OutDir>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)bin\$(Configuration)\</OutDir>\r
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectName)</TargetName>\r
index 467fada3401513824f66f937365ad55c6a568fa9..d0c0ba2ca8de11b45bffca322f25f9b8a79ea611 100644 (file)
@@ -45,8 +45,8 @@
   <PropertyGroup>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)tmp\$(Configuration)\</IntDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)tmp\$(Configuration)\</IntDir>\r
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\;..\..\dependencies64\bluefish\include\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include\;..\..\dependencies64\glew\include\;..\..\dependencies64\sfml\include\;..\..\dependencies64\ffmpeg\include\;..\..\dependencies64\asmlib\;$(IncludePath)</IncludePath>\r
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\;..\..\dependencies64\bluefish\include\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include\;..\..\dependencies64\glew\include\;..\..\dependencies64\sfml\include\;..\..\dependencies64\ffmpeg\include\;..\..\dependencies64\asmlib\;$(IncludePath)</IncludePath>\r
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\dependencies64\RxCpp\include\;..\..\;..\..\dependencies64\bluefish\include\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include\;..\..\dependencies64\glew\include\;..\..\dependencies64\sfml\include\;..\..\dependencies64\ffmpeg\include\;..\..\dependencies64\asmlib\;$(IncludePath)</IncludePath>\r
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\dependencies64\RxCpp\include\;..\..\;..\..\dependencies64\bluefish\include\;..\..\dependencies64\boost\;..\..\dependencies64\tbb\include\;..\..\dependencies64\glew\include\;..\..\dependencies64\sfml\include\;..\..\dependencies64\ffmpeg\include\;..\..\dependencies64\asmlib\;$(IncludePath)</IncludePath>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)bin\$(Configuration)\</OutDir>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)bin\$(Configuration)\</OutDir>\r
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectName)</TargetName>\r
index 6e2f871bcb239b922ed59b6fafe0b98719818da3..57e4704c03ea23f9b16c119465e2fa72c313c48e 100644 (file)
   <ImportGroup Label="ExtensionSettings">\r
   </ImportGroup>\r
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
-    <IncludePath>..\;..\dependencies64\tbb\include;..\dependencies64\boost\;$(IncludePath)</IncludePath>\r
+    <IncludePath>..\dependencies64\RxCpp\include\;..\;..\dependencies64\tbb\include;..\dependencies64\boost\;$(IncludePath)</IncludePath>\r
     <OutDir>$(ProjectDir)bin\$(Configuration)\</OutDir>\r
     <IntDir>$(ProjectDir)tmp\$(Configuration)\</IntDir>\r
   </PropertyGroup>\r
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
-    <IncludePath>..\;..\dependencies64\tbb\include;..\dependencies64\boost\;$(IncludePath)</IncludePath>\r
+    <IncludePath>..\dependencies64\RxCpp\include\;..\;..\dependencies64\tbb\include;..\dependencies64\boost\;$(IncludePath)</IncludePath>\r
     <OutDir>$(ProjectDir)bin\$(Configuration)\</OutDir>\r
     <IntDir>$(ProjectDir)tmp\$(Configuration)\</IntDir>\r
   </PropertyGroup>\r
index a8fdc277f58c6a623d51ada03b1b4930b93b7ed5..3ca2b782f8169424b4b13c8b8a37bad07ffbac3f 100644 (file)
@@ -9,7 +9,8 @@
       <Configuration>Release</Configuration>\r
       <Platform>x64</Platform>\r
     </ProjectConfiguration>\r
-    <ProjectConfiguration Include="Release|Win32"> <!-- Only to enable profiling. See http://stackoverflow.com/questions/13934895/profiling-with-cmake-c-and-visual-studio-2012 -->\r
+    <ProjectConfiguration Include="Release|Win32">\r
+      <!-- Only to enable profiling. See http://stackoverflow.com/questions/13934895/profiling-with-cmake-c-and-visual-studio-2012 -->\r
       <Configuration>Release</Configuration>\r
       <Platform>Win32</Platform>\r
     </ProjectConfiguration>\r
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)tmp\$(Configuration)\</IntDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)tmp\$(Configuration)\</IntDir>\r
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\dependencies64\boost\;..\dependencies64\ffmpeg\include\;..\dependencies64\glew\include;..\dependencies64\sfml\include\;..\dependencies64\tbb\include\;$(IncludePath)</IncludePath>\r
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\dependencies64\boost\;..\dependencies64\ffmpeg\include\;..\dependencies64\glew\include;..\dependencies64\sfml\include\;..\dependencies64\tbb\include\;$(IncludePath)</IncludePath>\r
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\dependencies64\RxCpp\include\;..\dependencies64\boost\;..\dependencies64\ffmpeg\include\;..\dependencies64\glew\include;..\dependencies64\sfml\include\;..\dependencies64\tbb\include\;$(IncludePath)</IncludePath>\r
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\dependencies64\RxCpp\include\;..\dependencies64\boost\;..\dependencies64\ffmpeg\include\;..\dependencies64\glew\include;..\dependencies64\sfml\include\;..\dependencies64\tbb\include\;$(IncludePath)</IncludePath>\r
     <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\dependencies64\boost\stage\lib;..\dependencies64\ffmpeg\lib\;..\dependencies64\glew\lib;..\dependencies64\freeimage\lib\;..\dependencies64\sfml\extlibs\lib;..\dependencies64\sfml\lib\;..\dependencies64\tbb\lib\;..\dependencies64\openal\lib\;..\dependencies64\freetype\objs\win32\vc2010;..\dependencies64\asmlib\;..\dependencies64\zlib\lib\;$(LibraryPath)</LibraryPath>\r
     <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\dependencies64\boost\stage\lib;..\dependencies64\ffmpeg\lib\;..\dependencies64\glew\lib;..\dependencies64\sfml\lib\;..\dependencies64\tbb\lib\;..\dependencies64\freeimage\lib\;..\dependencies64\openal\lib\;..\dependencies64\asmlib\;..\dependencies64\sfml\extlibs\lib;..\dependencies64\freetype\objs\win32\vc2010;..\dependencies64\zlib\lib\;$(LibraryPath)</LibraryPath>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)bin\$(Configuration)\</OutDir>\r
index c634525765b03eb6cf3475051654b459ffa7fb7b..283c9803a68eddb6330f757c6dab74473a8df4a8 100644 (file)
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <LinkIncremental>true</LinkIncremental>
     <LibraryPath>..\..\dependencies64\boost\stage\lib;..\..\dependencies64\tbb\lib;$(LibraryPath)</LibraryPath>
-    <IncludePath>..\..\dependencies64\boost;..\..\;$(IncludePath)</IncludePath>
+    <IncludePath>..\dependencies64\RxCpp\include\;..\..\dependencies64\boost;..\..\;$(IncludePath)</IncludePath>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <LinkIncremental>false</LinkIncremental>
-    <IncludePath>..\..\dependencies64\boost;..\..\;$(IncludePath)</IncludePath>
+    <IncludePath>..\dependencies64\RxCpp\include\;..\..\dependencies64\boost;..\..\;$(IncludePath)</IncludePath>
     <LibraryPath>..\..\dependencies64\boost\stage\lib;..\..\dependencies64\tbb\lib;$(LibraryPath)</LibraryPath>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
index aa23fb30406585193df3a92e4d8b673daca1271a..6a9ac62bfa26f146bb5e9cd710490d8791928d89 100644 (file)
@@ -97,8 +97,8 @@
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)tmp\unit-test\$(Configuration)\</IntDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)tmp\unit-test\$(Configuration)\</IntDir>
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\dependencies64\boost\;..\dependencies64\ffmpeg\include\;..\dependencies64\glew\include;..\dependencies64\sfml\include\;..\dependencies64\tbb\include\;..\;..\dependencies64\gtest\include;$(IncludePath)</IncludePath>
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\dependencies64\boost\;..\dependencies64\ffmpeg\include\;..\dependencies64\glew\include;..\dependencies64\sfml\include\;..\dependencies64\tbb\include\;..\;..\dependencies64\gtest\include;$(IncludePath)</IncludePath>
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\dependencies64\RxCpp\include\;..\dependencies64\boost\;..\dependencies64\ffmpeg\include\;..\dependencies64\glew\include;..\dependencies64\sfml\include\;..\dependencies64\tbb\include\;..\;..\dependencies64\gtest\include;$(IncludePath)</IncludePath>
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\dependencies64\RxCpp\include\;..\dependencies64\boost\;..\dependencies64\ffmpeg\include\;..\dependencies64\glew\include;..\dependencies64\sfml\include\;..\dependencies64\tbb\include\;..\;..\dependencies64\gtest\include;$(IncludePath)</IncludePath>
     <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\dependencies64\boost\stage\lib;..\dependencies64\ffmpeg\lib\;..\dependencies64\glew\lib;..\dependencies64\sfml\extlibs\lib;..\dependencies64\sfml\lib\;..\dependencies64\tbb\lib\;..\dependencies64\freeimage\lib\;..\dependencies64\openal\lib\;..\dependencies64\asmlib\;..\dependencies64\gtest\lib;..\dependencies64\freetype\objs\win32\vc2010;..\dependencies64\zlib\lib\;$(LibraryPath)</LibraryPath>
     <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\dependencies64\boost\stage\lib;..\dependencies64\ffmpeg\lib\;..\dependencies64\glew\lib;..\dependencies64\sfml\extlibs\lib;..\dependencies64\sfml\lib\;..\dependencies64\tbb\lib\;..\dependencies64\freeimage\lib\;..\dependencies64\openal\lib\;..\dependencies64\asmlib\;..\dependencies64\gtest\lib;..\dependencies64\freetype\objs\win32\vc2010;..\dependencies64\zlib\lib\;$(LibraryPath)</LibraryPath>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)bin\unit-test\$(Configuration)\</OutDir>