├── .editorconfig ├── .gitattributes ├── .github └── workflows │ └── rxcpp-ci.yml ├── .gitignore ├── .gitmodules ├── .travis.yml ├── AUTHORS.txt ├── CMakeLists.txt ├── DeveloperManual.md ├── Ix └── CPP │ ├── .gitignore │ ├── license.txt │ ├── projects │ ├── CppLinq.vpj │ ├── CppLinq.vpw │ └── Unittest.CppLinq.vpj │ ├── samples │ └── SampleCppLinq │ │ ├── SampleCppLinq.cpp │ │ ├── SampleCppLinq.sln │ │ ├── SampleCppLinq.vcxproj │ │ ├── SampleCppLinq.vcxproj.filters │ │ └── data.txt │ ├── src │ ├── IxCpp.vcxproj │ ├── IxCpp.vcxproj.filters │ └── cpplinq │ │ ├── linq.hpp │ │ ├── linq_cursor.hpp │ │ ├── linq_groupby.hpp │ │ ├── linq_iterators.hpp │ │ ├── linq_last.hpp │ │ ├── linq_select.hpp │ │ ├── linq_selectmany.hpp │ │ ├── linq_skip.hpp │ │ ├── linq_take.hpp │ │ ├── linq_where.hpp │ │ └── util.hpp │ └── unittest │ ├── makefile │ ├── testbench.cpp │ └── testbench.hpp ├── README.md ├── Readme.html ├── Rx └── v2 │ ├── examples │ ├── awaitable │ │ ├── CMakeLists.txt │ │ └── main.cpp │ ├── cep │ │ ├── CMakeLists.txt │ │ └── main.cpp │ ├── doxygen │ │ ├── CMakeLists.txt │ │ ├── all.cpp │ │ ├── amb.cpp │ │ ├── any.cpp │ │ ├── as_dynamic.cpp │ │ ├── blocking_observable.cpp │ │ ├── buffer.cpp │ │ ├── combine_latest.cpp │ │ ├── composite_exception.cpp │ │ ├── concat.cpp │ │ ├── concat_map.cpp │ │ ├── contains.cpp │ │ ├── create.cpp │ │ ├── debounce.cpp │ │ ├── default_if_empty.cpp │ │ ├── defer.cpp │ │ ├── delay.cpp │ │ ├── distinct.cpp │ │ ├── distinct_until_changed.cpp │ │ ├── element_at.cpp │ │ ├── empty.cpp │ │ ├── error.cpp │ │ ├── exists.cpp │ │ ├── filter.cpp │ │ ├── finally.cpp │ │ ├── flat_map.cpp │ │ ├── from.cpp │ │ ├── group_by.cpp │ │ ├── ignore_elements.cpp │ │ ├── interval.cpp │ │ ├── is_empty.cpp │ │ ├── iterate.cpp │ │ ├── just.cpp │ │ ├── main.cpp │ │ ├── main.hpp │ │ ├── map.cpp │ │ ├── math.cpp │ │ ├── merge.cpp │ │ ├── merge_delay_error.cpp │ │ ├── never.cpp │ │ ├── observe_on.cpp │ │ ├── on_error_resume_next.cpp │ │ ├── pairwise.cpp │ │ ├── publish.cpp │ │ ├── range.cpp │ │ ├── reduce.cpp │ │ ├── ref_count.cpp │ │ ├── repeat.cpp │ │ ├── replay.cpp │ │ ├── retry.cpp │ │ ├── sample.cpp │ │ ├── scan.cpp │ │ ├── scope.cpp │ │ ├── sequence_equal.cpp │ │ ├── skip.cpp │ │ ├── skip_last.cpp │ │ ├── skip_until.cpp │ │ ├── skip_while.cpp │ │ ├── start_with.cpp │ │ ├── subscribe.cpp │ │ ├── subscribe_on.cpp │ │ ├── switch_if_empty.cpp │ │ ├── switch_on_next.cpp │ │ ├── take.cpp │ │ ├── take_last.cpp │ │ ├── take_until.cpp │ │ ├── take_while.cpp │ │ ├── tap.cpp │ │ ├── time_interval.cpp │ │ ├── timeout.cpp │ │ ├── timer.cpp │ │ ├── timestamp.cpp │ │ ├── window.cpp │ │ ├── with_latest_from.cpp │ │ └── zip.cpp │ ├── linesfrombytes │ │ ├── CMakeLists.txt │ │ └── main.cpp │ ├── println │ │ ├── CMakeLists.txt │ │ └── main.cpp │ ├── pythagorian │ │ ├── CMakeLists.txt │ │ └── main.cpp │ ├── stop │ │ ├── CMakeLists.txt │ │ └── main.cpp │ ├── tests │ │ ├── CMakeLists.txt │ │ ├── main.cpp │ │ └── take.cpp │ └── win_text │ │ ├── CMakeLists.txt │ │ ├── main.cpp │ │ ├── rx_windows_user.h │ │ ├── unwinder.h │ │ └── windows_user.h │ ├── license.txt │ ├── src │ └── rxcpp │ │ ├── operators │ │ ├── rx-all.hpp │ │ ├── rx-amb.hpp │ │ ├── rx-any.hpp │ │ ├── rx-buffer_count.hpp │ │ ├── rx-buffer_time.hpp │ │ ├── rx-buffer_time_count.hpp │ │ ├── rx-combine_latest.hpp │ │ ├── rx-concat.hpp │ │ ├── rx-concat_map.hpp │ │ ├── rx-connect_forever.hpp │ │ ├── rx-debounce.hpp │ │ ├── rx-delay.hpp │ │ ├── rx-distinct.hpp │ │ ├── rx-distinct_until_changed.hpp │ │ ├── rx-element_at.hpp │ │ ├── rx-filter.hpp │ │ ├── rx-finally.hpp │ │ ├── rx-flat_map.hpp │ │ ├── rx-group_by.hpp │ │ ├── rx-ignore_elements.hpp │ │ ├── rx-lift.hpp │ │ ├── rx-map.hpp │ │ ├── rx-merge.hpp │ │ ├── rx-merge_delay_error.hpp │ │ ├── rx-multicast.hpp │ │ ├── rx-observe_on.hpp │ │ ├── rx-on_error_resume_next.hpp │ │ ├── rx-pairwise.hpp │ │ ├── rx-publish.hpp │ │ ├── rx-reduce.hpp │ │ ├── rx-ref_count.hpp │ │ ├── rx-repeat.hpp │ │ ├── rx-replay.hpp │ │ ├── rx-retry-repeat-common.hpp │ │ ├── rx-retry.hpp │ │ ├── rx-sample_time.hpp │ │ ├── rx-scan.hpp │ │ ├── rx-sequence_equal.hpp │ │ ├── rx-skip.hpp │ │ ├── rx-skip_last.hpp │ │ ├── rx-skip_until.hpp │ │ ├── rx-skip_while.hpp │ │ ├── rx-start_with.hpp │ │ ├── rx-subscribe.hpp │ │ ├── rx-subscribe_on.hpp │ │ ├── rx-switch_if_empty.hpp │ │ ├── rx-switch_on_next.hpp │ │ ├── rx-take.hpp │ │ ├── rx-take_last.hpp │ │ ├── rx-take_until.hpp │ │ ├── rx-take_while.hpp │ │ ├── rx-tap.hpp │ │ ├── rx-time_interval.hpp │ │ ├── rx-timeout.hpp │ │ ├── rx-timestamp.hpp │ │ ├── rx-window.hpp │ │ ├── rx-window_time.hpp │ │ ├── rx-window_time_count.hpp │ │ ├── rx-window_toggle.hpp │ │ ├── rx-with_latest_from.hpp │ │ └── rx-zip.hpp │ │ ├── rx-composite_exception.hpp │ │ ├── rx-connectable_observable.hpp │ │ ├── rx-coordination.hpp │ │ ├── rx-coroutine.hpp │ │ ├── rx-grouped_observable.hpp │ │ ├── rx-includes.hpp │ │ ├── rx-lite.hpp │ │ ├── rx-notification.hpp │ │ ├── rx-observable-fwd.hpp │ │ ├── rx-observable.hpp │ │ ├── rx-observer.hpp │ │ ├── rx-operators.hpp │ │ ├── rx-predef.hpp │ │ ├── rx-scheduler.hpp │ │ ├── rx-sources.hpp │ │ ├── rx-subjects.hpp │ │ ├── rx-subscriber.hpp │ │ ├── rx-subscription.hpp │ │ ├── rx-test.hpp │ │ ├── rx-trace.hpp │ │ ├── rx-util.hpp │ │ ├── rx.hpp │ │ ├── schedulers │ │ ├── rx-currentthread.hpp │ │ ├── rx-eventloop.hpp │ │ ├── rx-immediate.hpp │ │ ├── rx-newthread.hpp │ │ ├── rx-runloop.hpp │ │ ├── rx-sameworker.hpp │ │ ├── rx-test.hpp │ │ └── rx-virtualtime.hpp │ │ ├── sources │ │ ├── rx-create.hpp │ │ ├── rx-defer.hpp │ │ ├── rx-empty.hpp │ │ ├── rx-error.hpp │ │ ├── rx-interval.hpp │ │ ├── rx-iterate.hpp │ │ ├── rx-never.hpp │ │ ├── rx-range.hpp │ │ ├── rx-scope.hpp │ │ └── rx-timer.hpp │ │ └── subjects │ │ ├── rx-behavior.hpp │ │ ├── rx-replaysubject.hpp │ │ ├── rx-subject.hpp │ │ └── rx-synchronize.hpp │ └── test │ ├── CMakeLists.txt │ ├── copy_verifier.h │ ├── operators │ ├── all.cpp │ ├── amb.cpp │ ├── amb_variadic.cpp │ ├── any.cpp │ ├── buffer.cpp │ ├── combine_latest.cpp │ ├── concat.cpp │ ├── concat_map.cpp │ ├── contains.cpp │ ├── debounce.cpp │ ├── default_if_empty.cpp │ ├── delay.cpp │ ├── distinct.cpp │ ├── distinct_until_changed.cpp │ ├── element_at.cpp │ ├── exists.cpp │ ├── filter.cpp │ ├── finally.cpp │ ├── flat_map.cpp │ ├── group_by.cpp │ ├── ignore_elements.cpp │ ├── is_empty.cpp │ ├── lift.cpp │ ├── map.cpp │ ├── merge.cpp │ ├── merge_delay_error.cpp │ ├── observe_on.cpp │ ├── on_error_resume_next.cpp │ ├── pairwise.cpp │ ├── publish.cpp │ ├── reduce.cpp │ ├── repeat.cpp │ ├── replay.cpp │ ├── retry.cpp │ ├── sample.cpp │ ├── scan.cpp │ ├── sequence_equal.cpp │ ├── skip.cpp │ ├── skip_last.cpp │ ├── skip_until.cpp │ ├── skip_while.cpp │ ├── start_with.cpp │ ├── subscribe_on.cpp │ ├── switch_if_empty.cpp │ ├── switch_on_next.cpp │ ├── take.cpp │ ├── take_last.cpp │ ├── take_until.cpp │ ├── take_while.cpp │ ├── tap.cpp │ ├── time_interval.cpp │ ├── timeout.cpp │ ├── timestamp.cpp │ ├── window.cpp │ ├── window_toggle.cpp │ ├── with_latest_from.cpp │ └── zip.cpp │ ├── sources │ ├── create.cpp │ ├── defer.cpp │ ├── empty.cpp │ ├── interval.cpp │ ├── iterate.cpp │ ├── scope.cpp │ └── timer.cpp │ ├── subjects │ └── subject.cpp │ ├── subscriptions │ ├── coroutine.cpp │ ├── observer.cpp │ └── subscription.cpp │ ├── test.cpp │ └── test.h ├── appveyor.yml ├── license.md └── projects ├── CMake ├── CMakeLists.txt └── shared.cmake ├── doxygen ├── CMakeLists.txt ├── doxygen.conf.in ├── footer.html └── mainpage.dox ├── nuget ├── release.txt └── rxcpp.autoconfig └── scripts ├── install_libcxx.sh ├── travis-doxygen.sh └── travis-install.sh /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 4 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Visual Studio 3 | ################# 4 | 5 | ## Ignore Visual Studio temporary files, build results, and 6 | ## files generated by popular Visual Studio add-ons. 7 | 8 | # User-specific files 9 | *.suo 10 | *.user 11 | *.sln.docstates 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Rr]elease/ 16 | *_i.c 17 | *_p.c 18 | *.ilk 19 | *.meta 20 | *.obj 21 | *.pch 22 | *.pdb 23 | *.pgc 24 | *.pgd 25 | *.rsp 26 | *.sbr 27 | *.tlb 28 | *.tli 29 | *.tlh 30 | *.tmp 31 | *.vspscc 32 | .builds 33 | *.dotCover 34 | 35 | ## TODO: If you have NuGet Package Restore enabled, uncomment this 36 | #packages/ 37 | 38 | # Visual C++ cache files 39 | ipch/ 40 | *.aps 41 | *.ncb 42 | *.opensdf 43 | *.sdf 44 | 45 | # Visual Studio profiler 46 | *.psess 47 | *.vsp 48 | 49 | # ReSharper is a .NET coding add-in 50 | _ReSharper* 51 | 52 | # Installshield output folder 53 | [Ee]xpress 54 | 55 | # DocProject is a documentation generator add-in 56 | DocProject/buildhelp/ 57 | DocProject/Help/*.HxT 58 | DocProject/Help/*.HxC 59 | DocProject/Help/*.hhc 60 | DocProject/Help/*.hhk 61 | DocProject/Help/*.hhp 62 | DocProject/Help/Html2 63 | DocProject/Help/html 64 | 65 | # Click-Once directory 66 | publish 67 | 68 | # Others 69 | [Bb]in 70 | [Oo]bj 71 | sql 72 | TestResults 73 | *.Cache 74 | ClientBin 75 | stylecop.* 76 | ~$* 77 | *.dbmdl 78 | Generated_Code #added for RIA/Silverlight projects 79 | 80 | # Backup & report files from converting an old project file to a newer 81 | # Visual Studio version. Backup files are not needed, because we have git ;-) 82 | _UpgradeReport_Files/ 83 | Backup*/ 84 | UpgradeLog*.XML 85 | 86 | 87 | 88 | ############ 89 | ## Windows 90 | ############ 91 | 92 | # Windows image file caches 93 | Thumbs.db 94 | 95 | # Folder config file 96 | Desktop.ini 97 | 98 | ############ 99 | ## Mac 100 | ############ 101 | 102 | .DS_Store 103 | 104 | ############ 105 | ## CMake 106 | ############ 107 | 108 | build/* 109 | dest/* 110 | .vscode/* 111 | nmake/* 112 | projects/* 113 | !projects/CMake/CMakeLists.txt 114 | !projects/CMake/shared.cmake 115 | !projects/nuget/rxcpp.autopackage 116 | !projects/doxygen 117 | !projects/scripts 118 | Testing/* 119 | 120 | CMakeCache.txt 121 | CMakeFiles 122 | *.cmake 123 | *.log 124 | *.vcxproj* 125 | *.sln 126 | Makefile 127 | 128 | ############ 129 | ## Sublime 130 | ############ 131 | 132 | *.sublime-* 133 | 134 | ############ 135 | ## Doxygen 136 | ############ 137 | 138 | projects/doxygen/*.conf 139 | projects/doxygen/html 140 | Rx/v2/examples/doxygen/output.txt 141 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "ext/catch"] 2 | path = ext/catch 3 | url = https://github.com/philsquared/Catch.git 4 | -------------------------------------------------------------------------------- /AUTHORS.txt: -------------------------------------------------------------------------------- 1 | List of contributors to the Rx libraries 2 | 3 | Rx and Ix.NET: 4 | Wes Dyer 5 | Jeffrey van Gogh 6 | Matthew Podwysocki 7 | Bart de Smet 8 | Danny van Velzen 9 | Erik Meijer 10 | Brian Beckman 11 | Aaron Lahman 12 | Georgi Chkodrov 13 | Arthur Watson 14 | Gert Drapers 15 | Mark Shields 16 | 17 | Rx.js and Ix.js: 18 | Matthew Podwysocki 19 | Jeffrey van Gogh 20 | Bart de Smet 21 | Brian Beckman 22 | Wes Dyer 23 | Erik Meijer 24 | 25 | Tx: 26 | Georgi Chkodrov 27 | Bart de Smet 28 | Aaron Lahman 29 | Erik Meijer 30 | Brian Grunkemeyer 31 | Beysim Sezgin 32 | Tiho Tarnavski 33 | Collin Meek 34 | Sajay Anthony 35 | Karen Albrecht 36 | John Allen 37 | Zach Kramer 38 | 39 | Rx++ and Ix++: 40 | Aaron Lahman 41 | Kirk Shoop 42 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.2 FATAL_ERROR) 2 | 3 | # define some folders 4 | 5 | add_subdirectory(projects/CMake build) 6 | -------------------------------------------------------------------------------- /DeveloperManual.md: -------------------------------------------------------------------------------- 1 | # Developer Manual 2 | 3 | ## Some comments on the scheduler system 4 | 5 | The scheduler in rxcpp v2 is based on the scheduler and worker constructs that *RxJava* uses (Eric Meijer was involved) The docs for *RxJava* will have an explanation for ```scheduler``` and ```worker```. RxCpp adds ```schedulable```, ```coordination``` and ```coordinator```. 6 | 7 | ```scheduler``` owns a timeline that is exposed by the ```now()``` method. ```scheduler``` is also a factory for workers in that timeline. Since a scheduler owns a timeline it is possible to build schedulers that time-travel. The virtual-scheduler is a base for the test-scheduler that uses this to make multi-second tests complete in ms. 8 | 9 | ```worker``` owns a queue of pending ```schedulable```s for the timeline and has a lifetime. When the time for an ```schedulable``` is reached the ```schedulable``` is run. The queue maintains insertion order so that when N ```schedulable```s have the same target time they are run in the order that they were inserted into the queue. The ```worker``` guarantees that each ```schedulable``` completes before the next ```schedulable``` is started. when the ```worker```'s lifetime is unsubscribed all pending ```schedulable```s are discarded. 10 | 11 | ```schedulable``` owns a function and has a ```worker``` and a ```lifetime```. When the ```schedulable```'s ```lifetime``` is unsubscribed the ```schedulable``` function will not be called. The ```schedulable``` is passed to the function and allows the function to reschedule itself or schedule something else on the same worker. 12 | 13 | The new concepts are ```coordination``` and ```coordinator```. I added these to simplify operator implementations and to introduce pay-for-use in operator implementations. Specifically, in Rx.NET and RxJava, the operators use atomic operations and synchronization primitives to coordinate messages from multiple streams even when all the streams are on the same thread (like UI events). The ```identity_...``` coordinations in RxCpp are used by default and have no overhead. The ```synchronize_...``` and ```observe_on_...``` coordinations use mutex and queue-onto-a-worker respectively, to interleave multiple streams safely. 14 | 15 | ```coordination``` is a factory for ```coordinator```s and has a scheduler. 16 | 17 | ```coordinator``` has a ```worker```, and is a factory for coordinated observables, subscribers and schedulable functions. 18 | 19 | All the operators that take multiple streams or deal in time (even ```subscribe_on``` and ```observe_on```) take a coordination parameter, not scheduler. 20 | 21 | Here are some supplied functions that will produce a coordination using a particular scheduler. 22 | 23 | * ```identity_immediate()``` 24 | * ```identity_current_thread()``` 25 | * ```identity_same_worker(worker w)``` 26 | * ```serialize_event_loop()``` 27 | * ```serialize_new_thread()``` 28 | * ```serialize_same_worker(worker w)``` 29 | * ```observe_on_event_loop()``` 30 | * ```observe_on_new_thread()``` 31 | 32 | There is no thread-pool scheduler yet. A thread-pool scheduler requires taking a dependency on a thread-pool implementation since I do not wish to write a thread-pool. My plan is to make a scheduler for the windows thread-pool and the apple thread-pool and the boost asio executor pool.. One question to answer is whether these platform specific constructs should live in the rxcpp repo or have platform specific repos. 33 | -------------------------------------------------------------------------------- /Ix/CPP/.gitignore: -------------------------------------------------------------------------------- 1 | # Custom 2 | *.vtg 3 | *.vpwhist 4 | 5 | # Build Folders (you can keep bin if you'd like, to store dlls and pdbs) 6 | [Bb]in/ 7 | [Oo]bj/ 8 | 9 | # mstest test results 10 | TestResults 11 | 12 | ## Ignore Visual Studio temporary files, build results, and 13 | ## files generated by popular Visual Studio add-ons. 14 | 15 | # User-specific files 16 | *.suo 17 | *.user 18 | *.sln.docstates 19 | 20 | # Build results 21 | [Dd]ebug/ 22 | [Rr]elease/ 23 | x64/ 24 | *_i.c 25 | *_p.c 26 | *.ilk 27 | *.meta 28 | *.obj 29 | *.pch 30 | *.pdb 31 | *.pgc 32 | *.pgd 33 | *.rsp 34 | *.sbr 35 | *.tlb 36 | *.tli 37 | *.tlh 38 | *.tmp 39 | *.log 40 | *.vspscc 41 | *.vssscc 42 | .builds 43 | 44 | # Visual C++ cache files 45 | ipch/ 46 | *.aps 47 | *.ncb 48 | *.opensdf 49 | *.sdf 50 | 51 | # Visual Studio profiler 52 | *.psess 53 | *.vsp 54 | *.vspx 55 | 56 | # Guidance Automation Toolkit 57 | *.gpState 58 | 59 | # ReSharper is a .NET coding add-in 60 | _ReSharper* 61 | 62 | # NCrunch 63 | *.ncrunch* 64 | .*crunch*.local.xml 65 | 66 | # Installshield output folder 67 | [Ee]xpress 68 | 69 | # DocProject is a documentation generator add-in 70 | DocProject/buildhelp/ 71 | DocProject/Help/*.HxT 72 | DocProject/Help/*.HxC 73 | DocProject/Help/*.hhc 74 | DocProject/Help/*.hhk 75 | DocProject/Help/*.hhp 76 | DocProject/Help/Html2 77 | DocProject/Help/html 78 | 79 | # Click-Once directory 80 | publish 81 | 82 | # Publish Web Output 83 | *.Publish.xml 84 | 85 | # NuGet Packages Directory 86 | packages 87 | 88 | # Windows Azure Build Output 89 | csx 90 | *.build.csdef 91 | 92 | # Others 93 | [Bb]in 94 | [Oo]bj 95 | sql 96 | TestResults 97 | [Tt]est[Rr]esult* 98 | *.Cache 99 | ClientBin 100 | [Ss]tyle[Cc]op.* 101 | ~$* 102 | *.dbmdl 103 | Generated_Code #added for RIA/Silverlight projects 104 | 105 | # Backup & report files from converting an old project file to a newer 106 | # Visual Studio version. Backup files are not needed, because we have git ;-) 107 | _UpgradeReport_Files/ 108 | Backup*/ 109 | UpgradeLog*.XML 110 | 111 | # Mac crap 112 | .DS_Store 113 | 114 | a.out 115 | -------------------------------------------------------------------------------- /Ix/CPP/license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. 2 | Microsoft Open Technologies would like to thank its contributors, a list 3 | of whom are at http://rx.codeplex.com/wikipage?title=Contributors. 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); you 6 | may not use this file except in compliance with the License. You may 7 | obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 14 | implied. See the License for the specific language governing permissions 15 | and limitations under the License. -------------------------------------------------------------------------------- /Ix/CPP/projects/CppLinq.vpw: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Ix/CPP/projects/Unittest.CppLinq.vpj: -------------------------------------------------------------------------------- 1 | 2 | 7 | 11 | 12 | 18 | 19 | 20 | 26 | 27 | 28 | 34 | 35 | 36 | 41 | 42 | 43 | 48 | 49 | 50 | 51 | 52 | 56 | 57 | 63 | 64 | 65 | 71 | 72 | 73 | 79 | 80 | 81 | 86 | 87 | 88 | 93 | 94 | 95 | 96 | 97 | 98 | 101 | 102 | 105 | 106 | 109 | 112 | 115 | 116 | 117 | 118 | 123 | 128 | 133 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /Ix/CPP/samples/SampleCppLinq/SampleCppLinq.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. 2 | 3 | // SampleCppLinq.cpp : Defines the entry point for the console application. 4 | // 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | using namespace std; 20 | 21 | vector load_data(); 22 | string extract_value(const string& input, const string& key); 23 | 24 | 25 | void run() 26 | { 27 | using namespace cpplinq; 28 | 29 | struct item { 30 | string args; 31 | int concurrency; 32 | double time; 33 | 34 | item(const string& input) { 35 | args = extract_value(input, "args"); 36 | concurrency = atoi( extract_value(input, "concurrency").c_str() ); 37 | time = atof( extract_value(input, "time").c_str() ); 38 | } 39 | }; 40 | 41 | auto data_unparsed = load_data(); 42 | auto data_parsed = 43 | from(data_unparsed) 44 | .select([](const string& line) { return item(line); }) 45 | .to_vector(); 46 | 47 | cout << "data loaded" << endl; 48 | 49 | auto data = 50 | from(data_parsed) 51 | .groupby([](const item& i) { return i.args; }); 52 | 53 | for (auto giter = data.begin(), end = data.end(); giter != end; ++giter) 54 | { 55 | const auto& g = *giter; 56 | 57 | cout << "arguments: " << g.key << endl; 58 | 59 | cout << "concurrency, mean, |, raw_data," << endl; 60 | auto seq = 61 | from(g) 62 | .groupby([](const item& i) { return i.concurrency; }); 63 | 64 | for (auto giter = seq.begin(), end = seq.end(); giter != end; ++giter) 65 | { 66 | const auto& g = *giter; 67 | 68 | cout << g.key << ", "; 69 | 70 | auto times = from(g).select([](const item& i) { return i.time; }); 71 | 72 | auto n = from(g).count(); 73 | auto sum = std::accumulate(times.begin(), times.end(), 0.0); 74 | 75 | cout << (sum / n) << ", |"; 76 | 77 | for (auto timeIter = times.begin(), end = times.end(); 78 | timeIter != end; 79 | ++timeIter) 80 | { 81 | cout << ", " << *timeIter; 82 | } 83 | cout << endl; 84 | } 85 | } 86 | } 87 | 88 | 89 | int main() 90 | { 91 | try { 92 | run(); 93 | } catch (exception& e) { 94 | cerr << "exception: " << e.what() << endl; 95 | } 96 | } 97 | 98 | vector load_data() 99 | { 100 | ifstream datafile("data.txt"); 101 | vector v; 102 | string line; 103 | 104 | if (datafile.fail()) 105 | throw logic_error("could not find file"); 106 | 107 | while(getline(datafile, line)) 108 | v.push_back(line); 109 | 110 | return v; 111 | } 112 | 113 | regex key_value_pair("'([^\']*)'\\s*[:,]\\s*(\\d+(?:\\.\\d+)?|'[^']*')"); 114 | 115 | string extract_value(const string& input, const string& key) 116 | { 117 | const std::sregex_iterator end; 118 | for (std::sregex_iterator i(input.cbegin(), input.cend(), key_value_pair); 119 | i != end; 120 | ++i) 121 | { 122 | if ((*i)[1] == key) 123 | { 124 | return (*i)[2]; 125 | } 126 | } 127 | throw std::range_error("search key not found"); 128 | } 129 | -------------------------------------------------------------------------------- /Ix/CPP/samples/SampleCppLinq/SampleCppLinq.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 11 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SampleCppLinq", "SampleCppLinq.vcxproj", "{B65551BA-E1BA-4735-BA51-FFA83D64823E}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {B65551BA-E1BA-4735-BA51-FFA83D64823E}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {B65551BA-E1BA-4735-BA51-FFA83D64823E}.Debug|Win32.Build.0 = Debug|Win32 14 | {B65551BA-E1BA-4735-BA51-FFA83D64823E}.Release|Win32.ActiveCfg = Release|Win32 15 | {B65551BA-E1BA-4735-BA51-FFA83D64823E}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /Ix/CPP/samples/SampleCppLinq/SampleCppLinq.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Ix/CPP/src/IxCpp.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {65483A0D-1D72-47CC-B147-27415FFC1FC3} 15 | MakeFileProj 16 | 17 | 18 | 19 | Makefile 20 | true 21 | v110 22 | 23 | 24 | Makefile 25 | false 26 | v110 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | WIN32;_DEBUG;$(NMakePreprocessorDefinitions) 40 | 41 | 42 | WIN32;NDEBUG;$(NMakePreprocessorDefinitions) 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /Ix/CPP/src/IxCpp.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | Header Files 35 | 36 | 37 | Header Files 38 | 39 | 40 | Header Files 41 | 42 | 43 | Header Files 44 | 45 | 46 | Header Files 47 | 48 | 49 | Header Files 50 | 51 | 52 | Header Files 53 | 54 | 55 | -------------------------------------------------------------------------------- /Ix/CPP/src/cpplinq/linq_last.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. 2 | 3 | #if !defined(CPPLINQ_LINQ_LAST_HPP) 4 | #define CPPLINQ_LINQ_LAST_HPP 5 | #pragma once 6 | 7 | namespace cpplinq { 8 | 9 | template 10 | typename Cursor::element_type 11 | linq_last_(Cursor c, onepass_cursor_tag) 12 | { 13 | if (c.empty()) { throw std::logic_error("last() out of bounds"); } 14 | typename Cursor::element_type elem = c.get(); 15 | for(;;) { 16 | c.inc(); 17 | if (c.empty()) break; 18 | elem = c.get(); 19 | } 20 | return elem; 21 | } 22 | 23 | // TODO: bidirectional iterator in constant time 24 | 25 | template 26 | typename Cursor::reference_type 27 | linq_last_(Cursor c, forward_cursor_tag) 28 | { 29 | if (c.empty()) { throw std::logic_error("last() out of bounds"); } 30 | Cursor best = c; 31 | for(;;) { 32 | c.inc(); 33 | if (c.empty()) break; 34 | best = c; 35 | } 36 | return best.get(); 37 | } 38 | 39 | template 40 | typename Cursor::reference_type 41 | linq_last_(Cursor c, random_access_cursor_tag) 42 | { 43 | if (c.empty()) { throw std::logic_error("last() out of bounds"); } 44 | c.skip(c.size()-1); 45 | return c.get(); 46 | } 47 | 48 | template 49 | typename Cursor::element_type 50 | linq_last_or_default_(Cursor c, onepass_cursor_tag) 51 | { 52 | typename Cursor::element_type elem; 53 | while(!c.empty()) { 54 | elem = c.get(); 55 | c.inc(); 56 | } 57 | return elem; 58 | } 59 | 60 | template 61 | typename Cursor::element_type 62 | linq_last_or_default_(Cursor c, forward_cursor_tag) 63 | { 64 | if (c.empty()) { throw std::logic_error("last() out of bounds"); } 65 | Cursor best = c; 66 | for(;;) { 67 | c.inc(); 68 | if (c.empty()) break; 69 | best = c; 70 | } 71 | return best.get(); 72 | } 73 | 74 | template 75 | typename Cursor::element_type 76 | linq_last_or_default_(Cursor c, random_access_cursor_tag) 77 | { 78 | if (c.empty()) { return typename Cursor::element_type(); } 79 | c.skip(c.size()-1); 80 | return c.get(); 81 | } 82 | 83 | } 84 | 85 | #endif // CPPLINQ_LINQ_LAST_HPP 86 | -------------------------------------------------------------------------------- /Ix/CPP/src/cpplinq/linq_select.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. 2 | 3 | #if !defined(CPPLINQ_LINQ_SELECT_HPP) 4 | #define CPPLINQ_LINQ_SELECT_HPP 5 | #pragma once 6 | 7 | #include 8 | 9 | namespace cpplinq 10 | { 11 | template 12 | class linq_select 13 | { 14 | typedef typename Collection::cursor 15 | inner_cursor; 16 | public: 17 | struct cursor { 18 | typedef typename util::result_of::type 19 | reference_type; 20 | typedef typename std::remove_reference::type 21 | element_type; 22 | typedef typename inner_cursor::cursor_category 23 | cursor_category; 24 | 25 | cursor(const inner_cursor& cur, Selector sel) : cur(cur), sel(std::move(sel)) {} 26 | 27 | void forget() { cur.forget(); } 28 | bool empty() const { return cur.empty(); } 29 | void inc() { cur.inc(); } 30 | reference_type get() const { return sel(cur.get()); } 31 | 32 | bool atbegin() const { return cur.atbegin(); } 33 | void dec() { cur.dec(); } 34 | 35 | void skip(std::size_t n) { cur.skip(n); } 36 | std::size_t position() const { return cur.position(); } 37 | std::size_t size() const { return cur.size(); } 38 | private: 39 | inner_cursor cur; 40 | Selector sel; 41 | }; 42 | 43 | linq_select(const Collection& c, Selector sel) : c(c), sel(sel) {} 44 | 45 | cursor get_cursor() const { return cursor(c.get_cursor(), sel); } 46 | 47 | private: 48 | Collection c; 49 | Selector sel; 50 | }; 51 | 52 | } 53 | 54 | #endif // defined(CPPLINQ_LINQ_SELECT_HPP) 55 | -------------------------------------------------------------------------------- /Ix/CPP/src/cpplinq/linq_skip.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. 2 | 3 | #if !defined(CPPLINQ_LINQ_SKIP_HPP) 4 | #define CPPLINQ_LINQ_SKIP_HPP 5 | #pragma once 6 | 7 | #include 8 | 9 | namespace cpplinq 10 | { 11 | template 12 | struct linq_skip 13 | { 14 | public: 15 | typedef typename Collection::cursor cursor; 16 | 17 | linq_skip(const Collection& c, std::size_t n) : c(c), n(n) {} 18 | 19 | cursor get_cursor() const { 20 | std::size_t rem = n; 21 | 22 | auto cur = c.get_cursor(); 23 | while(rem-- && !cur.empty()) { 24 | cur.inc(); 25 | } 26 | cur.forget(); 27 | return cur; 28 | } 29 | 30 | private: 31 | Collection c; 32 | std::size_t n; 33 | }; 34 | } 35 | #endif // !defined(CPPLINQ_LINQ_SKIP_HPP) 36 | 37 | 38 | -------------------------------------------------------------------------------- /Ix/CPP/src/cpplinq/linq_take.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. 2 | 3 | #if !defined(CPPLINQ_LINQ_TAKE_HPP) 4 | #define CPPLINQ_LINQ_TAKE_HPP 5 | #pragma once 6 | 7 | #include 8 | 9 | namespace cpplinq 10 | { 11 | template 12 | struct linq_take_cursor 13 | { 14 | typedef typename InnerCursor::element_type element_type; 15 | typedef typename InnerCursor::reference_type reference_type; 16 | typedef typename InnerCursor::cursor_category cursor_category; 17 | 18 | linq_take_cursor(const InnerCursor& cur, std::size_t rem) : cur(cur), rem(rem) {} 19 | 20 | void forget() { cur.forget(); } 21 | bool empty() const { return cur.empty() || rem == 0; } 22 | void inc() { cur.inc(); --rem; } 23 | reference_type get() const { return cur.get(); } 24 | 25 | bool atbegin() const { return cur.atbegin(); } 26 | void dec() { cur.dec(); --rem; } 27 | 28 | void skip(std::size_t n) { cur.skip(n); rem -= n; } 29 | std::size_t position() const { return cur.position(); } 30 | std::size_t size() const { return cur.size(); } 31 | 32 | private: 33 | InnerCursor cur; 34 | std::size_t rem; 35 | }; 36 | 37 | namespace detail { 38 | template 39 | linq_take_cursor 40 | take_get_cursor_( 41 | const Collection& c, 42 | std::size_t n, 43 | onepass_cursor_tag 44 | ) 45 | { 46 | return linq_take_cursor(c.get_cursor(), n); 47 | } 48 | 49 | template 50 | typename Collection::cursor 51 | take_get_cursor_( 52 | const Collection& c, 53 | std::size_t n, 54 | random_access_cursor_tag 55 | ) 56 | { 57 | auto cur = c.get_cursor(); 58 | if (cur.size() > n) { 59 | cur.truncate(n); 60 | } 61 | return cur; 62 | } 63 | } 64 | 65 | template 66 | struct linq_take 67 | { 68 | typedef typename std::conditional< 69 | util::less_or_equal_cursor_category< 70 | random_access_cursor_tag, 71 | typename Collection::cursor::cursor_category>::value, 72 | typename Collection::cursor, 73 | linq_take_cursor>::type 74 | cursor; 75 | 76 | linq_take(const Collection& c, std::size_t n) : c(c), n(n) {} 77 | 78 | cursor get_cursor() const { 79 | return detail::take_get_cursor_(c, n, typename Collection::cursor::cursor_category()); 80 | } 81 | 82 | Collection c; 83 | std::size_t n; 84 | }; 85 | 86 | template 87 | auto get_cursor( 88 | const linq_take& take 89 | ) 90 | -> decltype(get_cursor_(take, typename Collection::cursor::cursor_category())) 91 | { 92 | return get_cursor_(take, typename Collection::cursor::cursor_category()); 93 | } 94 | 95 | 96 | } 97 | #endif // !defined(CPPLINQ_LINQ_TAKE_HPP) 98 | 99 | -------------------------------------------------------------------------------- /Ix/CPP/src/cpplinq/linq_where.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. 2 | 3 | #if !defined(CPPLINQ_LINQ_WHERE_HPP) 4 | #define CPPLINQ_LINQ_WHERE_HPP 5 | #pragma once 6 | 7 | namespace cpplinq 8 | { 9 | template 10 | class linq_where 11 | { 12 | typedef typename Collection::cursor 13 | inner_cursor; 14 | public: 15 | struct cursor { 16 | typedef typename util::min_iterator_category< 17 | bidirectional_cursor_tag, 18 | typename inner_cursor::cursor_category>::type 19 | cursor_category; 20 | typedef typename inner_cursor::element_type 21 | element_type; 22 | typedef typename inner_cursor::reference_type 23 | reference_type; 24 | 25 | cursor(const inner_cursor& cur, const Predicate& p) : cur(cur), pred(p) 26 | { 27 | if (!cur.empty() && !pred(cur.get())) { 28 | this->inc(); 29 | } 30 | } 31 | 32 | void forget() { cur.forget(); } 33 | bool empty() const { return cur.empty(); } 34 | void inc() { 35 | for (;;) { 36 | cur.inc(); 37 | if (cur.empty() || pred(cur.get())) break; 38 | } 39 | } 40 | reference_type get() const { 41 | return cur.get(); 42 | } 43 | 44 | bool atbegin() const { return atbegin(cur); } 45 | void dec() { 46 | for (;;) { 47 | cur.dec(); 48 | if (pred(cur.get())) break; 49 | } 50 | } 51 | private: 52 | inner_cursor cur; 53 | Predicate pred; 54 | }; 55 | 56 | linq_where(const Collection& c, Predicate pred) : c(c), pred(pred) {} 57 | 58 | cursor get_cursor() const { 59 | return cursor(c.get_cursor(), pred); 60 | } 61 | 62 | private: 63 | Collection c; 64 | Predicate pred; 65 | }; 66 | } 67 | 68 | #endif // !defined(CPPLINQ_LINQ_WHERE_HPP) 69 | 70 | -------------------------------------------------------------------------------- /Ix/CPP/unittest/makefile: -------------------------------------------------------------------------------- 1 | 2 | 3 | !ifndef Config 4 | Config=Debug 5 | !endif 6 | 7 | O=..\..\bin\$(Config) 8 | 9 | !message Building ===== $(Config) ===== 10 | 11 | program=testbench.exe 12 | INCLUDE=$(INCLUDE);../src 13 | 14 | !if "$(Config)"=="Debug" 15 | OPTIONS=/Od 16 | !else 17 | OPTIONS=/Ox 18 | !endif 19 | OPTIONS=$(OPTIONS) /Zi /I$(BOOST) /DBOOST_RESULT_OF_USE_DECLTYPE 20 | 21 | runtests : "$O/$(program)" 22 | "$O/$(program)" 23 | 24 | 25 | all : "$O/$(program)" 26 | 27 | $O : 28 | mkdir $O 29 | 30 | "$O/$(program)" : testbench.cpp testbench.hpp ../src/cpplinq/*.hpp $O 31 | $(CPP) $(OPTIONS) /EHsc /Zi /Fe"$@" /Fo$O/ testbench.cpp 32 | 33 | clean : 34 | del /Q $O\*.exe 35 | del /Q $O\*.pdb 36 | del /Q $O\*.obj 37 | del /Q $O\*.ilk 38 | -------------------------------------------------------------------------------- /Ix/CPP/unittest/testbench.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. 2 | 3 | #pragma once 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | struct empty_testcase{ void run(){} const char* name(){return 0;} }; 14 | 15 | template 16 | struct testcase : empty_testcase{}; 17 | 18 | 19 | template 20 | struct testrange { 21 | void run(std::size_t& pass, std::size_t& fail) 22 | { 23 | using namespace std; 24 | { testcase a_case; 25 | if (a_case.name()) { 26 | std::size_t p=0, f=0; 27 | cout << "TEST: Running " << a_case.name() << endl; 28 | try { 29 | a_case.run(); 30 | ++p; 31 | } catch (logic_error& e) { 32 | cerr << "ERRORS:" << endl; 33 | cerr << " " << e.what() << endl; 34 | ++f; 35 | } 36 | pass += p; fail += f; 37 | } 38 | } 39 | const std::size_t rem = (end-begin-1); 40 | testrange().run(pass, fail); 41 | testrange().run(pass, fail); 42 | } 43 | }; 44 | 45 | template 46 | struct testrange { 47 | void run(std::size_t& pass, std::size_t& fail) {}; 48 | }; 49 | 50 | #define TEST(fun_name) \ 51 | void fun_name (); \ 52 | template <> \ 53 | struct testcase<__LINE__> { \ 54 | const char* name() { return(#fun_name); } \ 55 | void run() { fun_name(); } \ 56 | }; \ 57 | void fun_name() 58 | 59 | #define Q_(e) #e 60 | #define Q(e) Q_(e) 61 | #define TASSERT(expr) \ 62 | { auto e = (expr); if (!e) { throw std::logic_error(__FILE__ "(" Q(__LINE__) "): TASSERT("#expr")"); } } 63 | 64 | struct errmsg 65 | { 66 | std::shared_ptr msg; 67 | errmsg() : msg(new std::stringstream) 68 | {} 69 | 70 | template 71 | errmsg& operator<<(T value) 72 | { 73 | (*msg) << value; 74 | return *this; 75 | } 76 | std::string str() { return msg->str(); } 77 | }; 78 | 79 | #define TEST_WHERE __FILE__ "(" Q(__LINE__) "): " 80 | #define VERIFY(expr) \ 81 | { auto e = (expr); if (!e) { throw std::logic_error(TEST_WHERE "VERIFY("#expr")"); } } 82 | #define VERIFY_EQ(expected, actual) \ 83 | { auto e = (expected); auto a = (actual); \ 84 | if (!(e == a)) { \ 85 | throw std::logic_error( \ 86 | (errmsg() << TEST_WHERE << "(" << e << ")!=(" << a << ") in VERIFY_EQ("#expected","#actual")").str() );}} 87 | 88 | 89 | -------------------------------------------------------------------------------- /Rx/v2/examples/awaitable/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.2 FATAL_ERROR) 2 | 3 | get_filename_component(SAMPLE_PROJECT "${CMAKE_CURRENT_SOURCE_DIR}" NAME) 4 | 5 | project(${SAMPLE_PROJECT} LANGUAGES C CXX) 6 | 7 | # define some folders 8 | get_filename_component(RXCPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}" PATH) 9 | get_filename_component(RXCPP_DIR "${RXCPP_DIR}" PATH) 10 | get_filename_component(RXCPP_DIR "${RXCPP_DIR}" PATH) 11 | get_filename_component(RXCPP_DIR "${RXCPP_DIR}" PATH) 12 | 13 | MESSAGE( STATUS "RXCPP_DIR: " ${RXCPP_DIR} ) 14 | 15 | include(${RXCPP_DIR}/projects/CMake/shared.cmake) 16 | 17 | # define the sources 18 | set(SAMPLE_SOURCES 19 | ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp 20 | ) 21 | add_executable(${SAMPLE_PROJECT} ${SAMPLE_SOURCES}) 22 | add_executable(rxcpp::examples::${SAMPLE_PROJECT} ALIAS ${SAMPLE_PROJECT}) 23 | target_compile_options(${SAMPLE_PROJECT} PUBLIC ${RX_COMPILE_OPTIONS} /await) 24 | target_compile_features(${SAMPLE_PROJECT} PUBLIC ${RX_COMPILE_FEATURES}) 25 | target_include_directories(${SAMPLE_PROJECT} PUBLIC ${RX_SRC_DIR}) 26 | target_link_libraries(${SAMPLE_PROJECT} ${CMAKE_THREAD_LIBS_INIT}) 27 | 28 | # configure unit tests via CTest 29 | enable_testing() 30 | set(CTEST_CONFIGURATION_TYPE "${JOB_BUILD_CONFIGURATION}") 31 | 32 | set_target_properties(${SAMPLE_PROJECT} PROPERTIES FOLDER "Examples") 33 | 34 | add_test(NAME RunTests 35 | WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" 36 | COMMAND ${SAMPLE_PROJECT} ${TEST_ARGS}) 37 | -------------------------------------------------------------------------------- /Rx/v2/examples/awaitable/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | using namespace rxcpp; 8 | using namespace rxcpp::sources; 9 | using namespace rxcpp::operators; 10 | using namespace rxcpp::util; 11 | 12 | using namespace std; 13 | using namespace std::chrono; 14 | 15 | future intervals(){ 16 | 17 | { 18 | printf("early exit from interval on thread\n"); 19 | for co_await (auto c : interval(seconds(1), observe_on_event_loop())) { 20 | printf("%d\n", c); 21 | break; 22 | } 23 | } 24 | 25 | { 26 | printf("interval on thread\n"); 27 | for co_await (auto c : interval(seconds(1), observe_on_event_loop()) | take(3)) { 28 | printf("%d\n", c); 29 | } 30 | } 31 | 32 | { 33 | printf("current thread\n"); 34 | int last = 0; 35 | for co_await (auto c : range(1, 100000)) { 36 | last = c; 37 | } 38 | printf("reached %d\n", last); 39 | } 40 | 41 | try { 42 | printf("error in observable\n"); 43 | for co_await (auto c : error(runtime_error("stopped by error"))) { 44 | printf("%d\n", c); 45 | } 46 | printf("not reachable\n"); 47 | terminate(); 48 | } 49 | catch(const exception& e) { 50 | printf("%s\n", e.what()); 51 | } 52 | } 53 | 54 | int main() 55 | { 56 | intervals().get(); 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /Rx/v2/examples/cep/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.2 FATAL_ERROR) 2 | 3 | get_filename_component(SAMPLE_PROJECT "${CMAKE_CURRENT_SOURCE_DIR}" NAME) 4 | 5 | project(${SAMPLE_PROJECT} LANGUAGES C CXX) 6 | 7 | # define some folders 8 | get_filename_component(RXCPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}" PATH) 9 | get_filename_component(RXCPP_DIR "${RXCPP_DIR}" PATH) 10 | get_filename_component(RXCPP_DIR "${RXCPP_DIR}" PATH) 11 | get_filename_component(RXCPP_DIR "${RXCPP_DIR}" PATH) 12 | 13 | MESSAGE( STATUS "RXCPP_DIR: " ${RXCPP_DIR} ) 14 | 15 | include(${RXCPP_DIR}/projects/CMake/shared.cmake) 16 | 17 | # define the sources 18 | set(SAMPLE_SOURCES 19 | ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp 20 | ) 21 | add_executable(${SAMPLE_PROJECT} ${SAMPLE_SOURCES}) 22 | add_executable(rxcpp::examples::${SAMPLE_PROJECT} ALIAS ${SAMPLE_PROJECT}) 23 | target_compile_options(${SAMPLE_PROJECT} PUBLIC ${RX_COMPILE_OPTIONS}) 24 | target_compile_features(${SAMPLE_PROJECT} PUBLIC ${RX_COMPILE_FEATURES}) 25 | target_include_directories(${SAMPLE_PROJECT} 26 | PUBLIC ${RX_SRC_DIR} ${RX_CATCH_DIR} 27 | ) 28 | target_link_libraries(${SAMPLE_PROJECT} ${CMAKE_THREAD_LIBS_INIT}) 29 | 30 | # configure unit tests via CTest 31 | enable_testing() 32 | set(CTEST_CONFIGURATION_TYPE "${JOB_BUILD_CONFIGURATION}") 33 | 34 | set_target_properties(${SAMPLE_PROJECT} PROPERTIES FOLDER "Examples") 35 | 36 | add_test(NAME RunTests 37 | WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" 38 | COMMAND ${SAMPLE_PROJECT} ${TEST_ARGS}) 39 | -------------------------------------------------------------------------------- /Rx/v2/examples/cep/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "rxcpp/rx.hpp" 3 | // create alias' to simplify code 4 | // these are owned by the user so that 5 | // conflicts can be managed by the user. 6 | namespace rx=rxcpp; 7 | namespace rxsub=rxcpp::subjects; 8 | namespace rxu=rxcpp::util; 9 | 10 | #include 11 | #include 12 | 13 | // At this time, RxCpp will fail to compile if the contents 14 | // of the std namespace are merged into the global namespace 15 | // DO NOT USE: 'using namespace std;' 16 | 17 | int main() 18 | { 19 | auto keys = rx::observable<>::create( 20 | [](rx::subscriber dest){ 21 | for (;;) { 22 | int key = std::cin.get(); 23 | dest.on_next(key); 24 | } 25 | }). 26 | publish(); 27 | 28 | auto a = keys. 29 | filter([](int key){return std::tolower(key) == 'a';}); 30 | 31 | auto g = keys. 32 | filter([](int key){return std::tolower(key) == 'g';}); 33 | 34 | a.merge(g). 35 | subscribe([](int key){ 36 | std::cout << key << std::endl; 37 | }); 38 | 39 | // run the loop in create 40 | keys.connect(); 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.2 FATAL_ERROR) 2 | 3 | get_filename_component(SAMPLE_PROJECT "${CMAKE_CURRENT_SOURCE_DIR}" NAME) 4 | 5 | project(${SAMPLE_PROJECT} LANGUAGES C CXX) 6 | 7 | # define some folders 8 | get_filename_component(RXCPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}" PATH) 9 | get_filename_component(RXCPP_DIR "${RXCPP_DIR}" PATH) 10 | get_filename_component(RXCPP_DIR "${RXCPP_DIR}" PATH) 11 | get_filename_component(RXCPP_DIR "${RXCPP_DIR}" PATH) 12 | 13 | MESSAGE( STATUS "RXCPP_DIR: " ${RXCPP_DIR} ) 14 | 15 | include(${RXCPP_DIR}/projects/CMake/shared.cmake) 16 | 17 | # define the sources 18 | file(GLOB SAMPLE_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp") 19 | add_executable(${SAMPLE_PROJECT} ${SAMPLE_SOURCES}) 20 | add_executable(rxcpp::examples::${SAMPLE_PROJECT} ALIAS ${SAMPLE_PROJECT}) 21 | target_compile_options(${SAMPLE_PROJECT} PUBLIC ${RX_COMPILE_OPTIONS}) 22 | target_compile_features(${SAMPLE_PROJECT} PUBLIC ${RX_COMPILE_FEATURES}) 23 | target_include_directories(${SAMPLE_PROJECT} PUBLIC ${RX_SRC_DIR} ${RX_CATCH_DIR}) 24 | target_link_libraries(${SAMPLE_PROJECT} ${CMAKE_THREAD_LIBS_INIT}) 25 | 26 | # configure unit tests via CTest 27 | enable_testing() 28 | set(CTEST_CONFIGURATION_TYPE "${JOB_BUILD_CONFIGURATION}") 29 | 30 | add_test(NAME RunTests 31 | WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" 32 | COMMAND ${SAMPLE_PROJECT} ${TEST_ARGS}) 33 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/all.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("all sample") { 7 | printf("//! [all sample]\n"); 8 | auto values = rxcpp::observable<>::from(1, 2, 3, 4, 5).all([](int n) { return n < 6; }); 9 | values. 10 | subscribe( 11 | [](bool v) { printf("OnNext: %s\n", v ? "true" : "false"); }, 12 | []() { printf("OnCompleted\n"); }); 13 | printf("//! [all sample]\n"); 14 | } 15 | 16 | SCENARIO("all - operator syntax sample") { 17 | using namespace rxcpp; 18 | using namespace rxcpp::sources; 19 | using namespace rxcpp::operators; 20 | 21 | printf("//! [all - operator syntax sample]\n"); 22 | auto values = range(1, 10) 23 | | all([](int n) { return n < 100; }); 24 | values. 25 | subscribe( 26 | [](bool v) { printf("OnNext: %s\n", v ? "true" : "false"); }, 27 | []() { printf("OnCompleted\n"); }); 28 | printf("//! [all - operator syntax sample]\n"); 29 | } -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/amb.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("amb sample"){ 7 | printf("//! [amb sample]\n"); 8 | auto o1 = rxcpp::observable<>::timer(std::chrono::milliseconds(15)).map([](int) {return 1;}); 9 | auto o2 = rxcpp::observable<>::timer(std::chrono::milliseconds(10)).map([](int) {return 2;}); 10 | auto o3 = rxcpp::observable<>::timer(std::chrono::milliseconds(5)).map([](int) {return 3;}); 11 | auto values = o1.amb(o2, o3); 12 | values. 13 | subscribe( 14 | [](int v){printf("OnNext: %d\n", v);}, 15 | [](){printf("OnCompleted\n");}); 16 | printf("//! [amb sample]\n"); 17 | } 18 | 19 | SCENARIO("implicit amb sample"){ 20 | printf("//! [implicit amb sample]\n"); 21 | auto o1 = rxcpp::observable<>::timer(std::chrono::milliseconds(15)).map([](int) {return 1;}); 22 | auto o2 = rxcpp::observable<>::timer(std::chrono::milliseconds(10)).map([](int) {return 2;}); 23 | auto o3 = rxcpp::observable<>::timer(std::chrono::milliseconds(5)).map([](int) {return 3;}); 24 | auto base = rxcpp::observable<>::from(o1.as_dynamic(), o2, o3); 25 | auto values = base.amb(); 26 | values. 27 | subscribe( 28 | [](int v){printf("OnNext: %d\n", v);}, 29 | [](){printf("OnCompleted\n");}); 30 | printf("//! [implicit amb sample]\n"); 31 | } 32 | 33 | #include "main.hpp" 34 | 35 | SCENARIO("threaded amb sample"){ 36 | printf("//! [threaded amb sample]\n"); 37 | printf("[thread %s] Start task\n", get_pid().c_str()); 38 | auto o1 = rxcpp::observable<>::timer(std::chrono::milliseconds(15)).map([](int) { 39 | printf("[thread %s] Timer1 fired\n", get_pid().c_str()); 40 | return 1; 41 | }); 42 | auto o2 = rxcpp::observable<>::timer(std::chrono::milliseconds(10)).map([](int) { 43 | printf("[thread %s] Timer2 fired\n", get_pid().c_str()); 44 | return 2; 45 | }); 46 | auto o3 = rxcpp::observable<>::timer(std::chrono::milliseconds(5)).map([](int) { 47 | printf("[thread %s] Timer3 fired\n", get_pid().c_str()); 48 | return 3; 49 | }); 50 | auto values = o1.amb(rxcpp::observe_on_new_thread(), o2, o3); 51 | values. 52 | as_blocking(). 53 | subscribe( 54 | [](int v){printf("[thread %s] OnNext: %d\n", get_pid().c_str(), v);}, 55 | [](){printf("[thread %s] OnCompleted\n", get_pid().c_str());}); 56 | printf("[thread %s] Finish task\n", get_pid().c_str()); 57 | printf("//! [threaded amb sample]\n"); 58 | } 59 | 60 | SCENARIO("threaded implicit amb sample"){ 61 | printf("//! [threaded implicit amb sample]\n"); 62 | printf("[thread %s] Start task\n", get_pid().c_str()); 63 | auto o1 = rxcpp::observable<>::timer(std::chrono::milliseconds(15)).map([](int) { 64 | printf("[thread %s] Timer1 fired\n", get_pid().c_str()); 65 | return 1; 66 | }); 67 | auto o2 = rxcpp::observable<>::timer(std::chrono::milliseconds(10)).map([](int) { 68 | printf("[thread %s] Timer2 fired\n", get_pid().c_str()); 69 | return 2; 70 | }); 71 | auto o3 = rxcpp::observable<>::timer(std::chrono::milliseconds(5)).map([](int) { 72 | printf("[thread %s] Timer3 fired\n", get_pid().c_str()); 73 | return 3; 74 | }); 75 | auto base = rxcpp::observable<>::from(o1.as_dynamic(), o2, o3); 76 | auto values = base.amb(rxcpp::observe_on_new_thread()); 77 | values. 78 | as_blocking(). 79 | subscribe( 80 | [](int v){printf("[thread %s] OnNext: %d\n", get_pid().c_str(), v);}, 81 | [](){printf("[thread %s] OnCompleted\n", get_pid().c_str());}); 82 | printf("[thread %s] Finish task\n", get_pid().c_str()); 83 | printf("//! [threaded implicit amb sample]\n"); 84 | } 85 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/any.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("any sample") { 7 | printf("//! [any sample]\n"); 8 | auto values = rxcpp::observable<>::from(1, 2, 3, 4, 5).any([](int n) { return n > 3; }); 9 | values. 10 | subscribe( 11 | [](bool v) { printf("OnNext: %s\n", v ? "true" : "false"); }, 12 | []() { printf("OnCompleted\n"); }); 13 | printf("//! [any sample]\n"); 14 | } 15 | 16 | SCENARIO("any - operator syntax sample") { 17 | using namespace rxcpp; 18 | using namespace rxcpp::sources; 19 | using namespace rxcpp::operators; 20 | 21 | printf("//! [any - operator syntax sample]\n"); 22 | auto values = range(1, 10) 23 | | any([](int n) { return n == 1; }); 24 | values. 25 | subscribe( 26 | [](bool v) { printf("OnNext: %s\n", v ? "true" : "false"); }, 27 | []() { printf("OnCompleted\n"); }); 28 | printf("//! [any - operator syntax sample]\n"); 29 | } -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/as_dynamic.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("as_dynamic sample"){ 7 | printf("//! [as_dynamic sample]\n"); 8 | auto o1 = rxcpp::observable<>::range(1, 3); 9 | auto o2 = rxcpp::observable<>::just(4); 10 | auto o3 = rxcpp::observable<>::empty(); 11 | auto values = o1.concat(o2, o3); 12 | printf("type of o1: %s\n", typeid(o1).name()); 13 | printf("type of o1.as_dynamic(): %s\n", typeid(o1.as_dynamic()).name()); 14 | printf("type of o2: %s\n", typeid(o2).name()); 15 | printf("type of o2.as_dynamic(): %s\n", typeid(o2.as_dynamic()).name()); 16 | printf("type of o3: %s\n", typeid(o3).name()); 17 | printf("type of o3.as_dynamic(): %s\n", typeid(o3.as_dynamic()).name()); 18 | printf("type of values: %s\n", typeid(values).name()); 19 | printf("type of values.as_dynamic(): %s\n", typeid(values.as_dynamic()).name()); 20 | printf("//! [as_dynamic sample]\n"); 21 | } 22 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/combine_latest.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("combine_latest sample"){ 7 | printf("//! [combine_latest sample]\n"); 8 | auto o1 = rxcpp::observable<>::interval(std::chrono::milliseconds(2)); 9 | auto o2 = rxcpp::observable<>::interval(std::chrono::milliseconds(3)); 10 | auto o3 = rxcpp::observable<>::interval(std::chrono::milliseconds(5)); 11 | auto values = o1.combine_latest(o2, o3); 12 | values. 13 | take(5). 14 | subscribe( 15 | [](std::tuple v){printf("OnNext: %d, %d, %d\n", std::get<0>(v), std::get<1>(v), std::get<2>(v));}, 16 | [](){printf("OnCompleted\n");}); 17 | printf("//! [combine_latest sample]\n"); 18 | } 19 | 20 | #include "main.hpp" 21 | 22 | SCENARIO("Coordination combine_latest sample"){ 23 | printf("//! [Coordination combine_latest sample]\n"); 24 | printf("[thread %s] Start task\n", get_pid().c_str()); 25 | auto thr = rxcpp::synchronize_event_loop(); 26 | auto o1 = rxcpp::observable<>::interval(std::chrono::milliseconds(2)).map([](int v) { 27 | printf("[thread %s] Source1 OnNext: %d\n", get_pid().c_str(), v); 28 | return v; 29 | }); 30 | auto o2 = rxcpp::observable<>::interval(std::chrono::milliseconds(3)).map([](int v) { 31 | printf("[thread %s] Source2 OnNext: %d\n", get_pid().c_str(), v); 32 | return v; 33 | }); 34 | auto o3 = rxcpp::observable<>::interval(std::chrono::milliseconds(5)).map([](int v) { 35 | printf("[thread %s] Source3 OnNext: %d\n", get_pid().c_str(), v); 36 | return v; 37 | }); 38 | auto values = o1.combine_latest(thr, o2, o3); 39 | values. 40 | take(5). 41 | as_blocking(). 42 | subscribe( 43 | [](std::tuple v){printf("[thread %s] OnNext: %d, %d, %d\n", get_pid().c_str(), std::get<0>(v), std::get<1>(v), std::get<2>(v));}, 44 | [](){printf("[thread %s] OnCompleted\n", get_pid().c_str());}); 45 | printf("[thread %s] Finish task\n", get_pid().c_str()); 46 | printf("//! [Coordination combine_latest sample]\n"); 47 | } 48 | 49 | SCENARIO("Selector combine_latest sample"){ 50 | printf("//! [Selector combine_latest sample]\n"); 51 | auto o1 = rxcpp::observable<>::interval(std::chrono::milliseconds(2)); 52 | auto o2 = rxcpp::observable<>::interval(std::chrono::milliseconds(3)); 53 | auto o3 = rxcpp::observable<>::interval(std::chrono::milliseconds(5)); 54 | auto values = o1.combine_latest( 55 | [](int v1, int v2, int v3) { 56 | return 100 * v1 + 10 * v2 + v3; 57 | }, 58 | o2, o3); 59 | values. 60 | take(5). 61 | subscribe( 62 | [](int v){printf("OnNext: %d\n", v);}, 63 | [](){printf("OnCompleted\n");}); 64 | printf("//! [Selector combine_latest sample]\n"); 65 | } 66 | 67 | SCENARIO("Coordination+Selector combine_latest sample"){ 68 | printf("//! [Coordination+Selector combine_latest sample]\n"); 69 | auto o1 = rxcpp::observable<>::interval(std::chrono::milliseconds(2)); 70 | auto o2 = rxcpp::observable<>::interval(std::chrono::milliseconds(3)); 71 | auto o3 = rxcpp::observable<>::interval(std::chrono::milliseconds(5)); 72 | auto values = o1.combine_latest( 73 | rxcpp::observe_on_new_thread(), 74 | [](int v1, int v2, int v3) { 75 | return 100 * v1 + 10 * v2 + v3; 76 | }, 77 | o2, o3); 78 | values. 79 | take(5). 80 | as_blocking(). 81 | subscribe( 82 | [](int v){printf("OnNext: %d\n", v);}, 83 | [](){printf("OnCompleted\n");}); 84 | printf("//! [Coordination+Selector combine_latest sample]\n"); 85 | } 86 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/composite_exception.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | namespace rxu=rxcpp::util; 3 | 4 | #include "rxcpp/rx-test.hpp" 5 | #include "catch.hpp" 6 | 7 | #if RXCPP_USE_EXCEPTIONS 8 | SCENARIO("composite_exception sample"){ 9 | printf("//! [composite_exception sample]\n"); 10 | auto o1 = rxcpp::observable<>::error(std::runtime_error("Error from source o1\n")); 11 | auto o2 = rxcpp::observable<>::error(std::runtime_error("Error from source o2\n")); 12 | auto o3 = rxcpp::observable<>::timer(std::chrono::milliseconds(5)).map([](int) {return 3;}); 13 | auto values = o1.merge_delay_error(o2, o3); 14 | values. 15 | subscribe( 16 | [](int v){printf("OnNext: %d\n", v);}, 17 | [](std::exception_ptr composite_e) { 18 | printf("OnError %s\n", rxu::what(composite_e).c_str()); 19 | try { std::rethrow_exception(composite_e); } 20 | catch(rxcpp::composite_exception const &ce) { 21 | for(std::exception_ptr particular_e : ce.exceptions) { 22 | 23 | try{ std::rethrow_exception(particular_e); } 24 | catch(std::runtime_error const &error) { printf(" *** %s\n", error.what()); } 25 | 26 | } 27 | } 28 | }, 29 | [](){printf("OnCompleted\n");} 30 | ); 31 | printf("//! [composite_exception sample]\n"); 32 | } 33 | #endif 34 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/concat.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("concat sample"){ 7 | printf("//! [concat sample]\n"); 8 | auto o1 = rxcpp::observable<>::range(1, 3); 9 | auto o2 = rxcpp::observable<>::just(4); 10 | auto o3 = rxcpp::observable<>::from(5, 6); 11 | auto values = o1.concat(o2, o3); 12 | values. 13 | subscribe( 14 | [](int v){printf("OnNext: %d\n", v);}, 15 | [](){printf("OnCompleted\n");}); 16 | printf("//! [concat sample]\n"); 17 | } 18 | 19 | SCENARIO("implicit concat sample"){ 20 | printf("//! [implicit concat sample]\n"); 21 | auto o1 = rxcpp::observable<>::range(1, 3); 22 | auto o2 = rxcpp::observable<>::just(4); 23 | auto o3 = rxcpp::observable<>::from(5, 6); 24 | auto base = rxcpp::observable<>::from(o1.as_dynamic(), o2, o3); 25 | auto values = base.concat(); 26 | values. 27 | subscribe( 28 | [](int v){printf("OnNext: %d\n", v);}, 29 | [](){printf("OnCompleted\n");}); 30 | printf("//! [implicit concat sample]\n"); 31 | } 32 | 33 | SCENARIO("threaded concat sample"){ 34 | printf("//! [threaded concat sample]\n"); 35 | auto o1 = rxcpp::observable<>::range(1, 3); 36 | auto o2 = rxcpp::observable<>::just(4); 37 | auto o3 = rxcpp::observable<>::from(5, 6); 38 | auto values = o1.concat(rxcpp::observe_on_new_thread(), o2, o3); 39 | values. 40 | as_blocking(). 41 | subscribe( 42 | [](int v){printf("OnNext: %d\n", v);}, 43 | [](){printf("OnCompleted\n");}); 44 | printf("//! [threaded concat sample]\n"); 45 | } 46 | 47 | SCENARIO("threaded implicit concat sample"){ 48 | printf("//! [threaded implicit concat sample]\n"); 49 | auto o1 = rxcpp::observable<>::range(1, 3); 50 | auto o2 = rxcpp::observable<>::just(4); 51 | auto o3 = rxcpp::observable<>::from(5, 6); 52 | auto base = rxcpp::observable<>::from(o1.as_dynamic(), o2, o3); 53 | auto values = base.concat(rxcpp::observe_on_new_thread()); 54 | values. 55 | as_blocking(). 56 | subscribe( 57 | [](int v){printf("OnNext: %d\n", v);}, 58 | [](){printf("OnCompleted\n");}); 59 | printf("//! [threaded implicit concat sample]\n"); 60 | } 61 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/concat_map.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("concat_map sample"){ 7 | printf("//! [concat_map sample]\n"); 8 | auto values = rxcpp::observable<>::range(1, 3). 9 | concat_map( 10 | [](int v){ 11 | return 12 | rxcpp::observable<>::interval(std::chrono::steady_clock::now() + std::chrono::milliseconds(10 * v), std::chrono::milliseconds(50)). 13 | take(3); 14 | }, 15 | [](int v_main, long v_sub){ 16 | return std::make_tuple(v_main, v_sub); 17 | }); 18 | values. 19 | subscribe( 20 | [](std::tuple v){printf("OnNext: %d - %ld\n", std::get<0>(v), std::get<1>(v));}, 21 | [](){printf("OnCompleted\n");}); 22 | printf("//! [concat_map sample]\n"); 23 | } 24 | 25 | #include "main.hpp" 26 | 27 | SCENARIO("threaded concat_map sample"){ 28 | printf("//! [threaded concat_map sample]\n"); 29 | printf("[thread %s] Start task\n", get_pid().c_str()); 30 | auto values = rxcpp::observable<>::range(1, 3). 31 | concat_map( 32 | [](int v){ 33 | printf("[thread %s] Call CollectionSelector(v = %d)\n", get_pid().c_str(), v); 34 | return 35 | rxcpp::observable<>::interval(std::chrono::steady_clock::now() + std::chrono::milliseconds(10 * v), std::chrono::milliseconds(50)). 36 | take(3); 37 | }, 38 | [](int v_main, long v_sub){ 39 | printf("[thread %s] Call ResultSelector(v_main = %d, v_sub = %ld)\n", get_pid().c_str(), v_main, v_sub); 40 | return std::make_tuple(v_main, v_sub); 41 | }, 42 | rxcpp::observe_on_new_thread()); 43 | values. 44 | as_blocking(). 45 | subscribe( 46 | [](std::tuple v){printf("[thread %s] OnNext: %d - %ld\n", get_pid().c_str(), std::get<0>(v), std::get<1>(v));}, 47 | [](){printf("[thread %s] OnCompleted\n", get_pid().c_str());}); 48 | printf("[thread %s] Finish task\n", get_pid().c_str()); 49 | printf("//! [threaded concat_map sample]\n"); 50 | } 51 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/contains.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("contains sample") { 7 | printf("//! [contains sample]\n"); 8 | auto values = rxcpp::observable<>::from(1, 2, 3, 4, 5).contains(3); 9 | values. 10 | subscribe( 11 | [](bool v) { printf("OnNext: %s\n", v ? "true" : "false"); }, 12 | []() { printf("OnCompleted\n"); }); 13 | printf("//! [contains sample]\n"); 14 | } 15 | 16 | SCENARIO("contains - operator syntax sample") { 17 | using namespace rxcpp; 18 | using namespace rxcpp::sources; 19 | using namespace rxcpp::operators; 20 | 21 | printf("//! [contains - operator syntax sample]\n"); 22 | auto values = range(1, 10) 23 | | contains(2); 24 | values. 25 | subscribe( 26 | [](bool v) { printf("OnNext: %s\n", v ? "true" : "false"); }, 27 | []() { printf("OnCompleted\n"); }); 28 | printf("//! [contains - operator syntax sample]\n"); 29 | } -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/create.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("Create sample"){ 7 | printf("//! [Create sample]\n"); 8 | auto ints = rxcpp::observable<>::create( 9 | [](rxcpp::subscriber s){ 10 | s.on_next(1); 11 | s.on_next(2); 12 | s.on_completed(); 13 | }); 14 | 15 | ints. 16 | subscribe( 17 | [](int v){printf("OnNext: %d\n", v);}, 18 | [](){printf("OnCompleted\n");}); 19 | printf("//! [Create sample]\n"); 20 | } 21 | 22 | SCENARIO("Create bad code"){ 23 | printf("//! [Create bad code]\n"); 24 | auto subscription = rxcpp::composite_subscription(); 25 | auto subscriber = rxcpp::make_subscriber( 26 | subscription, 27 | [&](int v){ 28 | printf("OnNext: %d\n", v); 29 | if (v == 2) 30 | subscription.unsubscribe(); 31 | }, 32 | [](){ 33 | printf("OnCompleted\n"); 34 | }); 35 | rxcpp::observable<>::create( 36 | [](rxcpp::subscriber s){ 37 | for (int i = 0; i < 5; ++i) { 38 | s.on_next(i); 39 | printf("Just sent: OnNext(%d)\n", i); 40 | } 41 | s.on_completed(); 42 | printf("Just sent: OnCompleted()\n"); 43 | }).subscribe(subscriber); 44 | printf("//! [Create bad code]\n"); 45 | } 46 | 47 | SCENARIO("Create good code"){ 48 | printf("//! [Create good code]\n"); 49 | auto subscription = rxcpp::composite_subscription(); 50 | auto subscriber = rxcpp::make_subscriber( 51 | subscription, 52 | [&](int v){ 53 | printf("OnNext: %d\n", v); 54 | if (v == 2) 55 | subscription.unsubscribe(); 56 | }, 57 | [](){ 58 | printf("OnCompleted\n"); 59 | }); 60 | rxcpp::observable<>::create( 61 | [](rxcpp::subscriber s){ 62 | for (int i = 0; i < 5; ++i) { 63 | if (!s.is_subscribed()) // Stop emitting if nobody is listening 64 | break; 65 | s.on_next(i); 66 | printf("Just sent: OnNext(%d)\n", i); 67 | } 68 | s.on_completed(); 69 | printf("Just sent: OnCompleted()\n"); 70 | }).subscribe(subscriber); 71 | printf("//! [Create good code]\n"); 72 | } 73 | 74 | SCENARIO("Create great code"){ 75 | printf("//! [Create great code]\n"); 76 | auto ints = rxcpp::observable<>::create( 77 | [](rxcpp::subscriber s){ 78 | for (int i = 0; i < 5; ++i) { 79 | if (!s.is_subscribed()) // Stop emitting if nobody is listening 80 | break; 81 | s.on_next(i); 82 | printf("Just sent: OnNext(%d)\n", i); 83 | } 84 | s.on_completed(); 85 | printf("Just sent: OnCompleted()\n"); 86 | }); 87 | ints. 88 | take(2). 89 | subscribe( 90 | [](int v){ 91 | printf("OnNext: %d\n", v); 92 | }, 93 | [](rxcpp::util::error_ptr ep){ 94 | printf("OnError: %s\n", rxcpp::util::what(ep).c_str()); 95 | }, 96 | [](){ 97 | printf("OnCompleted\n"); 98 | }); 99 | printf("//! [Create great code]\n"); 100 | } 101 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/debounce.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("debounce sample"){ 7 | printf("//! [debounce sample]\n"); 8 | using namespace std::chrono; 9 | auto scheduler = rxcpp::identity_current_thread(); 10 | auto start = scheduler.now(); 11 | auto period = milliseconds(10); 12 | auto values = rxcpp::observable<>::interval(start, period, scheduler). 13 | take(4). 14 | debounce(period); 15 | values. 16 | subscribe( 17 | [](long v) { printf("OnNext: %ld\n", v); }, 18 | []() { printf("OnCompleted\n"); }); 19 | printf("//! [debounce sample]\n"); 20 | } -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/default_if_empty.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("default_if_empty sample"){ 7 | printf("//! [default_if_empty sample]\n"); 8 | 9 | auto values = rxcpp::observable<>::empty() 10 | .default_if_empty(42); 11 | 12 | values.subscribe( 13 | [](int v) { printf("OnNext: %d\n", v); }, 14 | []() { printf("OnCompleted\n"); } ); 15 | 16 | printf("//! [default_if_empty sample]\n"); 17 | } 18 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/defer.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("defer sample"){ 7 | printf("//! [defer sample]\n"); 8 | auto observable_factory = [](){return rxcpp::observable<>::range(1, 3);}; 9 | auto values = rxcpp::observable<>::defer(observable_factory); 10 | values. 11 | subscribe( 12 | [](int v){printf("OnNext: %d\n", v);}, 13 | [](){printf("OnCompleted\n");}); 14 | printf("//! [defer sample]\n"); 15 | } 16 | 17 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/delay.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("delay period+coordination sample"){ 7 | printf("//! [delay period+coordination sample]\n"); 8 | using namespace std::chrono; 9 | auto scheduler = rxcpp::identity_current_thread(); 10 | auto start = scheduler.now(); 11 | auto period = milliseconds(10); 12 | const auto next = [=](const char* s) { 13 | return [=](long v){ 14 | auto t = duration_cast(scheduler.now() - start); 15 | long long int ms = t.count(); 16 | printf("[%s @ %lld] OnNext: %ld\n", s, ms, v); 17 | }; 18 | }; 19 | auto values = rxcpp::observable<>::interval(start, period, scheduler). 20 | take(4). 21 | tap(next("interval")). 22 | delay(period, rxcpp::observe_on_new_thread()); 23 | values. 24 | as_blocking(). 25 | subscribe( 26 | next(" delayed"), 27 | [](){printf("OnCompleted\n");}); 28 | printf("//! [delay period+coordination sample]\n"); 29 | } 30 | 31 | SCENARIO("delay period sample"){ 32 | printf("//! [delay period sample]\n"); 33 | using namespace std::chrono; 34 | auto scheduler = rxcpp::identity_current_thread(); 35 | auto start = scheduler.now(); 36 | auto period = milliseconds(10); 37 | const auto next = [=](const char* s) { 38 | return [=](long v){ 39 | auto t = duration_cast(scheduler.now() - start); 40 | long long int ms = t.count(); 41 | printf("[%s @ %lld] OnNext: %ld\n", s, ms, v); 42 | }; 43 | }; 44 | auto values = rxcpp::observable<>::interval(start, period, scheduler). 45 | take(4). 46 | tap(next("interval")). 47 | delay(period); 48 | values. 49 | subscribe( 50 | next(" delayed"), 51 | [](){printf("OnCompleted\n");}); 52 | printf("//! [delay period sample]\n"); 53 | } 54 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/distinct.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("distinct sample"){ 7 | printf("//! [distinct sample]\n"); 8 | auto values = rxcpp::observable<>::from(1, 2, 2, 3, 3, 3, 4, 5, 5).distinct(); 9 | values. 10 | subscribe( 11 | [](int v){printf("OnNext: %d\n", v);}, 12 | [](){printf("OnCompleted\n");}); 13 | printf("//! [distinct sample]\n"); 14 | } 15 | 16 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/distinct_until_changed.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("distinct_until_changed sample"){ 7 | printf("//! [distinct_until_changed sample]\n"); 8 | auto values = rxcpp::observable<>::from(1, 2, 2, 3, 3, 3, 4, 5, 5).distinct_until_changed(); 9 | values. 10 | subscribe( 11 | [](int v){printf("OnNext: %d\n", v);}, 12 | [](){printf("OnCompleted\n");}); 13 | printf("//! [distinct_until_changed sample]\n"); 14 | } 15 | 16 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/element_at.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("element_at sample"){ 7 | printf("//! [element_at sample]\n"); 8 | auto values = rxcpp::observable<>::range(1, 7).element_at(3); 9 | values. 10 | subscribe( 11 | [](int v){printf("OnNext: %d\n", v);}, 12 | [](){printf("OnCompleted\n");}); 13 | printf("//! [element_at sample]\n"); 14 | } 15 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/empty.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("empty sample"){ 7 | printf("//! [empty sample]\n"); 8 | auto values = rxcpp::observable<>::empty(); 9 | values. 10 | subscribe( 11 | [](int v){printf("OnNext: %d\n", v);}, 12 | [](){printf("OnCompleted\n");}); 13 | printf("//! [empty sample]\n"); 14 | } 15 | 16 | SCENARIO("threaded empty sample"){ 17 | printf("//! [threaded empty sample]\n"); 18 | auto values = rxcpp::observable<>::empty(rxcpp::observe_on_event_loop()); 19 | values. 20 | as_blocking(). 21 | subscribe( 22 | [](int v){printf("OnNext: %d\n", v);}, 23 | [](){printf("OnCompleted\n");}); 24 | printf("//! [threaded empty sample]\n"); 25 | } 26 | 27 | SCENARIO("empty operator syntax sample"){ 28 | using namespace rxcpp::sources; 29 | 30 | printf("//! [empty operator syntax sample]\n"); 31 | auto values = empty(); 32 | values. 33 | subscribe( 34 | [](int v){printf("OnNext: %d\n", v);}, 35 | [](){printf("OnCompleted\n");}); 36 | printf("//! [empty operator syntax sample]\n"); 37 | } 38 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/error.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("error sample"){ 7 | printf("//! [error sample]\n"); 8 | auto values = rxcpp::observable<>::error(std::runtime_error("Error from source")); 9 | values. 10 | subscribe( 11 | [](int v){printf("OnNext: %d\n", v);}, 12 | [](rxcpp::util::error_ptr ep){ 13 | printf("OnError: %s\n", rxcpp::util::what(ep).c_str()); 14 | }, 15 | [](){printf("OnCompleted\n");}); 16 | printf("//! [error sample]\n"); 17 | } 18 | 19 | SCENARIO("threaded error sample"){ 20 | printf("//! [threaded error sample]\n"); 21 | auto values = rxcpp::observable<>::error(std::runtime_error("Error from source"), rxcpp::observe_on_event_loop()); 22 | values. 23 | as_blocking(). 24 | subscribe( 25 | [](int v){printf("OnNext: %d\n", v);}, 26 | [](rxcpp::util::error_ptr ep){ 27 | printf("OnError: %s\n", rxcpp::util::what(ep).c_str()); 28 | }, 29 | [](){printf("OnCompleted\n");}); 30 | printf("//! [threaded error sample]\n"); 31 | } 32 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/exists.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("exists sample") { 7 | printf("//! [exists sample]\n"); 8 | auto values = rxcpp::observable<>::from(1, 2, 3, 4, 5).exists([](int n) { return n > 3; }); 9 | values. 10 | subscribe( 11 | [](bool v) { printf("OnNext: %s\n", v ? "true" : "false"); }, 12 | []() { printf("OnCompleted\n"); }); 13 | printf("//! [exists sample]\n"); 14 | } 15 | 16 | SCENARIO("exists - operator syntax sample") { 17 | using namespace rxcpp; 18 | using namespace rxcpp::sources; 19 | using namespace rxcpp::operators; 20 | 21 | printf("//! [exists - operator syntax sample]\n"); 22 | auto values = range(1, 10) 23 | | exists([](int n) { return n == 1; }); 24 | values. 25 | subscribe( 26 | [](bool v) { printf("OnNext: %s\n", v ? "true" : "false"); }, 27 | []() { printf("OnCompleted\n"); }); 28 | printf("//! [exists - operator syntax sample]\n"); 29 | } -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/filter.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("filter sample"){ 7 | printf("//! [filter sample]\n"); 8 | auto values = rxcpp::observable<>::range(1, 6). 9 | filter([](int v){ 10 | return v % 2; 11 | }); 12 | values. 13 | subscribe( 14 | [](int v){printf("OnNext: %d\n", v);}, 15 | [](){printf("OnCompleted\n");}); 16 | printf("//! [filter sample]\n"); 17 | } 18 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/finally.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("finally sample"){ 7 | printf("//! [finally sample]\n"); 8 | auto values = rxcpp::observable<>::range(1, 3). 9 | finally([](){ 10 | printf("The final action\n"); 11 | }); 12 | values. 13 | subscribe( 14 | [](int v){printf("OnNext: %d\n", v);}, 15 | [](){printf("OnCompleted\n");}); 16 | printf("//! [finally sample]\n"); 17 | } 18 | 19 | SCENARIO("error finally sample"){ 20 | printf("//! [error finally sample]\n"); 21 | auto values = rxcpp::observable<>::range(1, 3). 22 | concat(rxcpp::observable<>::error(std::runtime_error("Error from source"))). 23 | finally([](){ 24 | printf("The final action\n"); 25 | }); 26 | values. 27 | subscribe( 28 | [](int v){printf("OnNext: %d\n", v);}, 29 | [](rxcpp::util::error_ptr ep){ 30 | printf("OnError: %s\n", rxcpp::util::what(ep).c_str()); 31 | }, 32 | [](){printf("OnCompleted\n");}); 33 | printf("//! [error finally sample]\n"); 34 | } 35 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/flat_map.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("flat_map sample"){ 7 | printf("//! [flat_map sample]\n"); 8 | auto values = rxcpp::observable<>::range(1, 3). 9 | flat_map( 10 | [](int v){ 11 | return 12 | rxcpp::observable<>::interval(std::chrono::steady_clock::now() + std::chrono::milliseconds(10 * v), std::chrono::milliseconds(50)). 13 | take(3); 14 | }, 15 | [](int v_main, long v_sub){ 16 | return std::make_tuple(v_main, v_sub); 17 | }); 18 | values. 19 | subscribe( 20 | [](std::tuple v){printf("OnNext: %d - %ld\n", std::get<0>(v), std::get<1>(v));}, 21 | [](){printf("OnCompleted\n");}); 22 | printf("//! [flat_map sample]\n"); 23 | } 24 | 25 | #include "main.hpp" 26 | 27 | SCENARIO("threaded flat_map sample"){ 28 | printf("//! [threaded flat_map sample]\n"); 29 | printf("[thread %s] Start task\n", get_pid().c_str()); 30 | auto values = rxcpp::observable<>::range(1, 3). 31 | flat_map( 32 | [](int v){ 33 | printf("[thread %s] Call CollectionSelector(v = %d)\n", get_pid().c_str(), v); 34 | return 35 | rxcpp::observable<>::interval(std::chrono::steady_clock::now() + std::chrono::milliseconds(10 * v), std::chrono::milliseconds(50)). 36 | take(3); 37 | }, 38 | [](int v_main, int v_sub){ 39 | printf("[thread %s] Call ResultSelector(v_main = %d, v_sub = %d)\n", get_pid().c_str(), v_main, v_sub); 40 | return std::make_tuple(v_main, v_sub); 41 | }, 42 | rxcpp::observe_on_new_thread()); 43 | values. 44 | as_blocking(). 45 | subscribe( 46 | [](std::tuple v){printf("[thread %s] OnNext: %d - %ld\n", get_pid().c_str(), std::get<0>(v), std::get<1>(v));}, 47 | [](){printf("[thread %s] OnCompleted\n", get_pid().c_str());}); 48 | printf("[thread %s] Finish task\n", get_pid().c_str()); 49 | printf("//! [threaded flat_map sample]\n"); 50 | } 51 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/from.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("from sample"){ 7 | printf("//! [from sample]\n"); 8 | auto values = rxcpp::observable<>::from(1, 2, 3); 9 | values. 10 | subscribe( 11 | [](int v){printf("OnNext: %d\n", v);}, 12 | [](){printf("OnCompleted\n");}); 13 | printf("//! [from sample]\n"); 14 | } 15 | 16 | #include "main.hpp" 17 | 18 | SCENARIO("threaded from sample"){ 19 | printf("//! [threaded from sample]\n"); 20 | printf("[thread %s] Start task\n", get_pid().c_str()); 21 | auto values = rxcpp::observable<>::from(rxcpp::observe_on_new_thread(), 1, 2, 3).map([](int v){ 22 | printf("[thread %s] Emit value: %d\n", get_pid().c_str(), v); 23 | return v; 24 | }); 25 | values. 26 | as_blocking(). 27 | subscribe( 28 | [](int v){printf("[thread %s] OnNext: %d\n", get_pid().c_str(), v);}, 29 | [](){printf("[thread %s] OnCompleted\n", get_pid().c_str());}); 30 | printf("[thread %s] Finish task\n", get_pid().c_str()); 31 | printf("//! [threaded from sample]\n"); 32 | } 33 | 34 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/group_by.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | #include 7 | 8 | SCENARIO("group_by sample"){ 9 | printf("//! [group_by sample]\n"); 10 | auto values = rxcpp::observable<>::range(0, 8). 11 | group_by( 12 | [](int v){return v % 3;}, 13 | [](int v){return 10 * v;}); 14 | values. 15 | subscribe( 16 | [](rxcpp::grouped_observable g){ 17 | auto key = g.get_key(); 18 | printf("OnNext: key = %d\n", key); 19 | g.subscribe( 20 | [key](int v){printf("[key %d] OnNext: %d\n", key, v);}, 21 | [key](){printf("[key %d] OnCompleted\n", key);}); 22 | }, 23 | [](){printf("OnCompleted\n");}); 24 | printf("//! [group_by sample]\n"); 25 | } 26 | 27 | //! [group_by full intro] 28 | static bool less(int v1, int v2){ 29 | return v1 < v2; 30 | } 31 | //! [group_by full intro] 32 | 33 | SCENARIO("group_by full sample"){ 34 | printf("//! [group_by full sample]\n"); 35 | auto data = rxcpp::observable<>::range(0, 8). 36 | map([](int v){ 37 | std::stringstream s; 38 | s << "Value " << v; 39 | return std::make_pair(v % 3, s.str()); 40 | }); 41 | auto values = data.group_by( 42 | [](std::pair v){return v.first;}, 43 | [](std::pair v){return v.second;}, 44 | less); 45 | values. 46 | subscribe( 47 | [](rxcpp::grouped_observable g){ 48 | auto key = g.get_key(); 49 | printf("OnNext: key = %d\n", key); 50 | g.subscribe( 51 | [key](const std::string& v){printf("[key %d] OnNext: %s\n", key, v.c_str());}, 52 | [key](){printf("[key %d] OnCompleted\n", key);}); 53 | }, 54 | [](){printf("OnCompleted\n");}); 55 | printf("//! [group_by full sample]\n"); 56 | } 57 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/ignore_elements.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("ignore_elements sample"){ 7 | printf("//! [ignore_elements sample]\n"); 8 | auto values = rxcpp::observable<>::from(1, 2, 3, 4, 5).ignore_elements(); 9 | values. 10 | subscribe( 11 | [](int v) { printf("OnNext: %d\n", v); }, 12 | []() { printf("OnCompleted\n"); }); 13 | printf("//! [ignore_elements sample]\n"); 14 | } 15 | 16 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/interval.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("immediate interval sample"){ 7 | printf("//! [immediate interval sample]\n"); 8 | auto period = std::chrono::milliseconds(1); 9 | auto values = rxcpp::observable<>::interval(period); 10 | values. 11 | take(3). 12 | subscribe( 13 | [](int v){printf("OnNext: %d\n", v);}, 14 | [](){printf("OnCompleted\n");}); 15 | printf("//! [immediate interval sample]\n"); 16 | } 17 | 18 | SCENARIO("threaded immediate interval sample"){ 19 | printf("//! [threaded immediate interval sample]\n"); 20 | auto scheduler = rxcpp::identity_current_thread(); 21 | auto period = std::chrono::milliseconds(1); 22 | auto values = rxcpp::observable<>::interval(period, scheduler); 23 | values. 24 | take(3). 25 | subscribe( 26 | [](int v){printf("OnNext: %d\n", v);}, 27 | [](){printf("OnCompleted\n");}); 28 | printf("//! [threaded immediate interval sample]\n"); 29 | } 30 | 31 | SCENARIO("interval sample"){ 32 | printf("//! [interval sample]\n"); 33 | auto start = std::chrono::steady_clock::now() + std::chrono::milliseconds(1); 34 | auto period = std::chrono::milliseconds(1); 35 | auto values = rxcpp::observable<>::interval(start, period); 36 | values. 37 | take(3). 38 | subscribe( 39 | [](int v){printf("OnNext: %d\n", v);}, 40 | [](){printf("OnCompleted\n");}); 41 | printf("//! [interval sample]\n"); 42 | } 43 | 44 | SCENARIO("threaded interval sample"){ 45 | printf("//! [threaded interval sample]\n"); 46 | auto scheduler = rxcpp::identity_current_thread(); 47 | auto start = scheduler.now() + std::chrono::milliseconds(1); 48 | auto period = std::chrono::milliseconds(1); 49 | auto values = rxcpp::observable<>::interval(start, period, scheduler); 50 | values. 51 | take(3). 52 | subscribe( 53 | [](int v){printf("OnNext: %d\n", v);}, 54 | [](){printf("OnCompleted\n");}); 55 | printf("//! [threaded interval sample]\n"); 56 | } 57 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/is_empty.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("is_empty sample") { 7 | printf("//! [is_empty sample]\n"); 8 | auto values = rxcpp::observable<>::from(1, 2, 3, 4, 5).is_empty(); 9 | values. 10 | subscribe( 11 | [](bool v) { printf("OnNext: %s\n", v ? "true" : "false"); }, 12 | []() { printf("OnCompleted\n"); }); 13 | printf("//! [is_empty sample]\n"); 14 | } 15 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/iterate.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("iterate sample"){ 7 | printf("//! [iterate sample]\n"); 8 | std::array< int, 3 > a={{1, 2, 3}}; 9 | auto values = rxcpp::observable<>::iterate(a); 10 | values. 11 | subscribe( 12 | [](int v){printf("OnNext: %d\n", v);}, 13 | [](){printf("OnCompleted\n");}); 14 | printf("//! [iterate sample]\n"); 15 | } 16 | 17 | SCENARIO("threaded iterate sample"){ 18 | printf("//! [threaded iterate sample]\n"); 19 | std::array< int, 3 > a={{1, 2, 3}}; 20 | auto values = rxcpp::observable<>::iterate(a, rxcpp::observe_on_event_loop()); 21 | values. 22 | as_blocking(). 23 | subscribe( 24 | [](int v){printf("OnNext: %d\n", v);}, 25 | [](){printf("OnCompleted\n");}); 26 | printf("//! [threaded iterate sample]\n"); 27 | } 28 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/just.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("just sample"){ 7 | printf("//! [just sample]\n"); 8 | auto values = rxcpp::observable<>::just(1); 9 | values. 10 | subscribe( 11 | [](int v){printf("OnNext: %d\n", v);}, 12 | [](){printf("OnCompleted\n");}); 13 | printf("//! [just sample]\n"); 14 | } 15 | 16 | SCENARIO("threaded just sample"){ 17 | printf("//! [threaded just sample]\n"); 18 | auto values = rxcpp::observable<>::just(1, rxcpp::observe_on_event_loop()); 19 | values. 20 | as_blocking(). 21 | subscribe( 22 | [](int v){printf("OnNext: %d\n", v);}, 23 | [](){printf("OnCompleted\n");}); 24 | printf("//! [threaded just sample]\n"); 25 | } 26 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/main.cpp: -------------------------------------------------------------------------------- 1 | #define CATCH_CONFIG_MAIN 2 | #include "catch.hpp" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "main.hpp" 9 | 10 | std::string get_pid() { 11 | std::stringstream s; 12 | s << std::this_thread::get_id(); 13 | return s.str(); 14 | } 15 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/main.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | std::string get_pid(); 4 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/map.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("map sample"){ 7 | printf("//! [map sample]\n"); 8 | auto values = rxcpp::observable<>::range(1, 3). 9 | map([](int v){ 10 | return 2 * v; 11 | }); 12 | values. 13 | subscribe( 14 | [](int v){printf("OnNext: %d\n", v);}, 15 | [](){printf("OnCompleted\n");}); 16 | printf("//! [map sample]\n"); 17 | } 18 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/merge.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("merge sample"){ 7 | printf("//! [merge sample]\n"); 8 | auto o1 = rxcpp::observable<>::timer(std::chrono::milliseconds(15)).map([](int) {return 1;}); 9 | auto o2 = rxcpp::observable<>::timer(std::chrono::milliseconds(10)).map([](int) {return 2;}); 10 | auto o3 = rxcpp::observable<>::timer(std::chrono::milliseconds(5)).map([](int) {return 3;}); 11 | auto values = o1.merge(o2, o3); 12 | values. 13 | subscribe( 14 | [](int v){printf("OnNext: %d\n", v);}, 15 | [](){printf("OnCompleted\n");}); 16 | printf("//! [merge sample]\n"); 17 | } 18 | 19 | SCENARIO("implicit merge sample"){ 20 | printf("//! [implicit merge sample]\n"); 21 | auto o1 = rxcpp::observable<>::timer(std::chrono::milliseconds(15)).map([](int) {return 1;}); 22 | auto o2 = rxcpp::observable<>::timer(std::chrono::milliseconds(10)).map([](int) {return 2;}); 23 | auto o3 = rxcpp::observable<>::timer(std::chrono::milliseconds(5)).map([](int) {return 3;}); 24 | auto base = rxcpp::observable<>::from(o1.as_dynamic(), o2, o3); 25 | auto values = base.merge(); 26 | values. 27 | subscribe( 28 | [](int v){printf("OnNext: %d\n", v);}, 29 | [](){printf("OnCompleted\n");}); 30 | printf("//! [implicit merge sample]\n"); 31 | } 32 | 33 | #include "main.hpp" 34 | 35 | SCENARIO("threaded merge sample"){ 36 | printf("//! [threaded merge sample]\n"); 37 | printf("[thread %s] Start task\n", get_pid().c_str()); 38 | auto o1 = rxcpp::observable<>::timer(std::chrono::milliseconds(10)).map([](int) { 39 | printf("[thread %s] Timer1 fired\n", get_pid().c_str()); 40 | return 1; 41 | }); 42 | auto o2 = rxcpp::observable<>::timer(std::chrono::milliseconds(20)).map([](int) { 43 | printf("[thread %s] Timer2 fired\n", get_pid().c_str()); 44 | return 2; 45 | }); 46 | auto o3 = rxcpp::observable<>::timer(std::chrono::milliseconds(30)).map([](int) { 47 | printf("[thread %s] Timer3 fired\n", get_pid().c_str()); 48 | return 3; 49 | }); 50 | auto values = o1.merge(rxcpp::observe_on_new_thread(), o2, o3); 51 | values. 52 | as_blocking(). 53 | subscribe( 54 | [](int v){printf("[thread %s] OnNext: %d\n", get_pid().c_str(), v);}, 55 | [](){printf("[thread %s] OnCompleted\n", get_pid().c_str());}); 56 | printf("[thread %s] Finish task\n", get_pid().c_str()); 57 | printf("//! [threaded merge sample]\n"); 58 | } 59 | 60 | SCENARIO("threaded implicit merge sample"){ 61 | printf("//! [threaded implicit merge sample]\n"); 62 | printf("[thread %s] Start task\n", get_pid().c_str()); 63 | auto o1 = rxcpp::observable<>::timer(std::chrono::milliseconds(10)).map([](int) { 64 | printf("[thread %s] Timer1 fired\n", get_pid().c_str()); 65 | return 1; 66 | }); 67 | auto o2 = rxcpp::observable<>::timer(std::chrono::milliseconds(20)).map([](int) { 68 | printf("[thread %s] Timer2 fired\n", get_pid().c_str()); 69 | return 2; 70 | }); 71 | auto o3 = rxcpp::observable<>::timer(std::chrono::milliseconds(30)).map([](int) { 72 | printf("[thread %s] Timer3 fired\n", get_pid().c_str()); 73 | return 3; 74 | }); 75 | auto base = rxcpp::observable<>::from(o1.as_dynamic(), o2, o3); 76 | auto values = base.merge(rxcpp::observe_on_new_thread()); 77 | values. 78 | as_blocking(). 79 | subscribe( 80 | [](int v){printf("[thread %s] OnNext: %d\n", get_pid().c_str(), v);}, 81 | [](){printf("[thread %s] OnCompleted\n", get_pid().c_str());}); 82 | printf("[thread %s] Finish task\n", get_pid().c_str()); 83 | printf("//! [threaded implicit merge sample]\n"); 84 | } 85 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/never.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("never sample"){ 7 | printf("//! [never sample]\n"); 8 | auto values = rxcpp::observable<>::never(); 9 | values. 10 | take_until(std::chrono::steady_clock::now() + std::chrono::milliseconds(10)). 11 | subscribe( 12 | [](int v){printf("OnNext: %d\n", v);}, 13 | [](){printf("OnCompleted\n");}); 14 | printf("//! [never sample]\n"); 15 | } 16 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/observe_on.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | #include "main.hpp" 7 | 8 | SCENARIO("observe_on sample"){ 9 | printf("//! [observe_on sample]\n"); 10 | printf("[thread %s] Start task\n", get_pid().c_str()); 11 | auto values = rxcpp::observable<>::range(1, 3). 12 | map([](int v){ 13 | printf("[thread %s] Emit value %d\n", get_pid().c_str(), v); 14 | return v; 15 | }); 16 | values. 17 | observe_on(rxcpp::synchronize_new_thread()). 18 | as_blocking(). 19 | subscribe( 20 | [](int v){printf("[thread %s] OnNext: %d\n", get_pid().c_str(), v);}, 21 | [](){printf("[thread %s] OnCompleted\n", get_pid().c_str());}); 22 | printf("[thread %s] Finish task\n", get_pid().c_str()); 23 | printf("//! [observe_on sample]\n"); 24 | } 25 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/on_error_resume_next.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | namespace rxu=rxcpp::util; 3 | 4 | #include "rxcpp/rx-test.hpp" 5 | #include "catch.hpp" 6 | 7 | SCENARIO("on_error_resume_next sample"){ 8 | printf("//! [on_error_resume_next sample]\n"); 9 | auto values = rxcpp::observable<>::range(1, 3). 10 | concat(rxcpp::observable<>::error(std::runtime_error("Error from source"))). 11 | on_error_resume_next([](std::exception_ptr ep){ 12 | printf("Resuming after: %s\n", rxu::what(ep).c_str()); 13 | return rxcpp::observable<>::just(-1); 14 | }); 15 | values. 16 | subscribe( 17 | [](int v){printf("OnNext: %d\n", v);}, 18 | [](std::exception_ptr ep){ 19 | printf("OnError: %s\n", rxu::what(ep).c_str()); 20 | }, 21 | [](){printf("OnCompleted\n");}); 22 | printf("//! [on_error_resume_next sample]\n"); 23 | } 24 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/pairwise.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("pairwise sample"){ 7 | printf("//! [pairwise sample]\n"); 8 | auto values = rxcpp::observable<>::range(1, 5).pairwise(); 9 | values. 10 | subscribe( 11 | [](std::tuple v){printf("OnNext: %d, %d\n", std::get<0>(v), std::get<1>(v));}, 12 | [](){printf("OnCompleted\n");}); 13 | printf("//! [pairwise sample]\n"); 14 | } 15 | 16 | SCENARIO("pairwise short sample"){ 17 | printf("//! [pairwise short sample]\n"); 18 | auto values = rxcpp::observable<>::just(1).pairwise(); 19 | values. 20 | subscribe( 21 | [](std::tuple v){printf("OnNext: %d, %d\n", std::get<0>(v), std::get<1>(v));}, 22 | [](){printf("OnCompleted\n");}); 23 | printf("//! [pairwise short sample]\n"); 24 | } 25 | 26 | //#include "main.hpp" 27 | // 28 | //SCENARIO("threaded flat_map sample"){ 29 | // printf("//! [threaded flat_map sample]\n"); 30 | // printf("[thread %s] Start task\n", get_pid().c_str()); 31 | // auto values = rxcpp::observable<>::range(1, 3). 32 | // flat_map( 33 | // [](int v){ 34 | // printf("[thread %s] Call CollectionSelector(v = %d)\n", get_pid().c_str(), v); 35 | // return 36 | // rxcpp::observable<>::interval(std::chrono::steady_clock::now() + std::chrono::milliseconds(10 * v), std::chrono::milliseconds(50)). 37 | // take(3); 38 | // }, 39 | // [](int v_main, int v_sub){ 40 | // printf("[thread %s] Call ResultSelector(v_main = %d, v_sub = %d)\n", get_pid().c_str(), v_main, v_sub); 41 | // return std::make_tuple(v_main, v_sub); 42 | // }, 43 | // rxcpp::observe_on_new_thread()); 44 | // values. 45 | // as_blocking(). 46 | // subscribe( 47 | // [](std::tuple v){printf("[thread %s] OnNext: %d - %d\n", get_pid().c_str(), std::get<0>(v), std::get<1>(v));}, 48 | // [](){printf("[thread %s] OnCompleted\n", get_pid().c_str());}); 49 | // printf("[thread %s] Finish task\n", get_pid().c_str()); 50 | // printf("//! [threaded flat_map sample]\n"); 51 | //} 52 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/reduce.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("reduce sample"){ 7 | printf("//! [reduce sample]\n"); 8 | auto values = rxcpp::observable<>::range(1, 7). 9 | reduce( 10 | std::make_pair(0, 1.0), 11 | [](std::pair seed, int v){ 12 | seed.first += 1; 13 | seed.second *= v; 14 | return seed; 15 | }, 16 | [](std::pair res){ 17 | return std::pow(res.second, 1.0 / res.first); 18 | }); 19 | values. 20 | subscribe( 21 | [](double v){printf("OnNext: %lf\n", v);}, 22 | [](){printf("OnCompleted\n");}); 23 | printf("//! [reduce sample]\n"); 24 | } 25 | 26 | SCENARIO("reduce empty sample"){ 27 | printf("//! [reduce empty sample]\n"); 28 | auto values = rxcpp::observable<>::empty(). 29 | reduce( 30 | 1, 31 | [](int,int){return 0;}, 32 | [](int res){return res;}); 33 | values. 34 | subscribe( 35 | [](int v){printf("OnNext: %d\n", v);}, 36 | [](){printf("OnCompleted\n");}); 37 | printf("//! [reduce empty sample]\n"); 38 | } 39 | 40 | SCENARIO("reduce exception from accumulator sample"){ 41 | printf("//! [reduce exception from accumulator sample]\n"); 42 | auto values = rxcpp::observable<>::range(1, 3). 43 | reduce( 44 | 0, 45 | [](int seed, int v){ 46 | if (v == 2) 47 | throw std::runtime_error("Exception from accumulator"); 48 | return seed; 49 | }, 50 | [](int res){return res;}); 51 | values. 52 | subscribe( 53 | [](int v){printf("OnNext: %d\n", v);}, 54 | [](std::exception_ptr ep){ 55 | try {std::rethrow_exception(ep);} 56 | catch (const std::exception& ex) { 57 | printf("OnError: %s\n", ex.what()); 58 | } 59 | }, 60 | [](){printf("OnCompleted\n");}); 61 | printf("//! [reduce exception from accumulator sample]\n"); 62 | } 63 | 64 | SCENARIO("reduce exception from result selector sample"){ 65 | printf("//! [reduce exception from result selector sample]\n"); 66 | auto values = rxcpp::observable<>::range(1, 3). 67 | reduce( 68 | 0, 69 | [](int seed, int v){return seed + v;}, 70 | [](int res){ 71 | throw std::runtime_error("Exception from result selector"); 72 | return res; 73 | }); 74 | values. 75 | subscribe( 76 | [](int v){printf("OnNext: %d\n", v);}, 77 | [](std::exception_ptr ep){ 78 | try {std::rethrow_exception(ep);} 79 | catch (const std::exception& ex) { 80 | printf("OnError: %s\n", ex.what()); 81 | } 82 | }, 83 | [](){printf("OnCompleted\n");}); 84 | printf("//! [reduce exception from result selector sample]\n"); 85 | } 86 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/ref_count.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | #include 7 | 8 | SCENARIO("ref_count other diamond sample"){ 9 | printf("//! [ref_count other diamond sample]\n"); 10 | 11 | /* 12 | * Implements the following diamond graph chain with publish+ref_count without using threads. 13 | * This version is composable because it does not use connect explicitly. 14 | * 15 | * Values 16 | * / \ 17 | * *2 *100 18 | * \ / 19 | * Merge 20 | * | 21 | * RefCount 22 | */ 23 | 24 | std::array a={{1.0, 2.0, 3.0, 4.0, 5.0}}; 25 | auto values = rxcpp::observable<>::iterate(a) 26 | // The root of the chain is only subscribed to once. 27 | .tap([](double v) { printf("[0] OnNext: %lf\n", v); }) 28 | .publish(); 29 | 30 | auto values_to_long = values.map([](double v) { return (long) v; }); 31 | 32 | // Left side multiplies by 2. 33 | auto left = values_to_long.map( 34 | [](long v) -> long {printf("[1] OnNext: %ld -> %ld\n", v, v*2); return v * 2L;} ); 35 | 36 | // Right side multiplies by 100. 37 | auto right = values_to_long.map( 38 | [](long v) -> long {printf("[2] OnNext: %ld -> %ld\n", v, v*100); return v * 100L; }); 39 | 40 | // Merge the left,right sides together. 41 | // The items are emitted interleaved ... [left1, right1, left2, right2, left3, right3, ...]. 42 | auto merged = left.merge(right); 43 | 44 | // When this value is subscribed to, it calls connect on values. 45 | auto connect_on_subscribe = merged.ref_count(values); 46 | 47 | // This immediately starts emitting all values and blocks until they are completed. 48 | connect_on_subscribe.subscribe( 49 | [](long v) { printf("[3] OnNext: %ld\n", v); }, 50 | [&]() { printf("[3] OnCompleted:\n"); }); 51 | 52 | printf("//! [ref_count other diamond sample]\n"); 53 | } 54 | 55 | // see also examples/doxygen/publish.cpp for non-ref_count diamonds 56 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/repeat.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("repeat sample"){ 7 | printf("//! [repeat sample]\n"); 8 | auto values = rxcpp::observable<>::from(1, 2). 9 | repeat(). 10 | take(5); 11 | values. 12 | subscribe( 13 | [](int v){printf("OnNext: %d\n", v);}, 14 | [](){printf("OnCompleted\n");}); 15 | printf("//! [repeat sample]\n"); 16 | } 17 | 18 | SCENARIO("repeat count sample"){ 19 | printf("//! [repeat count sample]\n"); 20 | auto values = rxcpp::observable<>::from(1, 2).repeat(3); 21 | values. 22 | subscribe( 23 | [](int v){printf("OnNext: %d\n", v);}, 24 | [](){printf("OnCompleted\n");}); 25 | printf("//! [repeat count sample]\n"); 26 | } 27 | 28 | SCENARIO("repeat error sample"){ 29 | printf("//! [repeat error sample]\n"); 30 | auto values = rxcpp::observable<>::from(1, 2). 31 | concat(rxcpp::observable<>::error(std::runtime_error("Error from source"))). 32 | repeat(); 33 | values. 34 | subscribe( 35 | [](int v){printf("OnNext: %d\n", v);}, 36 | [](std::exception_ptr ep){ 37 | try {std::rethrow_exception(ep);} 38 | catch (const std::exception& ex) { 39 | printf("OnError: %s\n", ex.what()); 40 | } 41 | }, 42 | [](){printf("OnCompleted\n");}); 43 | printf("//! [repeat error sample]\n"); 44 | } 45 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/retry.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("retry sample"){ 7 | printf("//! [retry sample]\n"); 8 | auto values = rxcpp::observable<>::from(1, 2). 9 | concat(rxcpp::observable<>::error(std::runtime_error("Error from source"))). 10 | retry(). 11 | take(5); 12 | values. 13 | subscribe( 14 | [](int v){printf("OnNext: %d\n", v);}, 15 | [](){printf("OnCompleted\n");}); 16 | printf("//! [retry sample]\n"); 17 | } 18 | 19 | SCENARIO("retry count sample"){ 20 | printf("//! [retry count sample]\n"); 21 | auto source = rxcpp::observable<>::from(1, 2). 22 | concat(rxcpp::observable<>::error(std::runtime_error("Error from source"))); 23 | auto values = source.retry(3); 24 | values. 25 | subscribe( 26 | [](int v){printf("OnNext: %d\n", v);}, 27 | [](std::exception_ptr ep){ 28 | try {std::rethrow_exception(ep);} 29 | catch (const std::exception& ex) { 30 | printf("OnError: %s\n", ex.what()); 31 | } 32 | }, 33 | [](){printf("OnCompleted\n");}); 34 | printf("//! [retry count sample]\n"); 35 | } 36 | 37 | //SCENARIO("retry hot sample"){ 38 | // printf("//! [retry hot sample]\n"); 39 | // auto values = rxcpp::observable<>::timer(std::chrono::milliseconds(10)). 40 | // concat(rxcpp::observable<>::error(std::runtime_error("Error1 from source"))). 41 | // concat(rxcpp::observable<>::timer(std::chrono::milliseconds(10))). 42 | // concat(rxcpp::observable<>::error(std::runtime_error("Error2 from source"))). 43 | // concat(rxcpp::observable<>::timer(std::chrono::milliseconds(10))). 44 | // concat(rxcpp::observable<>::error(std::runtime_error("Error3 from source"))). 45 | // concat(rxcpp::observable<>::timer(std::chrono::milliseconds(10))). 46 | // concat(rxcpp::observable<>::error(std::runtime_error("Error4 from source"))). 47 | // retry(3); 48 | // values. 49 | // subscribe( 50 | // [](long v){printf("OnNext: %d\n", v);}, 51 | // [](std::exception_ptr ep){ 52 | // try {std::rethrow_exception(ep);} 53 | // catch (const std::exception& ex) { 54 | // printf("OnError: %s\n", ex.what()); 55 | // } 56 | // }, 57 | // [](){printf("OnCompleted\n");}); 58 | // printf("//! [retry hot sample]\n"); 59 | //} 60 | // 61 | //SCENARIO("retry completed sample"){ 62 | // printf("//! [retry completed sample <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]\n"); 63 | // auto source = rxcpp::observable<>::from(1, 2). 64 | // concat(rxcpp::observable<>::error(std::runtime_error("Error from source"))). 65 | // publish(); 66 | // auto values = source.retry(); 67 | // //auto values = rxcpp::observable<>::timer(std::chrono::milliseconds(10)). 68 | // // concat(rxcpp::observable<>::error(std::runtime_error("Error1 from source"))). 69 | // // concat(rxcpp::observable<>::timer(std::chrono::milliseconds(10))). 70 | // // concat(rxcpp::observable<>::error(std::runtime_error("Error2 from source"))). 71 | // // concat(rxcpp::observable<>::timer(std::chrono::milliseconds(10))). 72 | // // retry(3); 73 | // values. 74 | // subscribe( 75 | // [](long v){printf("OnNext: %d\n", v);}, 76 | // [](std::exception_ptr ep){ 77 | // try {std::rethrow_exception(ep);} 78 | // catch (const std::exception& ex) { 79 | // printf("OnError: %s\n", ex.what()); 80 | // } 81 | // }, 82 | // [](){printf("OnCompleted\n");}); 83 | // printf("//! [retry completed sample]\n"); 84 | //} 85 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/sample.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("sample period sample") { 7 | printf("//! [sample period sample]\n"); 8 | auto values = rxcpp::observable<>::interval(std::chrono::milliseconds(2)). 9 | take(7). 10 | sample_with_time(std::chrono::milliseconds(4)); 11 | values. 12 | subscribe( 13 | [](long v) { 14 | printf("OnNext: %ld\n", v); 15 | }, 16 | []() { printf("OnCompleted\n"); }); 17 | printf("//! [sample period sample]\n"); 18 | } 19 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/scan.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("scan sample"){ 7 | printf("//! [scan sample]\n"); 8 | auto values = rxcpp::observable<>::range(1, 7). 9 | scan( 10 | 0, 11 | [](int seed, int v){ 12 | return seed + v; 13 | }); 14 | values. 15 | subscribe( 16 | [](int v){printf("OnNext: %d\n", v);}, 17 | [](){printf("OnCompleted\n");}); 18 | printf("//! [scan sample]\n"); 19 | } 20 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/scope.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("scope sample"){ 7 | printf("//! [scope sample]\n"); 8 | typedef rxcpp::resource> resource; 9 | auto resource_factory = [](){return resource(rxcpp::util::to_vector({1, 2, 3, 4, 5}));}; 10 | auto observable_factory = [](resource res){return rxcpp::observable<>::iterate(res.get());}; 11 | auto values = rxcpp::observable<>::scope(resource_factory, observable_factory); 12 | values. 13 | subscribe( 14 | [](int v){printf("OnNext: %d\n", v);}, 15 | [](){printf("OnCompleted\n");}); 16 | printf("//! [scope sample]\n"); 17 | } 18 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/sequence_equal.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("sequence_equal sample"){ 7 | printf("//! [sequence_equal sample]\n"); 8 | auto source = rxcpp::observable<>::range(1, 3); 9 | auto values = source.sequence_equal(rxcpp::observable<>::range(1, 3)); 10 | values. 11 | subscribe( 12 | [](bool v){ printf("OnNext: %s\n", v ? "true" : "false"); }, 13 | [](){ printf("OnCompleted\n");} ); 14 | printf("//! [sequence_equal sample]\n"); 15 | } 16 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/skip.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("skip sample"){ 7 | printf("//! [skip sample]\n"); 8 | auto values = rxcpp::observable<>::range(1, 7).skip(3); 9 | values. 10 | subscribe( 11 | [](int v){printf("OnNext: %d\n", v);}, 12 | [](){printf("OnCompleted\n");}); 13 | printf("//! [skip sample]\n"); 14 | } 15 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/skip_last.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("skip_last sample"){ 7 | printf("//! [skip_last sample]\n"); 8 | auto values = rxcpp::observable<>::range(1, 7).skip_last(3); 9 | values. 10 | subscribe( 11 | [](int v){printf("OnNext: %d\n", v);}, 12 | [](){printf("OnCompleted\n");}); 13 | printf("//! [skip_last sample]\n"); 14 | } 15 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/skip_until.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("skip_until sample"){ 7 | printf("//! [skip_until sample]\n"); 8 | auto source = rxcpp::observable<>::interval(std::chrono::milliseconds(10)).take(7); 9 | auto trigger = rxcpp::observable<>::timer(std::chrono::milliseconds(25)); 10 | auto values = source.skip_until(trigger); 11 | values. 12 | subscribe( 13 | [](long v){printf("OnNext: %ld\n", v);}, 14 | [](){printf("OnCompleted\n");}); 15 | printf("//! [skip_until sample]\n"); 16 | } 17 | 18 | #include "main.hpp" 19 | 20 | SCENARIO("threaded skip_until sample"){ 21 | printf("//! [threaded skip_until sample]\n"); 22 | printf("[thread %s] Start task\n", get_pid().c_str()); 23 | auto source = rxcpp::observable<>::interval(std::chrono::milliseconds(10)).take(7).map([](long v){ 24 | printf("[thread %s] Source emits, value = %ld\n", get_pid().c_str(), v); 25 | return v; 26 | }); 27 | auto trigger = rxcpp::observable<>::timer(std::chrono::milliseconds(25)).map([](long v){ 28 | printf("[thread %s] Trigger emits, value = %ld\n", get_pid().c_str(), v); 29 | return v; 30 | }); 31 | auto values = source.skip_until(trigger, rxcpp::observe_on_new_thread()); 32 | values. 33 | as_blocking(). 34 | subscribe( 35 | [](long v){printf("[thread %s] OnNext: %ld\n", get_pid().c_str(), v);}, 36 | [](){printf("[thread %s] OnCompleted\n", get_pid().c_str());}); 37 | printf("[thread %s] Finish task\n", get_pid().c_str()); 38 | printf("//! [threaded skip_until sample]\n"); 39 | } 40 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/skip_while.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("skip_while sample"){ 7 | printf("//! [skip_while sample]\n"); 8 | auto values = rxcpp::observable<>::range(1, 8). 9 | skip_while([](int v){ 10 | return v <= 4; 11 | }); 12 | values. 13 | subscribe( 14 | [](int v){printf("OnNext: %d\n", v);}, 15 | [](){printf("OnCompleted\n");}); 16 | printf("//! [skip_while sample]\n"); 17 | } 18 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/start_with.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("full start_with sample"){ 7 | printf("//! [full start_with sample]\n"); 8 | auto observable = rxcpp::observable<>::range(10, 12); 9 | auto values = rxcpp::observable<>::start_with(observable, 1, 2, 3); 10 | values. 11 | subscribe( 12 | [](int v){printf("OnNext: %d\n", v);}, 13 | [](){printf("OnCompleted\n");}); 14 | printf("//! [full start_with sample]\n"); 15 | } 16 | 17 | SCENARIO("short start_with sample"){ 18 | printf("//! [short start_with sample]\n"); 19 | auto values = rxcpp::observable<>::range(10, 12). 20 | start_with(1, 2, 3); 21 | values. 22 | subscribe( 23 | [](int v){printf("OnNext: %d\n", v);}, 24 | [](){printf("OnCompleted\n");}); 25 | printf("//! [short start_with sample]\n"); 26 | } 27 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/subscribe_on.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | #include "main.hpp" 7 | 8 | SCENARIO("subscribe_on sample"){ 9 | printf("//! [subscribe_on sample]\n"); 10 | printf("[thread %s] Start task\n", get_pid().c_str()); 11 | auto values = rxcpp::observable<>::range(1, 3). 12 | map([](int v){ 13 | printf("[thread %s] Emit value %d\n", get_pid().c_str(), v); 14 | return v; 15 | }); 16 | values. 17 | subscribe_on(rxcpp::synchronize_new_thread()). 18 | as_blocking(). 19 | subscribe( 20 | [](int v){printf("[thread %s] OnNext: %d\n", get_pid().c_str(), v);}, 21 | [](){printf("[thread %s] OnCompleted\n", get_pid().c_str());}); 22 | printf("[thread %s] Finish task\n", get_pid().c_str()); 23 | printf("//! [subscribe_on sample]\n"); 24 | } 25 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/switch_if_empty.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("switch_if_empty sample"){ 7 | printf("//! [switch_if_empty sample]\n"); 8 | 9 | auto values = rxcpp::observable<>::empty() 10 | .switch_if_empty(rxcpp::observable<>::range(1, 5)); 11 | 12 | values.subscribe( 13 | [](int v) { printf("OnNext: %d\n", v); }, 14 | []() { printf("OnCompleted\n"); } ); 15 | 16 | printf("//! [switch_if_empty sample]\n"); 17 | } 18 | 19 | SCENARIO("switch_if_empty - operator syntax sample") { 20 | using namespace rxcpp; 21 | using namespace rxcpp::sources; 22 | using namespace rxcpp::operators; 23 | 24 | printf("//! [switch_if_empty - operator syntax sample]\n"); 25 | auto values = empty() 26 | | switch_if_empty(range(1, 5)); 27 | 28 | values.subscribe( 29 | [](int v) { printf("OnNext: %d\n", v); }, 30 | []() { printf("OnCompleted\n"); } ); 31 | 32 | printf("//! [switch_if_empty - operator syntax sample]\n"); 33 | } 34 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/switch_on_next.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("switch_on_next sample"){ 7 | printf("//! [switch_on_next sample]\n"); 8 | auto base = rxcpp::observable<>::interval(std::chrono::milliseconds(30)). 9 | take(3). 10 | map([](long){ 11 | return rxcpp::observable<>::interval(std::chrono::milliseconds(10)).as_dynamic(); 12 | }); 13 | auto values = base.switch_on_next().take(10); 14 | values. 15 | subscribe( 16 | [](long v){printf("OnNext: %ld\n", v);}, 17 | [](){printf("OnCompleted\n");}); 18 | printf("//! [switch_on_next sample]\n"); 19 | } 20 | 21 | SCENARIO("threaded switch_on_next sample"){ 22 | printf("//! [threaded switch_on_next sample]\n"); 23 | auto base = rxcpp::observable<>::interval(std::chrono::milliseconds(30)). 24 | take(3). 25 | map([](long){ 26 | return rxcpp::observable<>::interval(std::chrono::milliseconds(10), rxcpp::observe_on_event_loop()).as_dynamic(); 27 | }); 28 | auto values = base.switch_on_next(rxcpp::observe_on_new_thread()).take(10); 29 | values. 30 | as_blocking(). 31 | subscribe( 32 | [](long v){printf("OnNext: %ld\n", v);}, 33 | [](){printf("OnCompleted\n");}); 34 | printf("//! [threaded switch_on_next sample]\n"); 35 | } 36 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/take.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | 7 | SCENARIO("take sample"){ 8 | printf("//! [take sample]\n"); 9 | auto values = rxcpp::observable<>::range(1, 7).take(3); 10 | values. 11 | subscribe( 12 | [](int v){printf("OnNext: %d\n", v);}, 13 | [](){printf("OnCompleted\n");}); 14 | printf("//! [take sample]\n"); 15 | } 16 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/take_last.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | 7 | SCENARIO("take_last sample"){ 8 | printf("//! [take_last sample]\n"); 9 | auto values = rxcpp::observable<>::range(1, 7).take_last(3); 10 | values. 11 | subscribe( 12 | [](int v){printf("OnNext: %d\n", v);}, 13 | [](){printf("OnCompleted\n");}); 14 | printf("//! [take_last sample]\n"); 15 | } 16 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/take_until.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("take_until sample"){ 7 | printf("//! [take_until sample]\n"); 8 | auto source = rxcpp::observable<>::interval(std::chrono::milliseconds(10)).take(7); 9 | auto trigger = rxcpp::observable<>::timer(std::chrono::milliseconds(25)); 10 | auto values = source.take_until(trigger); 11 | values. 12 | subscribe( 13 | [](long v){printf("OnNext: %ld\n", v);}, 14 | [](){printf("OnCompleted\n");}); 15 | printf("//! [take_until sample]\n"); 16 | } 17 | 18 | SCENARIO("take_until time sample"){ 19 | printf("//! [take_until time sample]\n"); 20 | auto source = rxcpp::observable<>::interval(std::chrono::milliseconds(10)).take(7); 21 | auto values = source.take_until(std::chrono::steady_clock::now() + std::chrono::milliseconds(25)); 22 | values. 23 | subscribe( 24 | [](long v){printf("OnNext: %ld\n", v);}, 25 | [](){printf("OnCompleted\n");}); 26 | printf("//! [take_until time sample]\n"); 27 | } 28 | 29 | #include "main.hpp" 30 | 31 | SCENARIO("threaded take_until sample"){ 32 | printf("//! [threaded take_until sample]\n"); 33 | printf("[thread %s] Start task\n", get_pid().c_str()); 34 | auto source = rxcpp::observable<>::interval(std::chrono::milliseconds(10)).take(7).map([](long v){ 35 | printf("[thread %s] Source emits, value = %ld\n", get_pid().c_str(), v); 36 | return v; 37 | }); 38 | auto trigger = rxcpp::observable<>::timer(std::chrono::milliseconds(25)).map([](long v){ 39 | printf("[thread %s] Trigger emits, value = %ld\n", get_pid().c_str(), v); 40 | return v; 41 | }); 42 | auto values = source.take_until(trigger, rxcpp::observe_on_new_thread()); 43 | values. 44 | as_blocking(). 45 | subscribe( 46 | [](long v){printf("[thread %s] OnNext: %ld\n", get_pid().c_str(), v);}, 47 | [](){printf("[thread %s] OnCompleted\n", get_pid().c_str());}); 48 | printf("[thread %s] Finish task\n", get_pid().c_str()); 49 | printf("//! [threaded take_until sample]\n"); 50 | } 51 | 52 | SCENARIO("threaded take_until time sample"){ 53 | printf("//! [threaded take_until time sample]\n"); 54 | printf("[thread %s] Start task\n", get_pid().c_str()); 55 | auto source = rxcpp::observable<>::interval(std::chrono::milliseconds(10)).take(7).map([](long v){ 56 | printf("[thread %s] Source emits, value = %ld\n", get_pid().c_str(), v); 57 | return v; 58 | }); 59 | auto scheduler = rxcpp::observe_on_new_thread(); 60 | auto values = source.take_until(scheduler.now() + std::chrono::milliseconds(25), scheduler); 61 | values. 62 | as_blocking(). 63 | subscribe( 64 | [](long v){printf("[thread %s] OnNext: %ld\n", get_pid().c_str(), v);}, 65 | [](){printf("[thread %s] OnCompleted\n", get_pid().c_str());}); 66 | printf("[thread %s] Finish task\n", get_pid().c_str()); 67 | printf("//! [threaded take_until time sample]\n"); 68 | } 69 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/take_while.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("take_while sample"){ 7 | printf("//! [take_while sample]\n"); 8 | auto values = rxcpp::observable<>::range(1, 8). 9 | take_while([](int v){ 10 | return v <= 4; 11 | }); 12 | values. 13 | subscribe( 14 | [](int v){printf("OnNext: %d\n", v);}, 15 | [](){printf("OnCompleted\n");}); 16 | printf("//! [take_while sample]\n"); 17 | } -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/tap.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | namespace rxu=rxcpp::util; 3 | 4 | #include "rxcpp/rx-test.hpp" 5 | #include "catch.hpp" 6 | 7 | SCENARIO("tap sample"){ 8 | printf("//! [tap sample]\n"); 9 | auto values = rxcpp::observable<>::range(1, 3). 10 | tap( 11 | [](int v){printf("Tap - OnNext: %d\n", v);}, 12 | [](){printf("Tap - OnCompleted\n");}); 13 | values. 14 | subscribe( 15 | [](int v){printf("Subscribe - OnNext: %d\n", v);}, 16 | [](){printf("Subscribe - OnCompleted\n");}); 17 | printf("//! [tap sample]\n"); 18 | } 19 | 20 | SCENARIO("error tap sample"){ 21 | printf("//! [error tap sample]\n"); 22 | auto values = rxcpp::observable<>::range(1, 3). 23 | concat(rxcpp::observable<>::error(std::runtime_error("Error from source"))). 24 | tap( 25 | [](int v){printf("Tap - OnNext: %d\n", v);}, 26 | [](std::exception_ptr ep){ 27 | printf("Tap - OnError: %s\n", rxu::what(ep).c_str()); 28 | }, 29 | [](){printf("Tap - OnCompleted\n");}); 30 | values. 31 | subscribe( 32 | [](int v){printf("Subscribe - OnNext: %d\n", v);}, 33 | [](std::exception_ptr ep){ 34 | printf("Subscribe - OnError: %s\n", rxu::what(ep).c_str()); 35 | }, 36 | [](){printf("Subscribe - OnCompleted\n");}); 37 | printf("//! [error tap sample]\n"); 38 | } 39 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/time_interval.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("time_interval sample") { 7 | printf("//! [time_interval sample]\n"); 8 | 9 | typedef rxcpp::schedulers::scheduler::clock_type::time_point::duration duration_type; 10 | 11 | using namespace std::chrono; 12 | auto values = rxcpp::observable<>::interval(milliseconds(100)) 13 | .time_interval() 14 | .take(3); 15 | values. 16 | subscribe( 17 | [&](duration_type v) { 18 | long long int ms = duration_cast(v).count(); 19 | printf("OnNext: @%lldms\n", ms); 20 | }, 21 | [](std::exception_ptr ep) { 22 | try { 23 | std::rethrow_exception(ep); 24 | } catch (const std::exception& ex) { 25 | printf("OnError: %s\n", ex.what()); 26 | } 27 | }, 28 | []() { printf("OnCompleted\n"); }); 29 | printf("//! [time_interval sample]\n"); 30 | } 31 | 32 | SCENARIO("time_interval operator syntax sample") { 33 | using namespace rxcpp; 34 | using namespace rxcpp::sources; 35 | using namespace rxcpp::operators; 36 | using namespace std::chrono; 37 | 38 | typedef rxcpp::schedulers::scheduler::clock_type::time_point::duration duration_type; 39 | 40 | printf("//! [time_interval operator syntax sample]\n"); 41 | auto values = interval(milliseconds(100)) 42 | | time_interval() 43 | | take(3); 44 | values. 45 | subscribe( 46 | [&](duration_type v) { 47 | long long int ms = duration_cast(v).count(); 48 | printf("OnNext: @%lldms\n", ms); 49 | }, 50 | [](std::exception_ptr ep) { 51 | try { 52 | std::rethrow_exception(ep); 53 | } catch (const std::exception& ex) { 54 | printf("OnError: %s\n", ex.what()); 55 | } 56 | }, 57 | []() { printf("OnCompleted\n"); }); 58 | printf("//! [time_interval operator syntax sample]\n"); 59 | } 60 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/timeout.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("timeout sample"){ 7 | printf("//! [timeout sample]\n"); 8 | 9 | using namespace std::chrono; 10 | auto values = rxcpp::observable<>::interval(milliseconds(100)) 11 | .take(3) 12 | .concat(rxcpp::observable<>::interval(milliseconds(500))) 13 | .timeout(milliseconds(200)); 14 | values. 15 | subscribe( 16 | [](long v) { printf("OnNext: %ld\n", v); }, 17 | [](std::exception_ptr ep) { 18 | try { 19 | std::rethrow_exception(ep); 20 | } catch (const rxcpp::timeout_error& ex) { 21 | printf("OnError: %s\n", ex.what()); 22 | } 23 | }, 24 | []() { printf("OnCompleted\n"); }); 25 | printf("//! [timeout sample]\n"); 26 | } 27 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/timer.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("timepoint timer sample"){ 7 | printf("//! [timepoint timer sample]\n"); 8 | auto start = std::chrono::steady_clock::now() + std::chrono::milliseconds(1); 9 | auto values = rxcpp::observable<>::timer(start); 10 | values. 11 | subscribe( 12 | [](int v){printf("OnNext: %d\n", v);}, 13 | [](){printf("OnCompleted\n");}); 14 | printf("//! [timepoint timer sample]\n"); 15 | } 16 | 17 | SCENARIO("duration timer sample"){ 18 | printf("//! [duration timer sample]\n"); 19 | auto period = std::chrono::milliseconds(1); 20 | auto values = rxcpp::observable<>::timer(period); 21 | values. 22 | subscribe( 23 | [](int v){printf("OnNext: %d\n", v);}, 24 | [](){printf("OnCompleted\n");}); 25 | printf("//! [duration timer sample]\n"); 26 | } 27 | 28 | SCENARIO("threaded timepoint timer sample"){ 29 | printf("//! [threaded timepoint timer sample]\n"); 30 | auto scheduler = rxcpp::observe_on_new_thread(); 31 | auto start = scheduler.now() + std::chrono::milliseconds(1); 32 | auto values = rxcpp::observable<>::timer(start, scheduler); 33 | values. 34 | as_blocking(). 35 | subscribe( 36 | [](int v){printf("OnNext: %d\n", v);}, 37 | [](){printf("OnCompleted\n");}); 38 | printf("//! [threaded timepoint timer sample]\n"); 39 | } 40 | 41 | SCENARIO("threaded duration timer sample"){ 42 | printf("//! [threaded duration timer sample]\n"); 43 | auto scheduler = rxcpp::observe_on_new_thread(); 44 | auto period = std::chrono::milliseconds(1); 45 | auto values = rxcpp::observable<>::timer(period, scheduler); 46 | values. 47 | as_blocking(). 48 | subscribe( 49 | [](int v){printf("OnNext: %d\n", v);}, 50 | [](){printf("OnCompleted\n");}); 51 | printf("//! [threaded duration timer sample]\n"); 52 | } 53 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/timestamp.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("timestamp sample") { 7 | printf("//! [timestamp sample]\n"); 8 | 9 | typedef rxcpp::schedulers::scheduler::clock_type::time_point time_point; 10 | 11 | using namespace std::chrono; 12 | auto values = rxcpp::observable<>::interval(milliseconds(100)) 13 | .timestamp() 14 | .take(3); 15 | time_point start = rxcpp::identity_current_thread().now(); 16 | values. 17 | subscribe( 18 | [&](std::pair v) { 19 | long long int ms = duration_cast(v.second - start).count(); 20 | printf("OnNext: %ld @%lldms\n", v.first, ms); 21 | }, 22 | [](std::exception_ptr ep) { 23 | try { 24 | std::rethrow_exception(ep); 25 | } catch (const std::exception& ex) { 26 | printf("OnError: %s\n", ex.what()); 27 | } 28 | }, 29 | []() { printf("OnCompleted\n"); }); 30 | printf("//! [timestamp sample]\n"); 31 | } 32 | 33 | SCENARIO("timestamp operator syntax sample") { 34 | using namespace rxcpp; 35 | using namespace rxcpp::sources; 36 | using namespace rxcpp::operators; 37 | using namespace std::chrono; 38 | 39 | typedef rxcpp::schedulers::scheduler::clock_type::time_point time_point; 40 | 41 | printf("//! [timestamp operator syntax sample]\n"); 42 | auto values = interval(milliseconds(100)) 43 | | timestamp() 44 | | take(3); 45 | time_point start = rxcpp::identity_current_thread().now(); 46 | values. 47 | subscribe( 48 | [&](std::pair v) { 49 | long long int ms = duration_cast(v.second - start).count(); 50 | printf("OnNext: %ld @%lldms\n", v.first, ms); 51 | }, 52 | [](std::exception_ptr ep) { 53 | try { 54 | std::rethrow_exception(ep); 55 | } catch (const std::exception& ex) { 56 | printf("OnError: %s\n", ex.what()); 57 | } 58 | }, 59 | []() { printf("OnCompleted\n"); }); 60 | printf("//! [timestamp operator syntax sample]\n"); 61 | } -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/with_latest_from.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("with_latest_from sample"){ 7 | printf("//! [with_latest_from sample]\n"); 8 | auto o1 = rxcpp::observable<>::interval(std::chrono::milliseconds(2)); 9 | auto o2 = rxcpp::observable<>::interval(std::chrono::milliseconds(3)); 10 | auto o3 = rxcpp::observable<>::interval(std::chrono::milliseconds(5)); 11 | auto values = o1.with_latest_from(o2, o3); 12 | values. 13 | take(5). 14 | subscribe( 15 | [](std::tuple v){printf("OnNext: %d, %d, %d\n", std::get<0>(v), std::get<1>(v), std::get<2>(v));}, 16 | [](){printf("OnCompleted\n");}); 17 | printf("//! [with_latest_from sample]\n"); 18 | } 19 | 20 | #include "main.hpp" 21 | 22 | SCENARIO("Coordination with_latest_from sample"){ 23 | printf("//! [Coordination with_latest_from sample]\n"); 24 | printf("[thread %s] Start task\n", get_pid().c_str()); 25 | auto thr = rxcpp::synchronize_event_loop(); 26 | auto o1 = rxcpp::observable<>::interval(std::chrono::milliseconds(2)).map([](int v) { 27 | printf("[thread %s] Source1 OnNext: %d\n", get_pid().c_str(), v); 28 | return v; 29 | }); 30 | auto o2 = rxcpp::observable<>::interval(std::chrono::milliseconds(3)).map([](int v) { 31 | printf("[thread %s] Source2 OnNext: %d\n", get_pid().c_str(), v); 32 | return v; 33 | }); 34 | auto o3 = rxcpp::observable<>::interval(std::chrono::milliseconds(5)).map([](int v) { 35 | printf("[thread %s] Source3 OnNext: %d\n", get_pid().c_str(), v); 36 | return v; 37 | }); 38 | auto values = o1.with_latest_from(thr, o2, o3); 39 | values. 40 | take(5). 41 | as_blocking(). 42 | subscribe( 43 | [](std::tuple v){printf("[thread %s] OnNext: %d, %d, %d\n", get_pid().c_str(), std::get<0>(v), std::get<1>(v), std::get<2>(v));}, 44 | [](){printf("[thread %s] OnCompleted\n", get_pid().c_str());}); 45 | printf("[thread %s] Finish task\n", get_pid().c_str()); 46 | printf("//! [Coordination with_latest_from sample]\n"); 47 | } 48 | 49 | SCENARIO("Selector with_latest_from sample"){ 50 | printf("//! [Selector with_latest_from sample]\n"); 51 | auto o1 = rxcpp::observable<>::interval(std::chrono::milliseconds(2)); 52 | auto o2 = rxcpp::observable<>::interval(std::chrono::milliseconds(3)); 53 | auto o3 = rxcpp::observable<>::interval(std::chrono::milliseconds(5)); 54 | auto values = o1.with_latest_from( 55 | [](int v1, int v2, int v3) { 56 | return 100 * v1 + 10 * v2 + v3; 57 | }, 58 | o2, o3); 59 | values. 60 | take(5). 61 | subscribe( 62 | [](int v){printf("OnNext: %d\n", v);}, 63 | [](){printf("OnCompleted\n");}); 64 | printf("//! [Selector with_latest_from sample]\n"); 65 | } 66 | 67 | SCENARIO("Coordination+Selector with_latest_from sample"){ 68 | printf("//! [Coordination+Selector with_latest_from sample]\n"); 69 | auto o1 = rxcpp::observable<>::interval(std::chrono::milliseconds(2)); 70 | auto o2 = rxcpp::observable<>::interval(std::chrono::milliseconds(3)); 71 | auto o3 = rxcpp::observable<>::interval(std::chrono::milliseconds(5)); 72 | auto values = o1.with_latest_from( 73 | rxcpp::observe_on_new_thread(), 74 | [](int v1, int v2, int v3) { 75 | return 100 * v1 + 10 * v2 + v3; 76 | }, 77 | o2, o3); 78 | values. 79 | take(5). 80 | as_blocking(). 81 | subscribe( 82 | [](int v){printf("OnNext: %d\n", v);}, 83 | [](){printf("OnCompleted\n");}); 84 | printf("//! [Coordination+Selector with_latest_from sample]\n"); 85 | } 86 | -------------------------------------------------------------------------------- /Rx/v2/examples/doxygen/zip.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | 3 | #include "rxcpp/rx-test.hpp" 4 | #include "catch.hpp" 5 | 6 | SCENARIO("zip sample"){ 7 | printf("//! [zip sample]\n"); 8 | auto o1 = rxcpp::observable<>::interval(std::chrono::milliseconds(1)); 9 | auto o2 = rxcpp::observable<>::interval(std::chrono::milliseconds(2)); 10 | auto o3 = rxcpp::observable<>::interval(std::chrono::milliseconds(3)); 11 | auto values = o1.zip(o2, o3); 12 | values. 13 | take(3). 14 | subscribe( 15 | [](std::tuple v){printf("OnNext: %d, %d, %d\n", std::get<0>(v), std::get<1>(v), std::get<2>(v));}, 16 | [](){printf("OnCompleted\n");}); 17 | printf("//! [zip sample]\n"); 18 | } 19 | 20 | #include "main.hpp" 21 | 22 | SCENARIO("Coordination zip sample"){ 23 | printf("//! [Coordination zip sample]\n"); 24 | printf("[thread %s] Start task\n", get_pid().c_str()); 25 | auto thr = rxcpp::synchronize_event_loop(); 26 | auto o1 = rxcpp::observable<>::interval(std::chrono::milliseconds(1)).map([](int v) { 27 | printf("[thread %s] Source1 OnNext: %d\n", get_pid().c_str(), v); 28 | return v; 29 | }); 30 | auto o2 = rxcpp::observable<>::interval(std::chrono::milliseconds(2)).map([](int v) { 31 | printf("[thread %s] Source2 OnNext: %d\n", get_pid().c_str(), v); 32 | return v; 33 | }); 34 | auto o3 = rxcpp::observable<>::interval(std::chrono::milliseconds(3)).map([](int v) { 35 | printf("[thread %s] Source3 OnNext: %d\n", get_pid().c_str(), v); 36 | return v; 37 | }); 38 | auto values = o1.zip(thr, o2, o3); 39 | values. 40 | take(3). 41 | as_blocking(). 42 | subscribe( 43 | [](std::tuple v){printf("[thread %s] OnNext: %d, %d, %d\n", get_pid().c_str(), std::get<0>(v), std::get<1>(v), std::get<2>(v));}, 44 | [](){printf("[thread %s] OnCompleted\n", get_pid().c_str());}); 45 | printf("[thread %s] Finish task\n", get_pid().c_str()); 46 | printf("//! [Coordination zip sample]\n"); 47 | } 48 | 49 | SCENARIO("Selector zip sample"){ 50 | printf("//! [Selector zip sample]\n"); 51 | auto o1 = rxcpp::observable<>::interval(std::chrono::milliseconds(1)); 52 | auto o2 = rxcpp::observable<>::interval(std::chrono::milliseconds(2)); 53 | auto o3 = rxcpp::observable<>::interval(std::chrono::milliseconds(3)); 54 | auto values = o1 | rxcpp::operators::zip( 55 | [](int v1, int v2, int v3) { 56 | return 100 * v1 + 10 * v2 + v3; 57 | }, 58 | o2, o3); 59 | values. 60 | take(3). 61 | subscribe( 62 | [](int v){printf("OnNext: %d\n", v);}, 63 | [](){printf("OnCompleted\n");}); 64 | printf("//! [Selector zip sample]\n"); 65 | } 66 | 67 | SCENARIO("Coordination+Selector zip sample"){ 68 | printf("//! [Coordination+Selector zip sample]\n"); 69 | auto o1 = rxcpp::observable<>::interval(std::chrono::milliseconds(1)); 70 | auto o2 = rxcpp::observable<>::interval(std::chrono::milliseconds(2)); 71 | auto o3 = rxcpp::observable<>::interval(std::chrono::milliseconds(3)); 72 | auto values = o1.zip( 73 | rxcpp::observe_on_new_thread(), 74 | [](int v1, int v2, int v3) { 75 | return 100 * v1 + 10 * v2 + v3; 76 | }, 77 | o2, o3); 78 | values. 79 | take(3). 80 | as_blocking(). 81 | subscribe( 82 | [](int v){printf("OnNext: %d\n", v);}, 83 | [](){printf("OnCompleted\n");}); 84 | printf("//! [Coordination+Selector zip sample]\n"); 85 | } 86 | -------------------------------------------------------------------------------- /Rx/v2/examples/linesfrombytes/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.2 FATAL_ERROR) 2 | 3 | get_filename_component(SAMPLE_PROJECT "${CMAKE_CURRENT_SOURCE_DIR}" NAME) 4 | 5 | project(${SAMPLE_PROJECT} LANGUAGES C CXX) 6 | 7 | # define some folders 8 | get_filename_component(RXCPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}" PATH) 9 | get_filename_component(RXCPP_DIR "${RXCPP_DIR}" PATH) 10 | get_filename_component(RXCPP_DIR "${RXCPP_DIR}" PATH) 11 | get_filename_component(RXCPP_DIR "${RXCPP_DIR}" PATH) 12 | 13 | MESSAGE( STATUS "RXCPP_DIR: " ${RXCPP_DIR} ) 14 | 15 | include(${RXCPP_DIR}/projects/CMake/shared.cmake) 16 | 17 | # define the sources 18 | set(SAMPLE_SOURCES 19 | ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp 20 | ) 21 | add_executable(${SAMPLE_PROJECT} ${SAMPLE_SOURCES}) 22 | add_executable(rxcpp::examples::${SAMPLE_PROJECT} ALIAS ${SAMPLE_PROJECT}) 23 | target_compile_options(${SAMPLE_PROJECT} PUBLIC ${RX_COMPILE_OPTIONS}) 24 | target_compile_features(${SAMPLE_PROJECT} PUBLIC ${RX_COMPILE_FEATURES}) 25 | target_include_directories(${SAMPLE_PROJECT} PUBLIC ${RX_SRC_DIR}) 26 | target_link_libraries(${SAMPLE_PROJECT} ${CMAKE_THREAD_LIBS_INIT}) 27 | 28 | # configure unit tests via CTest 29 | enable_testing() 30 | set(CTEST_CONFIGURATION_TYPE "${JOB_BUILD_CONFIGURATION}") 31 | 32 | set_target_properties(${SAMPLE_PROJECT} PROPERTIES FOLDER "Examples") 33 | 34 | add_test(NAME RunTests 35 | WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" 36 | COMMAND ${SAMPLE_PROJECT} ${TEST_ARGS}) 37 | -------------------------------------------------------------------------------- /Rx/v2/examples/linesfrombytes/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | namespace Rx { 18 | using namespace rxcpp; 19 | using namespace rxcpp::sources; 20 | using namespace rxcpp::operators; 21 | using namespace rxcpp::util; 22 | } 23 | using namespace Rx; 24 | 25 | #include 26 | #include 27 | using namespace std; 28 | using namespace std::chrono; 29 | 30 | int main() 31 | { 32 | random_device rd; // non-deterministic generator 33 | mt19937 gen(rd()); 34 | uniform_int_distribution<> dist(4, 18); 35 | 36 | // for testing purposes, produce byte stream that from lines of text 37 | auto bytes = range(0, 10) | 38 | flat_map([&](int i){ 39 | auto body = from((uint8_t)('A' + i)) | 40 | repeat(dist(gen)) | 41 | as_dynamic(); 42 | auto delim = from((uint8_t)'\r'); 43 | return from(body, delim) | concat(); 44 | }) | 45 | window(17) | 46 | flat_map([](observable w){ 47 | return w | 48 | reduce( 49 | vector(), 50 | [](vector v, uint8_t b){ 51 | v.push_back(b); 52 | return v; 53 | }) | 54 | as_dynamic(); 55 | }) | 56 | tap([](const vector& v){ 57 | // print input packet of bytes 58 | copy(v.begin(), v.end(), ostream_iterator(cout, " ")); 59 | cout << endl; 60 | }); 61 | 62 | // 63 | // recover lines of text from byte stream 64 | // 65 | 66 | auto removespaces = [](string s){ 67 | s.erase(remove_if(s.begin(), s.end(), ::isspace), s.end()); 68 | return s; 69 | }; 70 | 71 | // create strings split on \r 72 | auto strings = bytes | 73 | concat_map([](vector v){ 74 | string s(v.begin(), v.end()); 75 | regex delim(R"/(\r)/"); 76 | cregex_token_iterator cursor(&s[0], &s[0] + s.size(), delim, {-1, 0}); 77 | cregex_token_iterator end; 78 | vector splits(cursor, end); 79 | return iterate(move(splits)); 80 | }) | 81 | filter([](const string& s){ 82 | return !s.empty(); 83 | }) | 84 | publish() | 85 | ref_count(); 86 | 87 | // filter to last string in each line 88 | auto closes = strings | 89 | filter( 90 | [](const string& s){ 91 | return s.back() == '\r'; 92 | }) | 93 | Rx::map([](const string&){return 0;}); 94 | 95 | // group strings by line 96 | auto linewindows = strings | 97 | window_toggle(closes | start_with(0), [=](int){return closes;}); 98 | 99 | // reduce the strings for a line into one string 100 | auto lines = linewindows | 101 | flat_map([&](observable w) { 102 | return w | start_with("") | sum() | Rx::map(removespaces); 103 | }); 104 | 105 | // print result 106 | lines | 107 | subscribe(println(cout)); 108 | 109 | return 0; 110 | } 111 | -------------------------------------------------------------------------------- /Rx/v2/examples/println/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.2 FATAL_ERROR) 2 | 3 | get_filename_component(SAMPLE_PROJECT "${CMAKE_CURRENT_SOURCE_DIR}" NAME) 4 | 5 | project(${SAMPLE_PROJECT} LANGUAGES C CXX) 6 | 7 | # define some folders 8 | get_filename_component(RXCPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}" PATH) 9 | get_filename_component(RXCPP_DIR "${RXCPP_DIR}" PATH) 10 | get_filename_component(RXCPP_DIR "${RXCPP_DIR}" PATH) 11 | get_filename_component(RXCPP_DIR "${RXCPP_DIR}" PATH) 12 | 13 | MESSAGE( STATUS "RXCPP_DIR: " ${RXCPP_DIR} ) 14 | 15 | include(${RXCPP_DIR}/projects/CMake/shared.cmake) 16 | 17 | # define the sources 18 | set(SAMPLE_SOURCES 19 | ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp 20 | ) 21 | add_executable(${SAMPLE_PROJECT} ${SAMPLE_SOURCES}) 22 | add_executable(rxcpp::examples::${SAMPLE_PROJECT} ALIAS ${SAMPLE_PROJECT}) 23 | target_compile_options(${SAMPLE_PROJECT} PUBLIC ${RX_COMPILE_OPTIONS}) 24 | target_compile_features(${SAMPLE_PROJECT} PUBLIC ${RX_COMPILE_FEATURES}) 25 | target_include_directories(${SAMPLE_PROJECT} PUBLIC ${RX_SRC_DIR}) 26 | target_link_libraries(${SAMPLE_PROJECT} ${CMAKE_THREAD_LIBS_INIT}) 27 | 28 | # configure unit tests via CTest 29 | enable_testing() 30 | set(CTEST_CONFIGURATION_TYPE "${JOB_BUILD_CONFIGURATION}") 31 | 32 | set_target_properties(${SAMPLE_PROJECT} PROPERTIES FOLDER "Examples") 33 | 34 | add_test(NAME RunTests 35 | WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" 36 | COMMAND ${SAMPLE_PROJECT} ${TEST_ARGS}) 37 | -------------------------------------------------------------------------------- /Rx/v2/examples/println/main.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | // create alias' to simplify code 3 | // these are owned by the user so that 4 | // conflicts can be managed by the user. 5 | namespace rx=rxcpp; 6 | namespace rxu=rxcpp::util; 7 | 8 | #include 9 | 10 | // At this time, RxCpp will fail to compile if the contents 11 | // of the std namespace are merged into the global namespace 12 | // DO NOT USE: 'using namespace std;' 13 | 14 | #if 0 15 | // 16 | // println will insert values into the specified stream 17 | // 18 | template 19 | struct println_function 20 | { 21 | OStream& os; 22 | println_function(OStream& os) : os(os) {} 23 | 24 | template 25 | void operator()(const TN&... tn) const { 26 | bool inserts[] = {(os << tn, true)...}; 27 | os << std::endl; 28 | } 29 | 30 | template 31 | void operator()(const std::tuple& tpl) const { 32 | apply(tpl, *this); 33 | } 34 | }; 35 | template 36 | auto println(OStream& os) 37 | -> println_function { 38 | return println_function(os); 39 | } 40 | #endif 41 | 42 | #ifdef UNICODE 43 | int wmain() 44 | #else 45 | int main() 46 | #endif 47 | { 48 | auto get_names = [](){return rx::observable<>::from( 49 | "Matthew", 50 | "Aaron" 51 | );}; 52 | 53 | std::cout << "===== println stream of std::string =====" << std::endl; 54 | auto hello_str = [&](){return get_names().map([](std::string n){ 55 | return "Hello, " + n + "!"; 56 | }).as_dynamic();}; 57 | 58 | hello_str().subscribe(rxu::println(std::cout)); 59 | 60 | std::cout << "===== println stream of std::tuple =====" << std::endl; 61 | auto hello_tpl = [&](){return get_names().map([](std::string n){ 62 | return std::make_tuple("Hello, ", n, "! (", n.size(), ")"); 63 | }).as_dynamic();}; 64 | 65 | hello_tpl().subscribe(rxu::println(std::cout)); 66 | 67 | hello_tpl().subscribe(rxu::print_followed_by(std::cout, " and "), rxu::endline(std::cout)); 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /Rx/v2/examples/pythagorian/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.2 FATAL_ERROR) 2 | 3 | get_filename_component(SAMPLE_PROJECT "${CMAKE_CURRENT_SOURCE_DIR}" NAME) 4 | 5 | project(${SAMPLE_PROJECT} LANGUAGES C CXX) 6 | 7 | # define some folders 8 | get_filename_component(RXCPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}" PATH) 9 | get_filename_component(RXCPP_DIR "${RXCPP_DIR}" PATH) 10 | get_filename_component(RXCPP_DIR "${RXCPP_DIR}" PATH) 11 | get_filename_component(RXCPP_DIR "${RXCPP_DIR}" PATH) 12 | 13 | MESSAGE( STATUS "RXCPP_DIR: " ${RXCPP_DIR} ) 14 | 15 | include(${RXCPP_DIR}/projects/CMake/shared.cmake) 16 | 17 | # define the sources 18 | set(SAMPLE_SOURCES 19 | ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp 20 | ) 21 | add_executable(${SAMPLE_PROJECT} ${SAMPLE_SOURCES}) 22 | add_executable(rxcpp::examples::${SAMPLE_PROJECT} ALIAS ${SAMPLE_PROJECT}) 23 | target_compile_options(${SAMPLE_PROJECT} PUBLIC ${RX_COMPILE_OPTIONS}) 24 | target_compile_features(${SAMPLE_PROJECT} PUBLIC ${RX_COMPILE_FEATURES}) 25 | target_include_directories(${SAMPLE_PROJECT} PUBLIC ${RX_SRC_DIR}) 26 | target_link_libraries(${SAMPLE_PROJECT} ${CMAKE_THREAD_LIBS_INIT}) 27 | 28 | # configure unit tests via CTest 29 | enable_testing() 30 | set(CTEST_CONFIGURATION_TYPE "${JOB_BUILD_CONFIGURATION}") 31 | 32 | set_target_properties(${SAMPLE_PROJECT} PROPERTIES FOLDER "Examples") 33 | 34 | add_test(NAME RunTests 35 | WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" 36 | COMMAND ${SAMPLE_PROJECT} ${TEST_ARGS}) 37 | -------------------------------------------------------------------------------- /Rx/v2/examples/stop/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.2 FATAL_ERROR) 2 | 3 | get_filename_component(SAMPLE_PROJECT "${CMAKE_CURRENT_SOURCE_DIR}" NAME) 4 | 5 | project(${SAMPLE_PROJECT} LANGUAGES C CXX) 6 | 7 | # define some folders 8 | get_filename_component(RXCPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}" PATH) 9 | get_filename_component(RXCPP_DIR "${RXCPP_DIR}" PATH) 10 | get_filename_component(RXCPP_DIR "${RXCPP_DIR}" PATH) 11 | get_filename_component(RXCPP_DIR "${RXCPP_DIR}" PATH) 12 | 13 | MESSAGE( STATUS "RXCPP_DIR: " ${RXCPP_DIR} ) 14 | 15 | include(${RXCPP_DIR}/projects/CMake/shared.cmake) 16 | 17 | # define the sources 18 | set(SAMPLE_SOURCES 19 | ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp 20 | ) 21 | add_executable(${SAMPLE_PROJECT} ${SAMPLE_SOURCES}) 22 | add_executable(rxcpp::examples::${SAMPLE_PROJECT} ALIAS ${SAMPLE_PROJECT}) 23 | target_compile_options(${SAMPLE_PROJECT} PUBLIC ${RX_COMPILE_OPTIONS}) 24 | target_compile_features(${SAMPLE_PROJECT} PUBLIC ${RX_COMPILE_FEATURES}) 25 | target_include_directories(${SAMPLE_PROJECT} PUBLIC ${RX_SRC_DIR}) 26 | target_link_libraries(${SAMPLE_PROJECT} ${CMAKE_THREAD_LIBS_INIT}) 27 | 28 | # configure unit tests via CTest 29 | enable_testing() 30 | set(CTEST_CONFIGURATION_TYPE "${JOB_BUILD_CONFIGURATION}") 31 | 32 | set_target_properties(${SAMPLE_PROJECT} PROPERTIES FOLDER "Examples") 33 | 34 | add_test(NAME RunTests 35 | WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" 36 | COMMAND ${SAMPLE_PROJECT} ${TEST_ARGS}) 37 | -------------------------------------------------------------------------------- /Rx/v2/examples/stop/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "rxcpp/rx.hpp" 3 | // create alias' to simplify code 4 | // these are owned by the user so that 5 | // conflicts can be managed by the user. 6 | namespace rx=rxcpp; 7 | namespace rxsub=rxcpp::subjects; 8 | namespace rxu=rxcpp::util; 9 | 10 | // At this time, RxCpp will fail to compile if the contents 11 | // of the std namespace are merged into the global namespace 12 | // DO NOT USE: 'using namespace std;' 13 | 14 | int main() 15 | { 16 | // works 17 | { 18 | auto published_observable = 19 | rx::observable<>::range(1) 20 | .filter([](int i) 21 | { 22 | std::cout << i << std::endl; 23 | std::this_thread::sleep_for(std::chrono::milliseconds(300)); 24 | return true; 25 | }) 26 | .subscribe_on(rx::observe_on_new_thread()) 27 | .publish(); 28 | 29 | auto subscription = published_observable.connect(); 30 | std::this_thread::sleep_for(std::chrono::seconds(1)); 31 | subscription.unsubscribe(); 32 | std::cout << "unsubscribed" << std::endl << std::endl; 33 | } 34 | 35 | // idiomatic (prefer operators) 36 | { 37 | auto published_observable = 38 | rx::observable<>::interval(std::chrono::milliseconds(300)) 39 | .subscribe_on(rx::observe_on_new_thread()) 40 | .publish(); 41 | 42 | published_observable. 43 | ref_count(). 44 | take_until(rx::observable<>::timer(std::chrono::seconds(1))). 45 | finally([](){ 46 | std::cout << "unsubscribed" << std::endl << std::endl; 47 | }). 48 | subscribe([](int i){ 49 | std::cout << i << std::endl; 50 | }); 51 | } 52 | 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /Rx/v2/examples/tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.2 FATAL_ERROR) 2 | 3 | get_filename_component(SAMPLE_PROJECT "${CMAKE_CURRENT_SOURCE_DIR}" NAME) 4 | 5 | project(${SAMPLE_PROJECT} LANGUAGES C CXX) 6 | 7 | # define some folders 8 | get_filename_component(RXCPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}" PATH) 9 | get_filename_component(RXCPP_DIR "${RXCPP_DIR}" PATH) 10 | get_filename_component(RXCPP_DIR "${RXCPP_DIR}" PATH) 11 | get_filename_component(RXCPP_DIR "${RXCPP_DIR}" PATH) 12 | 13 | MESSAGE( STATUS "RXCPP_DIR: " ${RXCPP_DIR} ) 14 | 15 | include(${RXCPP_DIR}/projects/CMake/shared.cmake) 16 | 17 | # define the sources 18 | set(SAMPLE_SOURCES 19 | ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp 20 | ${CMAKE_CURRENT_SOURCE_DIR}/take.cpp 21 | ) 22 | add_executable(${SAMPLE_PROJECT} ${SAMPLE_SOURCES}) 23 | add_executable(rxcpp::examples::${SAMPLE_PROJECT} ALIAS ${SAMPLE_PROJECT}) 24 | target_compile_options(${SAMPLE_PROJECT} PUBLIC ${RX_COMPILE_OPTIONS}) 25 | target_compile_features(${SAMPLE_PROJECT} PUBLIC ${RX_COMPILE_FEATURES}) 26 | target_include_directories(${SAMPLE_PROJECT} PUBLIC ${RX_SRC_DIR} ${RX_CATCH_DIR}) 27 | target_link_libraries(${SAMPLE_PROJECT} ${CMAKE_THREAD_LIBS_INIT}) 28 | 29 | # configure unit tests via CTest 30 | enable_testing() 31 | set(CTEST_CONFIGURATION_TYPE "${JOB_BUILD_CONFIGURATION}") 32 | 33 | set_target_properties(${SAMPLE_PROJECT} PROPERTIES FOLDER "Examples") 34 | 35 | add_test(NAME RunTests 36 | WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" 37 | COMMAND ${SAMPLE_PROJECT} ${TEST_ARGS}) 38 | -------------------------------------------------------------------------------- /Rx/v2/examples/tests/main.cpp: -------------------------------------------------------------------------------- 1 | #define CATCH_CONFIG_MAIN 2 | #include "catch.hpp" 3 | -------------------------------------------------------------------------------- /Rx/v2/examples/tests/take.cpp: -------------------------------------------------------------------------------- 1 | #include "rxcpp/rx.hpp" 2 | namespace rx=rxcpp; 3 | namespace rxu=rxcpp::util; 4 | namespace rxsc=rxcpp::schedulers; 5 | 6 | #include "rxcpp/rx-test.hpp" 7 | #include "catch.hpp" 8 | 9 | SCENARIO("take 2 - passes", "[take][passes][operators]"){ 10 | GIVEN("a source"){ 11 | auto sc = rxsc::make_test(); 12 | auto w = sc.create_worker(); 13 | const rxsc::test::messages on; 14 | 15 | auto xs = sc.make_hot_observable({ 16 | on.next(150, 1), 17 | on.next(210, 2), 18 | on.next(220, 3), 19 | on.next(230, 4), 20 | on.next(240, 5), 21 | on.completed(250) 22 | }); 23 | 24 | WHEN("2 values are taken"){ 25 | 26 | auto res = w.start( 27 | [xs]() { 28 | return xs 29 | .take(2) 30 | // forget type to workaround lambda deduction bug on msvc 2013 31 | .as_dynamic(); 32 | } 33 | ); 34 | 35 | THEN("the output only contains items sent while subscribed"){ 36 | auto required = rxu::to_vector({ 37 | on.next(210, 2), 38 | on.next(220, 3), 39 | on.completed(220) 40 | }); 41 | auto actual = res.get_observer().messages(); 42 | REQUIRE(required == actual); 43 | } 44 | 45 | THEN("there was 1 subscription/unsubscription to the source"){ 46 | auto required = rxu::to_vector({ 47 | on.subscribe(200, 220) 48 | }); 49 | auto actual = xs.subscriptions(); 50 | REQUIRE(required == actual); 51 | } 52 | 53 | } 54 | } 55 | } 56 | 57 | SCENARIO("take 2 - fails", "[take][fails][operators]"){ 58 | GIVEN("a source"){ 59 | auto sc = rxsc::make_test(); 60 | auto w = sc.create_worker(); 61 | const rxsc::test::messages on; 62 | 63 | auto xs = sc.make_hot_observable({ 64 | on.next(150, 1), 65 | on.next(210, 2), 66 | on.next(220, 3), 67 | on.next(230, 4), 68 | on.next(240, 5), 69 | on.completed(250) 70 | }); 71 | 72 | WHEN("2 values are taken"){ 73 | 74 | auto res = w.start( 75 | [xs]() { 76 | return xs 77 | // TYPO START 78 | .skip(2) 79 | // TYPO END 80 | // forget type to workaround lambda deduction bug on msvc 2013 81 | .as_dynamic(); 82 | } 83 | ); 84 | 85 | THEN("the output only contains items sent while subscribed"){ 86 | auto required = rxu::to_vector({ 87 | on.next(210, 2), 88 | on.next(220, 3), 89 | on.completed(220) 90 | }); 91 | auto actual = res.get_observer().messages(); 92 | REQUIRE(required == actual); 93 | } 94 | 95 | THEN("there was 1 subscription/unsubscription to the source"){ 96 | auto required = rxu::to_vector({ 97 | on.subscribe(200, 220) 98 | }); 99 | auto actual = xs.subscriptions(); 100 | REQUIRE(required == actual); 101 | } 102 | 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /Rx/v2/examples/win_text/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | 3 | get_filename_component(SAMPLE_PROJECT "${CMAKE_CURRENT_SOURCE_DIR}" NAME) 4 | 5 | project(${SAMPLE_PROJECT}) 6 | 7 | FIND_PACKAGE(Threads) 8 | 9 | MESSAGE( STATUS "CMAKE_CXX_COMPILER_ID: " ${CMAKE_CXX_COMPILER_ID} ) 10 | if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") 11 | MESSAGE( STATUS "using clang settings" ) 12 | add_compile_options( -Wall -Wextra -Werror ) 13 | add_compile_options( -std=c++11 -stdlib=libc++ ) 14 | add_compile_options( -ftemplate-depth=1024 ) # sometimes you just do what the compiler tells you 15 | elseif (CMAKE_CXX_COMPILER_ID MATCHES "GNU") 16 | MESSAGE( STATUS "using gnu settings" ) 17 | add_compile_options( -Wall -Wextra -Werror ) 18 | add_compile_options( -std=c++11 ) 19 | elseif (CMAKE_CXX_COMPILER_ID MATCHES "MSVC") 20 | MESSAGE( STATUS "using msvc settings" ) 21 | add_compile_options( /W4 /WX ) 22 | add_compile_options( /wd4503 ) # truncated symbol 23 | add_compile_options( /wd4702 ) # unreachable code 24 | add_compile_options( /wd4091 ) # typedef ignored on left when no variable is declared 25 | add_compile_options( /bigobj ) 26 | add_definitions( /DUNICODE /D_UNICODE ) # it is a new millenium 27 | endif() 28 | 29 | 30 | # define some folders 31 | get_filename_component(RXCPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}" PATH) 32 | get_filename_component(RXCPP_DIR "${RXCPP_DIR}" PATH) 33 | get_filename_component(RXCPP_DIR "${RXCPP_DIR}" PATH) 34 | get_filename_component(RXCPP_DIR "${RXCPP_DIR}" PATH) 35 | 36 | MESSAGE( STATUS "RXCPP_DIR: " ${RXCPP_DIR} ) 37 | 38 | include_directories(SYSTEM ${RXCPP_DIR}/ext/catch/include) 39 | include_directories(${RXCPP_DIR}/Ix/CPP/src ${RXCPP_DIR}/Rx/v2/src) 40 | 41 | # define the sources 42 | set(SAMPLE_SOURCES 43 | ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp 44 | ) 45 | add_executable(${SAMPLE_PROJECT} WIN32 ${SAMPLE_SOURCES}) 46 | TARGET_LINK_LIBRARIES(${SAMPLE_PROJECT} ${CMAKE_THREAD_LIBS_INIT}) 47 | 48 | # configure unit tests via CTest 49 | enable_testing() 50 | set(CTEST_CONFIGURATION_TYPE "${JOB_BUILD_CONFIGURATION}") 51 | 52 | add_test(NAME RunTests 53 | WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" 54 | COMMAND ${SAMPLE_PROJECT} ${TEST_ARGS}) -------------------------------------------------------------------------------- /Rx/v2/examples/win_text/unwinder.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace unwinder { namespace detail { 4 | 5 | template 6 | class unwinder 7 | { 8 | public: 9 | ~unwinder() noexcept 10 | { 11 | if (!!function) 12 | { 13 | (*function)(); 14 | } 15 | } 16 | 17 | explicit unwinder(Function* functionArg) 18 | : function(functionArg) 19 | { 20 | } 21 | 22 | void dismiss() 23 | { 24 | function = nullptr; 25 | } 26 | 27 | unwinder& operator=(nullptr_t) { 28 | dismiss(); 29 | return *this; 30 | } 31 | 32 | private: 33 | unwinder(); 34 | unwinder(const unwinder&); 35 | unwinder& operator=(const unwinder&); 36 | 37 | Function* function; 38 | }; 39 | } } 40 | 41 | #define UNWIND_MAKE_IDENTIFIER_EXPLICIT_PASTER(Prefix, Suffix) Prefix ## Suffix 42 | #define UNWIND_MAKE_IDENTIFIER_EXPLICIT(Prefix, Suffix) UNWIND_MAKE_IDENTIFIER_EXPLICIT_PASTER(Prefix, Suffix) 43 | 44 | #define UNWIND_MAKE_IDENTIFIER(Prefix) UNWIND_MAKE_IDENTIFIER_EXPLICIT(Prefix, __LINE__) 45 | 46 | #define ON_UNWIND(Name, Function) \ 47 | ON_UNWIND_EXPLICIT(uwfunc_ ## Name, Name, Function) 48 | 49 | #define ON_UNWIND_AUTO(Function) \ 50 | ON_UNWIND_EXPLICIT(UNWIND_MAKE_IDENTIFIER(uwfunc_), UNWIND_MAKE_IDENTIFIER(unwind_), Function) 51 | 52 | #define ON_UNWIND_EXPLICIT(FunctionName, UnwinderName, Function) \ 53 | auto FunctionName = (Function); \ 54 | ::unwinder::detail::unwinder UnwinderName(std::addressof(FunctionName)) 55 | -------------------------------------------------------------------------------- /Rx/v2/license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. 2 | Microsoft Open Technologies would like to thank its contributors, a list 3 | of whom are at http://rx.codeplex.com/wikipage?title=Contributors. 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); you 6 | may not use this file except in compliance with the License. You may 7 | obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 14 | implied. See the License for the specific language governing permissions 15 | and limitations under the License. -------------------------------------------------------------------------------- /Rx/v2/src/rxcpp/operators/rx-connect_forever.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. 2 | 3 | #pragma once 4 | 5 | /*! \file rx-connect_forever.hpp 6 | 7 | \brief takes a connectable_observable source and calls connect during the construction of the expression. 8 | This means that the source starts running without any subscribers and continues running after all subscriptions have been unsubscribed. 9 | 10 | \return An observable that emitting the items from its source. 11 | */ 12 | 13 | #if !defined(RXCPP_OPERATORS_RX_CONNECT_FOREVER_HPP) 14 | #define RXCPP_OPERATORS_RX_CONNECT_FOREVER_HPP 15 | 16 | #include "../rx-includes.hpp" 17 | 18 | namespace rxcpp { 19 | 20 | namespace operators { 21 | 22 | namespace detail { 23 | 24 | template 25 | struct connect_forever_invalid_arguments {}; 26 | 27 | template 28 | struct connect_forever_invalid : public rxo::operator_base> { 29 | using type = observable, connect_forever_invalid>; 30 | }; 31 | template 32 | using connect_forever_invalid_t = typename connect_forever_invalid::type; 33 | 34 | template 35 | struct connect_forever : public operator_base 36 | { 37 | using source_type = rxu::decay_t; 38 | 39 | source_type source; 40 | 41 | explicit connect_forever(source_type o) 42 | : source(std::move(o)) 43 | { 44 | source.connect(); 45 | } 46 | 47 | template 48 | void on_subscribe(Subscriber&& o) const { 49 | source.subscribe(std::forward(o)); 50 | } 51 | }; 52 | 53 | } 54 | 55 | /*! @copydoc rx-connect_forever.hpp 56 | */ 57 | template 58 | auto connect_forever(AN&&... an) 59 | -> operator_factory { 60 | return operator_factory(std::make_tuple(std::forward(an)...)); 61 | } 62 | 63 | } 64 | 65 | template<> 66 | struct member_overload 67 | { 68 | template>, 71 | class SourceValue = rxu::value_type_t, 72 | class ConnectForever = rxo::detail::connect_forever>, 73 | class Value = rxu::value_type_t, 74 | class Result = observable 75 | > 76 | static Result member(ConnectableObservable&& o) { 77 | return Result(ConnectForever(std::forward(o))); 78 | } 79 | 80 | template 81 | static operators::detail::connect_forever_invalid_t member(AN...) { 82 | std::terminate(); 83 | return {}; 84 | static_assert(sizeof...(AN) == 10000, "connect_forever takes no arguments"); 85 | } 86 | }; 87 | 88 | } 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /Rx/v2/src/rxcpp/operators/rx-ignore_elements.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. 2 | 3 | #pragma once 4 | 5 | /*! \file rx-ignore_elements.hpp 6 | 7 | \brief Do not emit any items from the source Observable, but allow termination notification (either onError or onCompleted) to pass through unchanged. 8 | 9 | \return Observable that emits termination notification from the source observable. 10 | 11 | \sample 12 | \snippet ignore_elements.cpp ignore_elements sample 13 | \snippet output.txt ignore_elements sample 14 | */ 15 | 16 | #if !defined(RXCPP_OPERATORS_RX_IGNORE_ELEMENTS_HPP) 17 | #define RXCPP_OPERATORS_RX_IGNORE_ELEMENTS_HPP 18 | 19 | #include "../rx-includes.hpp" 20 | 21 | namespace rxcpp { 22 | 23 | namespace operators { 24 | 25 | namespace detail { 26 | 27 | template 28 | struct ignore_elements_invalid_arguments {}; 29 | 30 | template 31 | struct ignore_elements_invalid : public rxo::operator_base> { 32 | using type = observable, ignore_elements_invalid>; 33 | }; 34 | template 35 | using ignore_elements_invalid_t = typename ignore_elements_invalid::type; 36 | 37 | template 38 | struct ignore_elements { 39 | using source_value_type = rxu::decay_t; 40 | 41 | template 42 | struct ignore_elements_observer 43 | { 44 | using this_type = ignore_elements_observer; 45 | using value_type = source_value_type; 46 | using dest_type = rxu::decay_t; 47 | using observer_type = observer; 48 | dest_type dest; 49 | 50 | ignore_elements_observer(dest_type d) 51 | : dest(d) 52 | { 53 | } 54 | 55 | void on_next(const source_value_type&) const { 56 | // no-op; ignore element 57 | } 58 | 59 | void on_error(rxu::error_ptr e) const { 60 | dest.on_error(e); 61 | } 62 | 63 | void on_completed() const { 64 | dest.on_completed(); 65 | } 66 | 67 | static subscriber make(dest_type d) { 68 | return make_subscriber(d, this_type(d)); 69 | } 70 | }; 71 | 72 | template 73 | auto operator()(Subscriber dest) const 74 | -> decltype(ignore_elements_observer::make(std::move(dest))) { 75 | return ignore_elements_observer::make(std::move(dest)); 76 | } 77 | }; 78 | 79 | } 80 | 81 | /*! @copydoc rx-ignore_elements.hpp 82 | */ 83 | template 84 | auto ignore_elements(AN&&... an) 85 | -> operator_factory { 86 | return operator_factory(std::make_tuple(std::forward(an)...)); 87 | } 88 | 89 | } 90 | 91 | template<> 92 | struct member_overload 93 | { 94 | template, 96 | class Enabled = rxu::enable_if_all_true_type_t< 97 | is_observable>, 98 | class IgnoreElements = rxo::detail::ignore_elements> 99 | static auto member(Observable&& o) 100 | -> decltype(o.template lift(IgnoreElements())) { 101 | return o.template lift(IgnoreElements()); 102 | } 103 | 104 | template 105 | static operators::detail::ignore_elements_invalid_t member(AN...) { 106 | std::terminate(); 107 | return {}; 108 | static_assert(sizeof...(AN) == 10000, "ignore_elements takes no arguments"); 109 | } 110 | }; 111 | 112 | } 113 | 114 | #endif 115 | -------------------------------------------------------------------------------- /Rx/v2/src/rxcpp/operators/rx-start_with.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. 2 | 3 | #pragma once 4 | 5 | /*! \file rx-start_with.hpp 6 | 7 | \brief Start with the supplied values, then concatenate this observable. 8 | 9 | \tparam Value0 ... 10 | \tparam ValueN the type of sending values 11 | 12 | \param v0 ... 13 | \param vn values to send 14 | 15 | \return Observable that emits the specified items and then emits the items emitted by the source observable. 16 | 17 | \sample 18 | \snippet start_with.cpp short start_with sample 19 | \snippet output.txt short start_with sample 20 | 21 | Another form of this operator, rxcpp::observable::start_with, gets the source observable as a parameter: 22 | \snippet start_with.cpp full start_with sample 23 | \snippet output.txt full start_with sample 24 | */ 25 | 26 | #if !defined(RXCPP_OPERATORS_RX_START_WITH_HPP) 27 | #define RXCPP_OPERATORS_RX_START_WITH_HPP 28 | 29 | #include "../rx-includes.hpp" 30 | #include "./rx-concat.hpp" 31 | 32 | namespace rxcpp { 33 | 34 | namespace operators { 35 | 36 | namespace detail { 37 | 38 | template 39 | struct start_with_invalid_arguments {}; 40 | 41 | template 42 | struct start_with_invalid : public rxo::operator_base> { 43 | using type = observable, start_with_invalid>; 44 | }; 45 | template 46 | using start_with_invalid_t = typename start_with_invalid::type; 47 | 48 | } 49 | 50 | /*! @copydoc rx-start_with.hpp 51 | */ 52 | template 53 | auto start_with(AN&&... an) 54 | -> operator_factory { 55 | return operator_factory(std::make_tuple(std::forward(an)...)); 56 | } 57 | 58 | } 59 | 60 | template<> 61 | struct member_overload 62 | { 63 | template>, 66 | class From = decltype(rxs::from(rxu::decay_t(std::declval()), rxu::decay_t(std::declval())...)) 67 | > 68 | static auto member(Observable&& o, Value0&& v0, ValueN&&... vn) 69 | -> decltype(member_overload::member(std::declval(), std::forward(o))) { 70 | auto first = rxs::from(rxu::decay_t(v0), rxu::decay_t(vn)...); 71 | return member_overload::member(first, std::forward(o)); 72 | } 73 | 74 | template 75 | static operators::detail::start_with_invalid_t member(const AN&...) { 76 | std::terminate(); 77 | return {}; 78 | static_assert(sizeof...(AN) == 10000, "start_with takes (Value0, optional ValueN...)"); 79 | } 80 | }; 81 | 82 | } 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /Rx/v2/src/rxcpp/rx-composite_exception.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. 2 | 3 | #pragma once 4 | 5 | #if !defined(RXCPP_SOURCES_RX_COMPOSITE_EXCEPTION_HPP) 6 | #define RXCPP_SOURCES_RX_COMPOSITE_EXCEPTION_HPP 7 | 8 | #include "rx-includes.hpp" 9 | 10 | namespace rxcpp { 11 | 12 | struct composite_exception : std::exception { 13 | 14 | using exception_values = std::vector; 15 | 16 | virtual const char *what() const RXCPP_NOEXCEPT override { 17 | return "rxcpp composite exception"; 18 | } 19 | 20 | virtual bool empty() const { 21 | return exceptions.empty(); 22 | } 23 | 24 | virtual composite_exception add(rxu::error_ptr exception_ptr) { 25 | exceptions.push_back(exception_ptr); 26 | return *this; 27 | } 28 | 29 | exception_values exceptions; 30 | }; 31 | 32 | } 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /Rx/v2/src/rxcpp/rx-lite.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. 2 | 3 | #pragma once 4 | 5 | #if !defined(RXCPP_RX_HPP) 6 | #define RXCPP_RX_HPP 7 | 8 | #define RXCPP_LITE 9 | #include "rx-includes.hpp" 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /Rx/v2/src/rxcpp/rx-observable-fwd.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. 2 | 3 | #pragma once 4 | 5 | #if !defined(RXCPP_RX_OBSERVABLE_FWD_HPP) 6 | #define RXCPP_RX_OBSERVABLE_FWD_HPP 7 | 8 | #include 9 | 10 | namespace rxcpp { 11 | 12 | template 13 | class dynamic_observable; 14 | 15 | template< 16 | class T = void, 17 | class SourceObservable = typename std::conditional_t, void, dynamic_observable>> 18 | class observable; 19 | 20 | template 21 | observable make_observable_dynamic(Source&&); 22 | 23 | } 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /Rx/v2/src/rxcpp/rx-sources.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. 3 | 4 | #pragma once 5 | 6 | #if !defined(RXCPP_RX_SOURCES_HPP) 7 | #define RXCPP_RX_SOURCES_HPP 8 | 9 | #include "rx-includes.hpp" 10 | 11 | namespace rxcpp { 12 | 13 | namespace sources { 14 | 15 | struct tag_source {}; 16 | template 17 | struct source_base 18 | { 19 | using value_type = T; 20 | using source_tag = tag_source; 21 | }; 22 | template 23 | class is_source 24 | { 25 | template 26 | static typename C::source_tag* check(int); 27 | template 28 | static void check(...); 29 | public: 30 | static const bool value = std::is_convertible>(0)), tag_source*>::value; 31 | }; 32 | 33 | } 34 | namespace rxs=sources; 35 | 36 | } 37 | 38 | #include "sources/rx-create.hpp" 39 | #include "sources/rx-range.hpp" 40 | #include "sources/rx-iterate.hpp" 41 | #include "sources/rx-interval.hpp" 42 | #include "sources/rx-empty.hpp" 43 | #include "sources/rx-defer.hpp" 44 | #include "sources/rx-never.hpp" 45 | #include "sources/rx-error.hpp" 46 | #include "sources/rx-scope.hpp" 47 | #include "sources/rx-timer.hpp" 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /Rx/v2/src/rxcpp/rx-subjects.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. 2 | 3 | #pragma once 4 | 5 | #if !defined(RXCPP_RX_SCHEDULER_SUBJECTS_HPP) 6 | #define RXCPP_RX_SCHEDULER_SUBJECTS_HPP 7 | 8 | #include "rx-includes.hpp" 9 | 10 | namespace rxcpp { 11 | 12 | namespace subjects { 13 | 14 | } 15 | namespace rxsub=subjects; 16 | 17 | } 18 | 19 | #include "subjects/rx-subject.hpp" 20 | #include "subjects/rx-behavior.hpp" 21 | #include "subjects/rx-replaysubject.hpp" 22 | #include "subjects/rx-synchronize.hpp" 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /Rx/v2/src/rxcpp/rx.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. 2 | 3 | #pragma once 4 | 5 | #if !defined(RXCPP_RX_HPP) 6 | #define RXCPP_RX_HPP 7 | 8 | #include "rx-includes.hpp" 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /Rx/v2/src/rxcpp/schedulers/rx-eventloop.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. 2 | 3 | #pragma once 4 | 5 | #if !defined(RXCPP_RX_SCHEDULER_EVENT_LOOP_HPP) 6 | #define RXCPP_RX_SCHEDULER_EVENT_LOOP_HPP 7 | 8 | #include "../rx-includes.hpp" 9 | 10 | namespace rxcpp { 11 | 12 | namespace schedulers { 13 | 14 | struct event_loop : public scheduler_interface 15 | { 16 | private: 17 | using this_type = event_loop; 18 | event_loop(const this_type&); 19 | 20 | struct loop_worker : public worker_interface 21 | { 22 | private: 23 | using this_type = loop_worker; 24 | loop_worker(const this_type&); 25 | 26 | using queue_item_time = detail::schedulable_queue; 27 | 28 | using item_type = queue_item_time::item_type; 29 | 30 | composite_subscription lifetime; 31 | worker controller; 32 | std::shared_ptr alive; 33 | 34 | public: 35 | virtual ~loop_worker() 36 | { 37 | } 38 | loop_worker(composite_subscription cs, worker w, std::shared_ptr alive) 39 | : lifetime(cs) 40 | , controller(w) 41 | , alive(alive) 42 | { 43 | auto token = controller.add(cs); 44 | cs.add([token, w](){ 45 | w.remove(token); 46 | }); 47 | } 48 | 49 | virtual clock_type::time_point now() const { 50 | return clock_type::now(); 51 | } 52 | 53 | virtual void schedule(const schedulable& scbl) const { 54 | controller.schedule(lifetime, scbl.get_action()); 55 | } 56 | 57 | virtual void schedule(clock_type::time_point when, const schedulable& scbl) const { 58 | controller.schedule(when, lifetime, scbl.get_action()); 59 | } 60 | }; 61 | 62 | mutable thread_factory factory; 63 | scheduler newthread; 64 | mutable std::atomic count; 65 | composite_subscription loops_lifetime; 66 | std::vector loops; 67 | 68 | public: 69 | event_loop() 70 | : factory([](std::function start){ 71 | return std::thread(std::move(start)); 72 | }) 73 | , newthread(make_new_thread()) 74 | , count(0) 75 | { 76 | auto remaining = std::max(std::thread::hardware_concurrency(), unsigned(4)); 77 | while (remaining--) { 78 | loops.push_back(newthread.create_worker(loops_lifetime)); 79 | } 80 | } 81 | explicit event_loop(thread_factory tf) 82 | : factory(tf) 83 | , newthread(make_new_thread(tf)) 84 | , count(0) 85 | { 86 | auto remaining = std::max(std::thread::hardware_concurrency(), unsigned(4)); 87 | while (remaining--) { 88 | loops.push_back(newthread.create_worker(loops_lifetime)); 89 | } 90 | } 91 | virtual ~event_loop() 92 | { 93 | loops_lifetime.unsubscribe(); 94 | } 95 | 96 | virtual clock_type::time_point now() const { 97 | return clock_type::now(); 98 | } 99 | 100 | virtual worker create_worker(composite_subscription cs) const { 101 | return worker(cs, std::make_shared(cs, loops[++count % loops.size()], this->shared_from_this())); 102 | } 103 | }; 104 | 105 | inline scheduler make_event_loop() { 106 | static scheduler instance = make_scheduler(); 107 | return instance; 108 | } 109 | inline scheduler make_event_loop(thread_factory tf) { 110 | return make_scheduler(tf); 111 | } 112 | 113 | } 114 | 115 | } 116 | 117 | #endif 118 | -------------------------------------------------------------------------------- /Rx/v2/src/rxcpp/schedulers/rx-immediate.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. 2 | 3 | #pragma once 4 | 5 | #if !defined(RXCPP_RX_SCHEDULER_IMMEDIATE_HPP) 6 | #define RXCPP_RX_SCHEDULER_IMMEDIATE_HPP 7 | 8 | #include "../rx-includes.hpp" 9 | 10 | namespace rxcpp { 11 | 12 | namespace schedulers { 13 | 14 | struct immediate : public scheduler_interface 15 | { 16 | private: 17 | using this_type = immediate; 18 | immediate(const this_type&); 19 | 20 | struct immediate_worker : public worker_interface 21 | { 22 | private: 23 | using this_type = immediate_worker; 24 | immediate_worker(const this_type&); 25 | public: 26 | virtual ~immediate_worker() 27 | { 28 | } 29 | immediate_worker() 30 | { 31 | } 32 | 33 | virtual clock_type::time_point now() const { 34 | return clock_type::now(); 35 | } 36 | 37 | virtual void schedule(const schedulable& scbl) const { 38 | if (scbl.is_subscribed()) { 39 | // allow recursion 40 | recursion r(true); 41 | scbl(r.get_recurse()); 42 | } 43 | } 44 | 45 | virtual void schedule(clock_type::time_point when, const schedulable& scbl) const { 46 | std::this_thread::sleep_until(when); 47 | if (scbl.is_subscribed()) { 48 | // allow recursion 49 | recursion r(true); 50 | scbl(r.get_recurse()); 51 | } 52 | } 53 | }; 54 | 55 | std::shared_ptr wi; 56 | 57 | public: 58 | immediate() 59 | : wi(std::make_shared()) 60 | { 61 | } 62 | virtual ~immediate() 63 | { 64 | } 65 | 66 | virtual clock_type::time_point now() const { 67 | return clock_type::now(); 68 | } 69 | 70 | virtual worker create_worker(composite_subscription cs) const { 71 | return worker(std::move(cs), wi); 72 | } 73 | }; 74 | 75 | inline const scheduler& make_immediate() { 76 | static scheduler instance = make_scheduler(); 77 | return instance; 78 | } 79 | 80 | } 81 | 82 | } 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /Rx/v2/src/rxcpp/schedulers/rx-sameworker.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. 2 | 3 | #pragma once 4 | 5 | #if !defined(RXCPP_RX_SCHEDULER_SAME_WORKER_HPP) 6 | #define RXCPP_RX_SCHEDULER_SAME_WORKER_HPP 7 | 8 | #include "../rx-includes.hpp" 9 | 10 | namespace rxcpp { 11 | 12 | namespace schedulers { 13 | 14 | struct same_worker : public scheduler_interface 15 | { 16 | private: 17 | using this_type = same_worker; 18 | same_worker(const this_type&); 19 | 20 | rxsc::worker controller; 21 | 22 | public: 23 | explicit same_worker(rxsc::worker w) 24 | : controller(std::move(w)) 25 | { 26 | } 27 | virtual ~same_worker() 28 | { 29 | } 30 | 31 | virtual clock_type::time_point now() const { 32 | return controller.now(); 33 | } 34 | 35 | virtual worker create_worker(composite_subscription cs) const { 36 | // use different lifetime 37 | auto inner_lifetime = controller.get_subscription(); 38 | auto token = inner_lifetime.add(cs); 39 | cs.add([inner_lifetime, token](){inner_lifetime.remove(token);}); 40 | return worker(cs, controller); 41 | } 42 | }; 43 | 44 | inline scheduler make_same_worker(rxsc::worker w) { 45 | return make_scheduler(std::move(w)); 46 | } 47 | 48 | } 49 | 50 | } 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /Rx/v2/src/rxcpp/sources/rx-create.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. 2 | 3 | #pragma once 4 | 5 | #if !defined(RXCPP_SOURCES_RX_CREATE_HPP) 6 | #define RXCPP_SOURCES_RX_CREATE_HPP 7 | 8 | #include "../rx-includes.hpp" 9 | 10 | /*! \file rx-create.hpp 11 | 12 | \brief Returns an observable that executes the specified function when a subscriber subscribes to it. 13 | 14 | \tparam T the type of the items that this observable emits 15 | \tparam OnSubscribe the type of OnSubscribe handler function 16 | 17 | \param os OnSubscribe event handler 18 | 19 | \return Observable that executes the specified function when a Subscriber subscribes to it. 20 | 21 | \sample 22 | \snippet create.cpp Create sample 23 | \snippet output.txt Create sample 24 | 25 | \warning 26 | It is good practice to check the observer's is_subscribed state from within the function you pass to create 27 | so that your observable can stop emitting items or doing expensive calculations when there is no longer an interested observer. 28 | 29 | \badcode 30 | \snippet create.cpp Create bad code 31 | \snippet output.txt Create bad code 32 | 33 | \goodcode 34 | \snippet create.cpp Create good code 35 | \snippet output.txt Create good code 36 | 37 | \warning 38 | It is good practice to use operators like observable::take to control lifetime rather than use the subscription explicitly. 39 | 40 | \goodcode 41 | \snippet create.cpp Create great code 42 | \snippet output.txt Create great code 43 | */ 44 | 45 | namespace rxcpp { 46 | 47 | namespace sources { 48 | 49 | namespace detail { 50 | 51 | template 52 | struct create : public source_base 53 | { 54 | using this_type = create; 55 | 56 | using on_subscribe_type = rxu::decay_t; 57 | 58 | on_subscribe_type on_subscribe_function; 59 | 60 | create(on_subscribe_type os) 61 | : on_subscribe_function(std::move(os)) 62 | { 63 | } 64 | 65 | template 66 | void on_subscribe(Subscriber o) const { 67 | 68 | on_exception( 69 | [&](){ 70 | this->on_subscribe_function(o); 71 | return true; 72 | }, 73 | o); 74 | } 75 | }; 76 | 77 | } 78 | 79 | /*! @copydoc rx-create.hpp 80 | */ 81 | template 82 | auto create(OnSubscribe os) 83 | -> observable> { 84 | return observable>( 85 | detail::create(std::move(os))); 86 | } 87 | 88 | } 89 | 90 | } 91 | 92 | #endif 93 | -------------------------------------------------------------------------------- /Rx/v2/src/rxcpp/sources/rx-defer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. 2 | 3 | #pragma once 4 | 5 | #if !defined(RXCPP_SOURCES_RX_DEFER_HPP) 6 | #define RXCPP_SOURCES_RX_DEFER_HPP 7 | 8 | #include "../rx-includes.hpp" 9 | 10 | /*! \file rx-defer.hpp 11 | 12 | \brief Returns an observable that calls the specified observable factory to create an observable for each new observer that subscribes. 13 | 14 | \tparam ObservableFactory the type of the observable factory 15 | 16 | \param of the observable factory function to invoke for each observer that subscribes to the resulting observable 17 | 18 | \return observable whose observers' subscriptions trigger an invocation of the given observable factory function 19 | 20 | \sample 21 | \snippet defer.cpp defer sample 22 | \snippet output.txt defer sample 23 | */ 24 | 25 | namespace rxcpp { 26 | 27 | namespace sources { 28 | 29 | namespace detail { 30 | 31 | template 32 | struct defer_traits 33 | { 34 | using observable_factory_type = rxu::decay_t; 35 | using collection_type = decltype(std::declval()()); 36 | using value_type = typename collection_type::value_type; 37 | }; 38 | 39 | template 40 | struct defer : public source_base>> 41 | { 42 | using this_type = defer; 43 | using traits = defer_traits; 44 | 45 | using observable_factory_type = typename traits::observable_factory_type; 46 | using collection_type = typename traits::collection_type; 47 | 48 | observable_factory_type observable_factory; 49 | 50 | defer(observable_factory_type of) 51 | : observable_factory(std::move(of)) 52 | { 53 | } 54 | template 55 | void on_subscribe(Subscriber o) const { 56 | 57 | auto selectedCollection = on_exception( 58 | [this](){return this->observable_factory();}, 59 | o); 60 | if (selectedCollection.empty()) { 61 | return; 62 | } 63 | 64 | selectedCollection->subscribe(o); 65 | } 66 | }; 67 | 68 | } 69 | 70 | /*! @copydoc rx-defer.hpp 71 | */ 72 | template 73 | auto defer(ObservableFactory of) 74 | -> observable>, detail::defer> { 75 | return observable>, detail::defer>( 76 | detail::defer(std::move(of))); 77 | } 78 | 79 | } 80 | 81 | } 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /Rx/v2/src/rxcpp/sources/rx-empty.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. 2 | 3 | #pragma once 4 | 5 | #if !defined(RXCPP_SOURCES_RX_EMPTY_HPP) 6 | #define RXCPP_SOURCES_RX_EMPTY_HPP 7 | 8 | #include "../rx-includes.hpp" 9 | 10 | /*! \file rx-empty.hpp 11 | 12 | \brief Returns an observable that sends no items to observer and immediately completes, on the specified scheduler. 13 | 14 | \tparam T the type of (not) emitted items 15 | \tparam Coordination the type of the scheduler (optional) 16 | 17 | \param cn the scheduler to use for scheduling the items (optional) 18 | 19 | \return Observable that sends no items to observer and immediately completes. 20 | 21 | \sample 22 | \snippet empty.cpp empty sample 23 | \snippet output.txt empty sample 24 | 25 | \sample 26 | \snippet empty.cpp threaded empty sample 27 | \snippet output.txt threaded empty sample 28 | */ 29 | 30 | namespace rxcpp { 31 | 32 | namespace sources { 33 | 34 | /*! @copydoc rx-empty.hpp 35 | */ 36 | template 37 | auto empty() 38 | -> decltype(from()) { 39 | return from(); 40 | } 41 | /*! @copydoc rx-empty.hpp 42 | */ 43 | template 44 | auto empty(Coordination cn) 45 | -> decltype(from(std::move(cn))) { 46 | return from(std::move(cn)); 47 | } 48 | 49 | } 50 | 51 | } 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /Rx/v2/src/rxcpp/sources/rx-never.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. 2 | 3 | #pragma once 4 | 5 | #if !defined(RXCPP_SOURCES_RX_NEVER_HPP) 6 | #define RXCPP_SOURCES_RX_NEVER_HPP 7 | 8 | #include "../rx-includes.hpp" 9 | 10 | /*! \file rx-never.hpp 11 | 12 | \brief Returns an observable that never sends any items or notifications to observer. 13 | 14 | \tparam T the type of (not) emitted items 15 | 16 | \return Observable that never sends any items or notifications to observer. 17 | 18 | \sample 19 | \snippet never.cpp never sample 20 | \snippet output.txt never sample 21 | */ 22 | 23 | namespace rxcpp { 24 | 25 | namespace sources { 26 | 27 | namespace detail { 28 | 29 | template 30 | struct never : public source_base 31 | { 32 | template 33 | void on_subscribe(Subscriber) const { 34 | } 35 | }; 36 | 37 | } 38 | 39 | /*! @copydoc rx-never.hpp 40 | */ 41 | template 42 | auto never() 43 | -> observable> { 44 | return observable>(detail::never()); 45 | } 46 | 47 | } 48 | 49 | } 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /Rx/v2/src/rxcpp/subjects/rx-behavior.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. 2 | 3 | #pragma once 4 | 5 | #if !defined(RXCPP_RX_BEHAVIOR_HPP) 6 | #define RXCPP_RX_BEHAVIOR_HPP 7 | 8 | #include "../rx-includes.hpp" 9 | 10 | namespace rxcpp { 11 | 12 | namespace subjects { 13 | 14 | namespace detail { 15 | 16 | template 17 | class behavior_observer : public detail::multicast_observer 18 | { 19 | using this_type = behavior_observer; 20 | using base_type = detail::multicast_observer; 21 | 22 | class behavior_observer_state : public std::enable_shared_from_this 23 | { 24 | mutable std::mutex lock; 25 | mutable T value; 26 | 27 | public: 28 | behavior_observer_state(T first) 29 | : value(first) 30 | { 31 | } 32 | 33 | void reset(T v) const { 34 | std::unique_lock guard(lock); 35 | value = std::move(v); 36 | } 37 | T get() const { 38 | std::unique_lock guard(lock); 39 | return value; 40 | } 41 | }; 42 | 43 | std::shared_ptr state; 44 | 45 | public: 46 | behavior_observer(T f, composite_subscription l) 47 | : base_type(l) 48 | , state(std::make_shared(std::move(f))) 49 | { 50 | } 51 | 52 | subscriber get_subscriber() const { 53 | return make_subscriber(this->get_id(), this->get_subscription(), observer>(*this)).as_dynamic(); 54 | } 55 | 56 | T get_value() const { 57 | return state->get(); 58 | } 59 | 60 | template 61 | void on_next(V v) const { 62 | state->reset(v); 63 | base_type::on_next(std::move(v)); 64 | } 65 | }; 66 | 67 | } 68 | 69 | template 70 | class behavior 71 | { 72 | detail::behavior_observer s; 73 | 74 | public: 75 | explicit behavior(T f, composite_subscription cs = composite_subscription()) 76 | : s(std::move(f), cs) 77 | { 78 | } 79 | 80 | bool has_observers() const { 81 | return s.has_observers(); 82 | } 83 | 84 | T get_value() const { 85 | return s.get_value(); 86 | } 87 | 88 | subscriber get_subscriber() const { 89 | return s.get_subscriber(); 90 | } 91 | 92 | observable get_observable() const { 93 | auto keepAlive = s; 94 | return make_observable_dynamic([keepAlive](subscriber o){ 95 | if (keepAlive.get_subscription().is_subscribed()) { 96 | o.on_next(keepAlive.get_value()); 97 | } 98 | keepAlive.add(keepAlive.get_subscriber(), std::move(o)); 99 | }); 100 | } 101 | }; 102 | 103 | } 104 | 105 | } 106 | 107 | #endif 108 | -------------------------------------------------------------------------------- /Rx/v2/test/copy_verifier.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class copy_verifier 6 | { 7 | public: 8 | copy_verifier() 9 | : _state(std::make_shared()) {} 10 | 11 | copy_verifier(const copy_verifier& other) 12 | : _state{other._state} 13 | { 14 | ++_state->copy_count; 15 | } 16 | 17 | copy_verifier(copy_verifier&& other) noexcept 18 | : _state{other._state} 19 | { 20 | ++_state->move_count; 21 | } 22 | 23 | copy_verifier& operator=(const copy_verifier& other) 24 | { 25 | if (this == &other) 26 | return *this; 27 | _state = other._state; 28 | ++_state->copy_count; 29 | return *this; 30 | } 31 | 32 | copy_verifier& operator=(copy_verifier&& other) noexcept 33 | { 34 | if (this == &other) 35 | return *this; 36 | _state = other._state; 37 | ++_state->move_count; 38 | return *this; 39 | } 40 | 41 | int get_copy_count() const { return _state->copy_count; } 42 | int get_move_count() const { return _state->move_count; } 43 | 44 | rxcpp::observable get_observable(size_t count = 1) 45 | { 46 | return rxcpp::observable<>::create([this, count](rxcpp::subscriber sub) 47 | { 48 | for (size_t i =0; i< count; ++i) 49 | sub.on_next(*this); 50 | sub.on_completed(); 51 | }); 52 | } 53 | 54 | rxcpp::observable get_observable_for_move(size_t count = 1) 55 | { 56 | return rxcpp::observable<>::create([this, count](rxcpp::subscriber sub) 57 | { 58 | for (size_t i =0; i< count; ++i) 59 | sub.on_next(std::move(*this)); 60 | sub.on_completed(); 61 | }); 62 | } 63 | 64 | bool operator==(const copy_verifier&) const { return false; } 65 | bool operator!=(const copy_verifier&) const { return true; } 66 | private: 67 | struct state 68 | { 69 | int copy_count = 0; 70 | int move_count = 0; 71 | }; 72 | 73 | std::shared_ptr _state; 74 | }; 75 | -------------------------------------------------------------------------------- /Rx/v2/test/sources/empty.cpp: -------------------------------------------------------------------------------- 1 | #include "../test.h" 2 | 3 | SCENARIO("empty emits no items", "[empty][sources]"){ 4 | GIVEN("an empty source"){ 5 | auto sc = rxsc::make_test(); 6 | auto w = sc.create_worker(); 7 | const rxsc::test::messages on; 8 | 9 | WHEN("created"){ 10 | 11 | auto res = w.start( 12 | []() { 13 | return rx::observable<>::empty() 14 | // forget type to workaround lambda deduction bug on msvc 2013 15 | .as_dynamic(); 16 | } 17 | ); 18 | 19 | THEN("the output only contains the completion message"){ 20 | auto required = rxu::to_vector({ 21 | on.completed(200) 22 | }); 23 | auto actual = res.get_observer().messages(); 24 | REQUIRE(required == actual); 25 | } 26 | 27 | } 28 | } 29 | } 30 | 31 | SCENARIO("empty emits no items (rx::sources)", "[empty][sources]"){ 32 | GIVEN("an empty source"){ 33 | auto sc = rxsc::make_test(); 34 | auto w = sc.create_worker(); 35 | const rxsc::test::messages on; 36 | 37 | WHEN("created"){ 38 | using namespace rx::sources; 39 | 40 | auto res = w.start( 41 | []() { 42 | return empty() 43 | // forget type to workaround lambda deduction bug on msvc 2013 44 | .as_dynamic(); 45 | } 46 | ); 47 | 48 | THEN("the output only contains the completion message"){ 49 | auto required = rxu::to_vector({ 50 | on.completed(200) 51 | }); 52 | auto actual = res.get_observer().messages(); 53 | REQUIRE(required == actual); 54 | } 55 | 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Rx/v2/test/sources/timer.cpp: -------------------------------------------------------------------------------- 1 | #include "../test.h" 2 | 3 | SCENARIO("timer", "[!hide][periodically][timer][scheduler][long][perf][sources]"){ 4 | GIVEN("the timer of 1 sec"){ 5 | WHEN("the period is 1 sec"){ 6 | using namespace std::chrono; 7 | 8 | auto sc = rxsc::make_current_thread(); 9 | auto so = rx::synchronize_in_one_worker(sc); 10 | auto start = sc.now(); 11 | auto period = seconds(1); 12 | rx::composite_subscription cs; 13 | rx::observable<>::timer(period, so) 14 | .subscribe( 15 | cs, 16 | [=](long counter){ 17 | auto nsDelta = duration_cast(sc.now() - (start + (period * counter))); 18 | std::cout << "timer : period " << counter << ", " << nsDelta.count() << "ms delta from target time" << std::endl; 19 | }, 20 | [](rxu::error_ptr){abort();}, 21 | [](){std::cout << "completed" << std::endl;}); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Rx/v2/test/test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #if (__GLIBCXX__ / 10000) == 2014 || (__GLIBCXX__ / 10000) == 2015 3 | namespace std { 4 | inline bool uncaught_exception() noexcept(true) { 5 | return current_exception() != nullptr; 6 | } 7 | } 8 | #endif 9 | 10 | #define CATCH_CONFIG_MAIN 11 | #include "catch.hpp" 12 | -------------------------------------------------------------------------------- /Rx/v2/test/test.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #if (__GLIBCXX__ / 10000) == 2014 || (__GLIBCXX__ / 10000) == 2015 5 | namespace std { 6 | inline bool uncaught_exception() noexcept(true) { 7 | return current_exception() != nullptr; 8 | } 9 | } 10 | #endif 11 | 12 | #include "rxcpp/rx-lite.hpp" 13 | namespace rx=rxcpp; 14 | namespace rxu=rxcpp::util; 15 | namespace rxs=rxcpp::sources; 16 | namespace rxo=rxcpp::operators; 17 | namespace rxsub=rxcpp::subjects; 18 | namespace rxsc=rxcpp::schedulers; 19 | namespace rxn=rx::notifications; 20 | 21 | #include "rxcpp/rx-test.hpp" 22 | namespace rxt = rxcpp::test; 23 | 24 | #include "catch.hpp" 25 | 26 | #include "copy_verifier.h" 27 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 2.2.{build} 2 | 3 | branches: 4 | # whitelist 5 | only: 6 | - main 7 | - appveyor 8 | 9 | image: Visual Studio 2017 10 | 11 | environment: 12 | matrix: 13 | - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 14 | VSVER: Visual Studio 14 2015 Win64 15 | - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 16 | VSVER: Visual Studio 15 2017 Win64 17 | 18 | platform: 19 | - x64 20 | 21 | configuration: 22 | - Release 23 | 24 | install: 25 | - cmake --version 26 | - git submodule -q update --init 27 | 28 | before_build: 29 | - cmake -G"%VSVER%" . 30 | 31 | build: 32 | project: build\rxcpp.sln 33 | 34 | test_script: 35 | - cd build\test\ 36 | - ctest -V -C Release 37 | - cd ..\.. 38 | 39 | artifacts: 40 | - path: Rx\v2\src\ 41 | name: rxcpp source 42 | type: zip 43 | - path: Rx\v2\examples\ 44 | name: rxcpp examples 45 | type: zip 46 | 47 | notifications: 48 | - provider: Webhook 49 | url: https://webhooks.gitter.im/e/4c53c094183ccaa8d059 50 | method: POST 51 | on_build_success: true 52 | on_build_failure: true 53 | on_build_status_changed: false 54 | - provider: Email 55 | to: 56 | - kirk.shoop@gmail.com 57 | on_build_success: true 58 | on_build_failure: true 59 | on_build_status_changed: false 60 | -------------------------------------------------------------------------------- /projects/CMake/shared.cmake: -------------------------------------------------------------------------------- 1 | FIND_PACKAGE(Threads) 2 | 3 | option(RX_USE_EXCEPTIONS "Use C++ exceptions" ON) 4 | 5 | # define some compiler settings 6 | 7 | MESSAGE( STATUS "CMAKE_CXX_COMPILER_ID: " ${CMAKE_CXX_COMPILER_ID} ) 8 | 9 | if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") 10 | MESSAGE( STATUS "clang compiler version: " ${CMAKE_CXX_COMPILER_VERSION} ) 11 | MESSAGE( STATUS "using clang settings" ) 12 | set(RX_COMPILE_OPTIONS 13 | -Wall -Wextra -Werror -Wunused 14 | -stdlib=libc++ 15 | -Wno-error=unused-command-line-argument 16 | -ftemplate-depth=1024 17 | ) 18 | if (NOT RX_USE_EXCEPTIONS) 19 | MESSAGE( STATUS "no exceptions" ) 20 | list(APPEND RX_COMPILE_OPTIONS -fno-exceptions) 21 | endif() 22 | elseif (CMAKE_CXX_COMPILER_ID MATCHES "GNU") 23 | MESSAGE( STATUS "gnu compiler version: " ${CMAKE_CXX_COMPILER_VERSION} ) 24 | MESSAGE( STATUS "using gnu settings" ) 25 | set(RX_COMPILE_OPTIONS 26 | -Wall -Wextra -Werror -Wunused 27 | ) 28 | if (NOT RX_USE_EXCEPTIONS) 29 | MESSAGE( STATUS "no exceptions" ) 30 | list(APPEND RX_COMPILE_OPTIONS -fno-exceptions) 31 | endif() 32 | elseif (CMAKE_CXX_COMPILER_ID MATCHES "MSVC") 33 | MESSAGE( STATUS "msvc compiler version: " ${CMAKE_CXX_COMPILER_VERSION} ) 34 | MESSAGE( STATUS "using msvc settings" ) 35 | set(RX_COMPILE_OPTIONS 36 | /W4 /WX 37 | /wd4503 # truncated symbol 38 | /wd4702 # unreachable code 39 | /bigobj 40 | /DUNICODE /D_UNICODE # it is a new millenium 41 | ) 42 | if (NOT RX_USE_EXCEPTIONS) 43 | MESSAGE( STATUS "no exceptions" ) 44 | list(APPEND RX_COMPILE_OPTIONS /EHs-c-) 45 | endif() 46 | if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "19.0.23506.0") 47 | MESSAGE( STATUS "with coroutines" ) 48 | list(APPEND RX_COMPILE_OPTIONS 49 | /await # enable coroutines 50 | ) 51 | endif() 52 | endif() 53 | 54 | set(RX_COMPILE_FEATURES cxx_std_14) 55 | 56 | set(IX_SRC_DIR ${RXCPP_DIR}/Ix/CPP/src) 57 | set(RX_SRC_DIR ${RXCPP_DIR}/Rx/v2/src) 58 | set(RX_CATCH_DIR ${RXCPP_DIR}/ext/catch/single_include/catch2) 59 | -------------------------------------------------------------------------------- /projects/doxygen/footer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | 14 | 19 | 20 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /projects/doxygen/mainpage.dox: -------------------------------------------------------------------------------- 1 | /*! 2 | \mainpage 3 | 4 | RxCpp is an implementation of the Observable/Observer pattern and a set of operations. It is an async equivalent of the container/iterator pattern and the set of algorithms found in the STL. 5 | 6 | \par Resources for Learning about Reactive Extentions 7 | 8 | Introduction to Rx --- http://www.introtorx.com 9 | 10 | Interactive diagrams of Rx Observables --- http://rxmarbles.com 11 | 12 | Reactive Extensions portal --- http://reactivex.io 13 | 14 | Reactive Extensions tutorial --- http://reactive-extensions.github.io/learnrx/ 15 | 16 | \par RxCpp specific 17 | 18 | Start here --- \ref group-core 19 | 20 | Github --- https://github.com/Reactive-Extensions/RxCpp 21 | 22 | \par readme.html 23 | 24 | \htmlinclude Readme.html 25 | */ 26 | -------------------------------------------------------------------------------- /projects/nuget/release.txt: -------------------------------------------------------------------------------- 1 | Write-NuGetPackage .\rxcpp.autoconfig 2 | Publish-NuGetPackage -Packages .\rxcpp.4.0.0.nupkg 3 | -------------------------------------------------------------------------------- /projects/nuget/rxcpp.autoconfig: -------------------------------------------------------------------------------- 1 | nuget { 2 | nuspec { 3 | id = rxcpp; 4 | version : 4.0.0; 5 | title: Reactive Extensions for C++; 6 | authors: {Microsoft Open Technologies Inc.}; 7 | owners: {Microsoft Open Technologies Inc.}; 8 | licenseUrl: "https://github.com/Reactive-Extensions/RxCpp/blob/master/license.md"; 9 | projectUrl: "https://github.com/Reactive-Extensions/RxCpp"; 10 | iconUrl: "http://go.microsoft.com/fwlink/?LinkId=261274"; 11 | requireLicenseAcceptance:false; 12 | summary: "The Reactive Extensions (Rx) asynchronous algorithm library"; 13 | description: @"The Reactive Extensions for C++ (RxCpp) is a library of algorithms for values-distributed-in-time. The Range-v3 library does the same for values-distributed-in-space. 14 | Compiles for gcc, clang and VisualStudio on Linux, OSX and Windows."; 15 | releaseNotes: "rx lite complete!, bug fixes, breaking changes to make repeat(0) and retry(0), VC2017 support, coroutines support, take_while, is_empty"; 16 | copyright: Copyright 2016; 17 | tags: { RxCpp, RxC++, Rx, Reactive, Observable, Functional, native, nativepackage}; 18 | }; 19 | 20 | files { 21 | 22 | #defines { 23 | SDK_RX = ..\..\; 24 | } 25 | include: { "${SDK_RX}Rx\v2\src\**\*" }; 26 | docs: { ${SDK_RX}AUTHORS.txt, ${SDK_RX}Rx\v2\license.txt, ${SDK_RX}Rx\v2\examples\**\* }; 27 | } 28 | 29 | targets { 30 | Defines += HAS_RXCPP; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /projects/scripts/install_libcxx.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Install libc++ under travis 4 | 5 | svn --quiet co http://llvm.org/svn/llvm-project/libcxx/trunk libcxx 6 | mkdir libcxx/build 7 | (cd libcxx/build && cmake .. -DLIBCXX_CXX_ABI=libstdc++ -DLIBCXX_CXX_ABI_INCLUDE_PATHS="/usr/include/c++/4.6;/usr/include/c++/4.6/x86_64-linux-gnu") 8 | make -C libcxx/build cxx -j2 9 | sudo cp libcxx/build/lib/libc++.so.1.0 /usr/lib/ 10 | sudo cp -r libcxx/build/include/c++/v1 /usr/include/c++/v1/ 11 | sudo ln -sf /usr/lib/libc++.so.1.0 /usr/lib/libc++.so 12 | sudo ln -sf /usr/lib/libc++.so.1.0 /usr/lib/libc++.so.1 -------------------------------------------------------------------------------- /projects/scripts/travis-doxygen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | if [ -n "$GH_TOKEN" ]; then 6 | cd projects/doxygen/html 7 | git init 8 | git config user.name "Kirk Shoop" 9 | git config user.email "kirk.shoop@microsoft.com" 10 | git add * 11 | git commit -m "doxygen generated site" 12 | git push --force "https://${GH_TOKEN}@github.com/Reactive-Extensions/RxCpp.git" master:gh-pages 13 | fi 14 | -------------------------------------------------------------------------------- /projects/scripts/travis-install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | echo "TRAVIS_OS_NAME=$TRAVIS_OS_NAME" 6 | 7 | #if OS is linux or is not set 8 | if [ "$TRAVIS_OS_NAME" = linux -o -z "$TRAVIS_OS_NAME" ]; then 9 | 10 | wget http://www.cmake.org/files/v3.2/cmake-3.2.3-Linux-x86_64.sh 11 | chmod a+x cmake-3.2.3-Linux-x86_64.sh 12 | sudo ./cmake-3.2.3-Linux-x86_64.sh --skip-license --prefix=/usr/local 13 | export PATH=/usr/local/bin:$PATH 14 | 15 | cmake --version 16 | 17 | elif [ "$TRAVIS_OS_NAME" = osx ]; then 18 | 19 | xcode-select --install 20 | brew update || echo "suppress failures in order to ignore warnings" 21 | brew doctor || echo "suppress failures in order to ignore warnings" 22 | brew list cmake || echo "suppress failures in order to ignore warnings" 23 | sudo brew uninstall --force cmake || "suppress failures in order to ignore warnings" 24 | brew search cmake || echo "suppress failures in order to ignore warnings" 25 | brew install cmake || echo "suppress failures in order to ignore warnings" 26 | brew upgrade cmake || echo "suppress failures in order to ignore warnings" 27 | 28 | cmake --version 29 | fi 30 | 31 | --------------------------------------------------------------------------------