From 6c9b142b78c3197b1bc4a7f359b7c4b0832ad3ff Mon Sep 17 00:00:00 2001 From: jonnew Date: Wed, 7 Dec 2016 20:20:44 -0500 Subject: [PATCH 1/8] Hacking up this repo to test usefulness for neural data processing. --- .clang-format | 90 +++++++ CMakeLists.txt | 2 +- examples/CMakeLists.txt | 4 + examples/src/SpikeDetect.cpp | 85 +++++++ examples/src/SpikeDetect.h | 185 ++++++++++++++ examples/src/filt.cpp | 266 ++++++++++++++++++++ examples/src/filt.h | 162 ++++++++++++ include/react/detail/graph/AlgorithmNodes.h | 10 +- 8 files changed, 802 insertions(+), 2 deletions(-) create mode 100644 .clang-format create mode 100644 examples/src/SpikeDetect.cpp create mode 100644 examples/src/SpikeDetect.h create mode 100644 examples/src/filt.cpp create mode 100644 examples/src/filt.h diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..77537cd8 --- /dev/null +++ b/.clang-format @@ -0,0 +1,90 @@ +--- +Language: Cpp +# BasedOnStyle: WebKit +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlinesLeft: false +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Inline +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: true +BinPackArguments: false +BinPackParameters: false +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false +BreakBeforeBinaryOperators: All +BreakBeforeBraces: Custom +BreakBeforeTernaryOperators: false +BreakConstructorInitializersBeforeComma: false +ColumnLimit: 80 +CommentPragmas: '\*/' +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 0 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +ForEachMacros: [ ] +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + - Regex: '^(<|"(gtest|isl|json)/)' + Priority: 3 + - Regex: '.*' + Priority: 1 +IndentCaseLabels: true +IndentWidth: 4 +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: Inner +ObjCBlockIndentWidth: 4 +ObjCSpaceAfterProperty: true +ObjCSpaceBeforeProtocolList: true +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 0 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Right +ReflowComments: true +SortIncludes: true +SpaceAfterCStyleCast: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +TabWidth: 4 +UseTab: Never +... + diff --git a/CMakeLists.txt b/CMakeLists.txt index ae21be06..9488f9d3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,7 +28,7 @@ if(build_examples) endif() ### benchmarks/ -option(build_benchmarks "Build benchmarks?" OFF) +option(build_benchmarks "Build benchmarks?" ON) if(build_benchmarks) add_subdirectory(benchmarks) endif() diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 940479ae..56747b7a 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -37,3 +37,7 @@ target_link_libraries(Example_BasicSynchronization CppReact) ### Example_Sandbox add_executable(Example_Sandbox src/Main.cpp) target_link_libraries(Example_Sandbox CppReact) + +### Spike det +add_executable(SpikeDetect src/SpikeDetect.cpp src/filt.cpp) +target_link_libraries(SpikeDetect CppReact) diff --git a/examples/src/SpikeDetect.cpp b/examples/src/SpikeDetect.cpp new file mode 100644 index 00000000..eefd8b1d --- /dev/null +++ b/examples/src/SpikeDetect.cpp @@ -0,0 +1,85 @@ +#include "SpikeDetect.h" + +int main() +{ + REACTIVE_DOMAIN(D, sequential) + + const size_t N = 256; + + using raw_size_t = std::array, N>::size_type; + + // Time + Time time(30.0e3); + std::cout << "Sample period: " << time.Ts << std::endl; + + // 256 electrodes + //std::vector> electrodes {256, time}; + + // 256 raw data sources, bandpass filters + std::array, N> raw; + + for (raw_size_t i = 0; i < N; i++) + raw[i] = MakeEventSource(); + + //BandPassFilter filter(time, raw[0]); + std::vector> filters; + for (auto &r :raw) + filters.emplace_back(time, r); + + //std::cout << "Filter N: " << filters.size() << std::endl; + + // Are merged into 1 TT + using Tetrode = NTrode, + Events, + Events, + Events>; + + //Tetrode tt(time, + // 0.01, + // filters[0].Out, + // filters[1].Out, + // filters[2].Out, + // filters[3].Out); + + ////SpikeDetector detector(filter.Out, 0.1); + + Observe(time.Count, [](uint64_t count) { + std::cout << "Current sample: " << count << std::endl; + }); + + Observe(time.Seconds, [](double sec) { + std::cout << "Current seconds: " << sec << std::endl; + }); + + //Observe(filter.Out, [](double out) { + // std::cout << "Current value: " << out << std::endl; + //}); + + // ///////////////////// + // HARDWARE SIMULATION + // This is simulating 100 transactions hardware + for (int i = 0; i < 100; i++) { + + std::random_device rd; + std::mt19937 gen(rd()); + std::normal_distribution<> d(0, 1); + + // Make a sample block coming from 4 contacts + for (int j = 0; j < BLOCKSIZE; j++) { + + // Graph update step + DoTransaction([&] { + + // Increment sample counter + time.NewSample(); + + // Make noise on all electrodes + for (auto &r : raw) + r << d(gen); + }); + } + } + + return 0; +} diff --git a/examples/src/SpikeDetect.h b/examples/src/SpikeDetect.h new file mode 100644 index 00000000..657f0a38 --- /dev/null +++ b/examples/src/SpikeDetect.h @@ -0,0 +1,185 @@ +#include +#include +#include +#include +#include +#include + +#include "filt.h" +#include "react/Algorithm.h" +#include "react/Domain.h" +#include "react/Event.h" +#include "react/Observer.h" +#include "react/Signal.h" +#include "react/common/Util.h" + +#define BLOCKSIZE 10 +#define SPK_PRE_SAMP 10 +#define SPK_POST_SAMP 22 + +using namespace react; + +template +struct Incrementer { + T operator()(Token, T v) const { return v + 1; } +}; + +enum {out_spike, in_spike}; + +template +class Time +{ +public: + USING_REACTIVE_DOMAIN(D) + + double Ts; + EventSourceT<> NewSample = MakeEventSource(); + SignalT Count = Iterate(NewSample, (uint64_t)0, Incrementer()); + SignalT Seconds + = Iterate(NewSample, 0.0, [&](Token, double sec) { return sec + Ts; }); + + Time(double sample_rate_hz) + : Ts(1.0 / sample_rate_hz) + { + // Nothing + } +}; + +//template +//class Electrode { +//public: +// USING_REACTIVE_DOMAIN(D) +// +// // Samples collected from API +// EventSourceT Out = MakeEventSource(); +// +// Electrode(Time &time) +// : time_(time) +// { +// // Nothing +// } +// +//private: +// Time &time_; +//}; + +//template +//class Spike +//{ +//public: +// +// double Waveform[E][L]; +// +// // Note: To be used as a signal value type, +// // values of the type must be comparable +// //bool operator==(const Spike& other) const +// //{ +// // return this == &other; +// //} +//}; + +template +class NTrode { +public: + USING_REACTIVE_DOMAIN(D) + + //SignalT> Spikes = Iterate(voltages_, [&]() { + + Signal Spikes + = Iterate(voltages_, 0.0, [&](double v, double spk) { + + // If detector is set and we are over threshold + set_ = !(set_ && v > thresh_); + + // If we are at at the end of detected spike and we are ready to + // transmitted the buffer + if (!set_ && !dead_count_--) { + set_ = true; + dead_count_ = sizeof...(Ts) * SPK_POST_SAMP; + return 42.0; + } else { + return 0.0; + } + + }); + + // Update buffer + // waveform_buffer_.emplace{ + // voltages_ + // Is current sample over threshold? If so, emit + + NTrode(Time& time, double thresh, Ts& ...sources) + : time_(time) + , thresh_(thresh) + { + voltages_ = Merge(sources...); + waveform_buffer_.resize(SPK_POST_SAMP + SPK_PRE_SAMP); + } + +private: + Time &time_; + EventsT voltages_; + std::deque> waveform_buffer_; + size_t dead_count_ {sizeof...(Ts) * SPK_POST_SAMP}; + bool set_ {true}; + double thresh_; +}; + +template +class BandPassFilter { +public: + USING_REACTIVE_DOMAIN(D) + + // Samples collected from API + EventsT In; + EventsT Out + = react::Transform(In, [&](double in) { return filt_.do_sample(in); }); + + BandPassFilter(Time &time, const EventsT s) + : time_(time) + , In(s) + //, period(1/time.Ts); + , filt_(dsp::BPF, 21, 30e3, 300, 3e3) + { + // Nothing + std::cout << 1.0/time.Ts; + } + +private: + dsp::Filter filt_; + Time &time_; +}; + +//template +//class SpikeDetector { +//public: +// USING_REACTIVE_DOMAIN(D) +// +// // Samples collected from API +// EventsT In; +// EventsT Out = react::Filter(In, [&](double in) { +// +// if (in_spike_ && counter_--) { +// return true; +// } else if (in > threshold_) { +// in_spike_ = true; +// return true; +// } else { +// counter_ = SPK_LEN; +// return false; +// } +// }); +// +// SpikeDetector(const EventsT s, const double threshold) +// : In(s), threshold_(threshold) +// { +// // Nothing +// } +// +//private: +// bool in_spike_{false}; +// int counter_{SPK_LEN}; +// const double threshold_; +// +// // Buffer [pre i post], i is the current sample being checked. One threshold crossing, The whole buffer is sent as a signal +//}; diff --git a/examples/src/filt.cpp b/examples/src/filt.cpp new file mode 100644 index 00000000..243690bb --- /dev/null +++ b/examples/src/filt.cpp @@ -0,0 +1,266 @@ +/* + * FIR filter class, by Mike Perkins + * + * a simple C++ class for linear phase FIR filtering + * + * For background, see the post http://www.cardinalpeak.com/blog?p=1841 + * + * Copyright (c) 2013, Cardinal Peak, LLC. http://www.cardinalpeak.com + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1) Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2) Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * 3) Neither the name of Cardinal Peak nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * CARDINAL PEAK, LLC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "filt.h" +#define ECODE(x) {m_error_flag = x; return;} + +namespace dsp { +// Handles LPF and HPF case +Filter::Filter(filterType filt_t, int num_taps, double Fs, double Fx) +{ + m_error_flag = 0; + m_filt_t = filt_t; + m_num_taps = num_taps; + m_Fs = Fs; + m_Fx = Fx; + m_lambda = M_PI * Fx / (Fs/2); + + if( Fs <= 0 ) ECODE(-1); + if( Fx <= 0 || Fx >= Fs/2 ) ECODE(-2); + if( m_num_taps <= 0 || m_num_taps > MAX_NUM_FILTER_TAPS ) ECODE(-3); + + m_taps = m_sr = NULL; + m_taps = (double*)malloc( m_num_taps * sizeof(double) ); + m_sr = (double*)malloc( m_num_taps * sizeof(double) ); + if( m_taps == NULL || m_sr == NULL ) ECODE(-4); + + init(); + + if( m_filt_t == LPF ) designLPF(); + else if( m_filt_t == HPF ) designHPF(); + else ECODE(-5); + + return; +} + +// Handles BPF case +Filter::Filter(filterType filt_t, int num_taps, double Fs, double Fl, + double Fu) +{ + m_error_flag = 0; + m_filt_t = filt_t; + m_num_taps = num_taps; + m_Fs = Fs; + m_Fx = Fl; + m_Fu = Fu; + m_lambda = M_PI * Fl / (Fs/2); + m_phi = M_PI * Fu / (Fs/2); + + if( Fs <= 0 ) ECODE(-10); + if( Fl >= Fu ) ECODE(-11); + if( Fl <= 0 || Fl >= Fs/2 ) ECODE(-12); + if( Fu <= 0 || Fu >= Fs/2 ) ECODE(-13); + if( m_num_taps <= 0 || m_num_taps > MAX_NUM_FILTER_TAPS ) ECODE(-14); + + m_taps = m_sr = NULL; + m_taps = (double*)malloc( m_num_taps * sizeof(double) ); + m_sr = (double*)malloc( m_num_taps * sizeof(double) ); + if( m_taps == NULL || m_sr == NULL ) ECODE(-15); + + init(); + + if( m_filt_t == BPF ) designBPF(); + else ECODE(-16); + + return; +} + +Filter::~Filter() +{ + if( m_taps != NULL ) free( m_taps ); + if( m_sr != NULL ) free( m_sr ); +} + +void +Filter::designLPF() +{ + int n; + double mm; + + for(n = 0; n < m_num_taps; n++){ + mm = n - (m_num_taps - 1.0) / 2.0; + if( mm == 0.0 ) m_taps[n] = m_lambda / M_PI; + else m_taps[n] = sin( mm * m_lambda ) / (mm * M_PI); + } + + return; +} + +void +Filter::designHPF() +{ + int n; + double mm; + + for(n = 0; n < m_num_taps; n++){ + mm = n - (m_num_taps - 1.0) / 2.0; + if( mm == 0.0 ) m_taps[n] = 1.0 - m_lambda / M_PI; + else m_taps[n] = -sin( mm * m_lambda ) / (mm * M_PI); + } + + return; +} + +void +Filter::designBPF() +{ + int n; + double mm; + + for(n = 0; n < m_num_taps; n++){ + mm = n - (m_num_taps - 1.0) / 2.0; + if( mm == 0.0 ) m_taps[n] = (m_phi - m_lambda) / M_PI; + else m_taps[n] = ( sin( mm * m_phi ) - + sin( mm * m_lambda ) ) / (mm * M_PI); + } + + return; +} + +void +Filter::get_taps( double *taps ) +{ + int i; + + if( m_error_flag != 0 ) return; + + for(i = 0; i < m_num_taps; i++) taps[i] = m_taps[i]; + + return; +} + +int +Filter::write_taps_to_file( char *filename ) +{ + FILE *fd; + + if( m_error_flag != 0 ) return -1; + + int i; + fd = fopen(filename, "w"); + if( fd == NULL ) return -1; + + fprintf(fd, "%d\n", m_num_taps); + for(i = 0; i < m_num_taps; i++){ + fprintf(fd, "%15.6f\n", m_taps[i]); + } + fclose(fd); + + return 0; +} + +// Output the magnitude of the frequency response in dB +#define NP 1000 +int +Filter::write_freqres_to_file( char *filename ) +{ + FILE *fd; + int i, k; + double w, dw; + double y_r[NP], y_i[NP], y_mag[NP]; + double mag_max = -1; + double tmp_d; + + if( m_error_flag != 0 ) return -1; + + dw = M_PI / (NP - 1.0); + for(i = 0; i < NP; i++){ + w = i*dw; + y_r[i] = y_i[i] = 0; + for(k = 0; k < m_num_taps; k++){ + y_r[i] += m_taps[k] * cos(k * w); + y_i[i] -= m_taps[k] * sin(k * w); + } + } + + for(i = 0; i < NP; i++){ + y_mag[i] = sqrt( y_r[i]*y_r[i] + y_i[i]*y_i[i] ); + if( y_mag[i] > mag_max ) mag_max = y_mag[i]; + } + + if( mag_max <= 0.0 ) return -2; + + fd = fopen(filename, "w"); + if( fd == NULL ) return -3; + + for(i = 0; i < NP; i++){ + w = i*dw; + if( y_mag[i] == 0 ) tmp_d = -100; + else{ + tmp_d = 20 * log10( y_mag[i] / mag_max ); + if( tmp_d < -100 ) tmp_d = -100; + } + fprintf(fd, "%10.6e %10.6e\n", w * (m_Fs/2)/M_PI, tmp_d); + } + + fclose(fd); + return 0; +} + +void +Filter::init() +{ + int i; + + if( m_error_flag != 0 ) return; + + for(i = 0; i < m_num_taps; i++) m_sr[i] = 0; + + return; +} + +double +Filter::do_sample(double data_sample) +{ + int i; + double result; + + if( m_error_flag != 0 ) return(0); + + for(i = m_num_taps - 1; i >= 1; i--){ + m_sr[i] = m_sr[i-1]; + } + m_sr[0] = data_sample; + + result = 0; + for(i = 0; i < m_num_taps; i++) result += m_sr[i] * m_taps[i]; + + return result; +} +} diff --git a/examples/src/filt.h b/examples/src/filt.h new file mode 100644 index 00000000..3b63df36 --- /dev/null +++ b/examples/src/filt.h @@ -0,0 +1,162 @@ +/* + * FIR filter class, by Mike Perkins + * + * a simple C++ class for linear phase FIR filtering + * + * For background, see the post http://www.cardinalpeak.com/blog?p=1841 + * + * Copyright (c) 2013, Cardinal Peak, LLC. http://www.cardinalpeak.com + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1) Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2) Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * 3) Neither the name of Cardinal Peak nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * CARDINAL PEAK, LLC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * + * PURPOSE: + * This object designs digital filters and filters digital data streams + * + * USAGE: + * Invoke an object of type Filter. Two constructors are available. + * One is used for LPF and HPF filters, one is used for BPFs. + * The arguments to the constructors are as follows: + * + * // For LPF or HPF only + * Filter(filterType filt_t, int num_taps, double Fs, double Fx); + * // For BPF only + * Filter(filterType filt_t, int num_taps, double Fs, double Fl, double Fu); + * + * filt_t: is LPF, HPF or BPF + * num_taps: is the number of taps you want the filter to use + * Fs: is the sampling frequency of the digital data being filtered + * Fx: is the "transition" frequency for LPF and HPF filters + * Fl, Fu: are the upper and lower transition frequencies for BPF filters + * + * Once the filter is created, you can start filtering data. Here + * is an example for 51 tap lowpass filtering of an audio stream sampled at + * 44.1Khz (the CD sampling rate), where the goal is to create a signal + * of "telephone" bandwidth (4Khz): + * + * Filter *my_filter; + * + * my_filter = new Filter(LPF, 51, 44.1, 4.0) + * if( my_filter->get_error_flag() != 0 ) // abort in an appropriate manner + * + * while(data_to_be_filtered){ + * next_sample = // Get the next sample from the data stream somehow + * filtered_sample = my_filter->do_sample( next_sample ); + * . + * . + * . + * } + * delete my_filter; + * + * Several helper functions are provided: + * init(): The filter can be re-initialized with a call to this function + * get_taps(double *taps): returns the filter taps in the array "taps" + * write_taps_to_file(char *filename): writes the filter taps to a file + * write_freqres_to_file(char *filename): output frequency response to a file + * + * Finally, a get_error_flag() function is provided. Recommended usage + * is to check the get_error_flag() return value for a non-zero + * value after the new Filter object is created. If it is non-zero, print + * out the non-zero value and look at the following table to see the + * error: + * -1: Fs <= 0 + * -2: Fx <= 0 or Fx >= Fs/2 + * -3: num_taps <= 0 or num_taps >= MAX_NUM_FILTER_TAPS + * -4: memory allocation for the needed arrays failed + * -5: an invalid filterType was passed into a constructor + * -10: Fs <= 0 (BPF case) + * -11: Fl >= Fu + * -12: Fl <= 0 || Fl >= Fs/2 + * -13: Fu <= 0 || Fu >= Fs/2 + * -14: num_taps <= 0 or num_taps >= MAX_NUM_FILTER_TAPS (BPF case) + * -15: memory allocation for the needed arrays failed (BPF case) + * -16: an invalid filterType was passed into a constructor (BPF case) + * + * Note that if a non-zero error code value occurs, every call to do_sample() + * will return the value 0. write_taps_fo_file() will fail and return a -1 (it + * also returns a -1 if it fails to open the tap file passed into it). + * get_taps() will have no effect on the array passed in if the error_flag + * is non-zero. write_freqres_to_file( ) returns different error codes + * depending on the nature of the error...see the function itself for details. + * + * The filters are designed using the "Fourier Series Method". This + * means that the coefficients of a Fourier Series approximation to the + * frequency response of an ideal filter (LPF, HPF, BPF) are used as + * the filter taps. The resulting filters have some ripple in the passband + * due to the Gibbs phenomenon; the filters are linear phase. + */ + +#ifndef _FILTER_H +#define _FILTER_H + +#define MAX_NUM_FILTER_TAPS 1000 + +#include +#include +#include +#include +#include +#include + +namespace dsp { +enum filterType { LPF, HPF, BPF }; + +class Filter { +private: + filterType m_filt_t; + int m_num_taps; + int m_error_flag; + double m_Fs; + double m_Fx; + double m_lambda; + double *m_taps; + double *m_sr; + void designLPF(); + void designHPF(); + + // Only needed for the bandpass filter case + double m_Fu, m_phi; + void designBPF(); + +public: + Filter(filterType filt_t, int num_taps, double Fs, double Fx); + Filter(filterType filt_t, int num_taps, double Fs, double Fl, double Fu); + ~Filter(); + void init(); + double do_sample(double data_sample); + int get_error_flag() { return m_error_flag; }; + void get_taps(double *taps); + int write_taps_to_file(char *filename); + int write_freqres_to_file(char *filename); +}; +} +#endif diff --git a/include/react/detail/graph/AlgorithmNodes.h b/include/react/detail/graph/AlgorithmNodes.h index 454fdfbb..6264bbb1 100644 --- a/include/react/detail/graph/AlgorithmNodes.h +++ b/include/react/detail/graph/AlgorithmNodes.h @@ -11,6 +11,14 @@ #include "react/detail/Defs.h" +// JPN: Added to prevent: +// +// call to function 'Equals' that is neither visible in +// the template definition nor found by argument-dependent lookup +// +// for call to Equals() which is declared and defined in detail/ReactiveBase.h +#include "react/detail/ReactiveBase.h" + #include #include @@ -657,4 +665,4 @@ class PulseNode : public EventStreamNode /****************************************/ REACT_IMPL_END /***************************************/ -#endif // REACT_DETAIL_GRAPH_ALGORITHMNODES_H_INCLUDED \ No newline at end of file +#endif // REACT_DETAIL_GRAPH_ALGORITHMNODES_H_INCLUDED From df314804a32fa296419ce63c32101480864a2911 Mon Sep 17 00:00:00 2001 From: jonnew Date: Thu, 8 Dec 2016 21:10:52 -0500 Subject: [PATCH 2/8] Added Trode, Time, EphysInput. Does not work. --- examples/src/DecoderTypes.h | 61 ++++++++++++ examples/src/EphysInput.hpp | 98 ++++++++++++++++++++ examples/src/SpikeDetect.cpp | 103 +++++++++++---------- examples/src/SpikeDetect.h | 175 ++++++++++++++++------------------- examples/src/Time.hpp | 38 ++++++++ examples/src/Trode.hpp | 81 ++++++++++++++++ 6 files changed, 409 insertions(+), 147 deletions(-) create mode 100644 examples/src/DecoderTypes.h create mode 100644 examples/src/EphysInput.hpp create mode 100644 examples/src/Time.hpp create mode 100644 examples/src/Trode.hpp diff --git a/examples/src/DecoderTypes.h b/examples/src/DecoderTypes.h new file mode 100644 index 00000000..cb33e6e0 --- /dev/null +++ b/examples/src/DecoderTypes.h @@ -0,0 +1,61 @@ +#pragma once + +#include +#include "react/Event.h" + +namespace decoder { +namespace types { + +using namespace react; + +// Primatives +using VoltageT = float; +using LocationT = float; +using SampleIndexT = uint64_t; +using TimeT = double; + +// Voltage +template +using VoltageSource = EventSource; + +template +using VoltateSourceVec = std::array, N>; + +template +using Voltages = Events; + +//template +//using VoltagePack = std::tuple; +// +//template +//using VoltagePacks = Events>; + +// LFP +template +using LFP = std::array; + +template +using LFPs = Events>; + +// Spikes +template +using SpikeWaveform = std::array, L>; + +template +using Spikes = Events>; + +// Amplitudes +template +using Amplitude = std::array; + +template +using Amplitudes = Signal>; + +// Position +using Position = std::tuple; + +template +using Positions = Events; + +} // namespace types +} // namespace decoder diff --git a/examples/src/EphysInput.hpp b/examples/src/EphysInput.hpp new file mode 100644 index 00000000..f259ab65 --- /dev/null +++ b/examples/src/EphysInput.hpp @@ -0,0 +1,98 @@ +#pragma once + +#include "DecoderTypes.h" +#include "react/Domain.h" + +namespace decoder { + +using namespace react; +using namespace decoder::types; + +namespace detail { + + template + struct VoltageTuple { + typedef std::tuple type; + }; + + template <> + struct VoltageTuple<1> { + typedef std::tuple type; + }; + + template <> + struct VoltageTuple<2> { + typedef std::tuple type; + }; + + template <> + struct VoltageTuple<4> { + typedef std::tuple type; + }; + + template <> + struct VoltageTuple<8> { + typedef std::tuple type; + }; + + template + using VTuple = typename VoltageTuple::type; +} + +// Voltage Event streams to LFPs +template +class EphysInput { + +static constexpr size_t N {sizeof...(Vs)}; +public: + USING_REACTIVE_DOMAIN(D) + + Events> voltages; // Input + LFPs lfp = Transform(voltages, [](detail::VTuple v, LFP l) { + + for (size_t i = 0; i < N; i++) + l[i] = std::get<0>(v); + + return l; + + }); // Output + + EphysInput(Time& t, Vs& ...sources) + : time(time) + { + voltages = Join(sources...); + } + +private: + Time &time; +}; + + +template +using EphysInput1 = EphysInput>; + +template +using EphysInput2 = EphysInput, VoltageSource>; + +template +using EphysInput4 = EphysInput, + VoltageSource, + VoltageSource, + VoltageSource>; + +template +using EphysInput8 = EphysInput, + VoltageSource, + VoltageSource, + VoltageSource>; +} // namespace decoder + diff --git a/examples/src/SpikeDetect.cpp b/examples/src/SpikeDetect.cpp index eefd8b1d..0ba7b9ea 100644 --- a/examples/src/SpikeDetect.cpp +++ b/examples/src/SpikeDetect.cpp @@ -1,41 +1,45 @@ -#include "SpikeDetect.h" +#include "Time.hpp" +#include "Trode.hpp" +#include "EphysInput.hpp" + +#define MakeVoltSource(D) + +using namespace decoder; int main() { - REACTIVE_DOMAIN(D, sequential) - const size_t N = 256; + REACTIVE_DOMAIN(D, sequential) - using raw_size_t = std::array, N>::size_type; + const size_t M = 8; // Time Time time(30.0e3); - std::cout << "Sample period: " << time.Ts << std::endl; - - // 256 electrodes - //std::vector> electrodes {256, time}; - - // 256 raw data sources, bandpass filters - std::array, N> raw; - - for (raw_size_t i = 0; i < N; i++) - raw[i] = MakeEventSource(); - - //BandPassFilter filter(time, raw[0]); - std::vector> filters; - for (auto &r :raw) - filters.emplace_back(time, r); - - //std::cout << "Filter N: " << filters.size() << std::endl; - - // Are merged into 1 TT - using Tetrode = NTrode, - Events, - Events, - Events>; - //Tetrode tt(time, + std::vector> e; + for (int i = 0; i < M; i++) + e.emplace_back(MakeEventSource()); + + EphysInput4 lfp(time, e[0], e[1], e[2], e[3]); + + + + // //BandPassFilter filter(time, raw[0]); + // std::vector> filters; + // for (auto &r :raw) + // filters.emplace_back(time, r); + // + // std::cout << "Sample period: " << time.Ts << std::endl; + // //std::cout << "Filter N: " << filters.size() << std::endl; + // + // // Are merged into 1 TT + // using Tetrode = NTrode, + // Events, + // Events, + // Events>; + // + // Tetrode tt(time, // 0.01, // filters[0].Out, // filters[1].Out, @@ -56,29 +60,26 @@ int main() // std::cout << "Current value: " << out << std::endl; //}); - // ///////////////////// + /////////////////////// // HARDWARE SIMULATION - // This is simulating 100 transactions hardware - for (int i = 0; i < 100; i++) { - - std::random_device rd; - std::mt19937 gen(rd()); - std::normal_distribution<> d(0, 1); - - // Make a sample block coming from 4 contacts - for (int j = 0; j < BLOCKSIZE; j++) { - - // Graph update step - DoTransaction([&] { - - // Increment sample counter - time.NewSample(); - - // Make noise on all electrodes - for (auto &r : raw) - r << d(gen); - }); - } + ////////////////////// + std::random_device rd; + std::mt19937 gen(rd()); + std::normal_distribution<> d(0, 1); + + // Make a sample block coming from 4 contacts + for (int j = 0; j < 1000; j++) { + + // Graph update step + DoTransaction([&] { + + // Increment sample counter + time.NewSample(); + + // Make noise on all electrodes + for (auto &electrode : e) + electrode << d(gen); + }); } return 0; diff --git a/examples/src/SpikeDetect.h b/examples/src/SpikeDetect.h index 657f0a38..84ed9d97 100644 --- a/examples/src/SpikeDetect.h +++ b/examples/src/SpikeDetect.h @@ -13,143 +13,124 @@ #include "react/Signal.h" #include "react/common/Util.h" +#include "DecoderTypes.h" + #define BLOCKSIZE 10 -#define SPK_PRE_SAMP 10 -#define SPK_POST_SAMP 22 + +namespace decoder { using namespace react; +using namespace decoder::types; template struct Incrementer { T operator()(Token, T v) const { return v + 1; } }; -enum {out_spike, in_spike}; - template class Time { public: USING_REACTIVE_DOMAIN(D) - double Ts; + TimeT Ts; EventSourceT<> NewSample = MakeEventSource(); - SignalT Count = Iterate(NewSample, (uint64_t)0, Incrementer()); - SignalT Seconds - = Iterate(NewSample, 0.0, [&](Token, double sec) { return sec + Ts; }); + SignalT Count + = Iterate(NewSample, (SampleIndexT)0, Incrementer()); + SignalT Seconds + = Iterate(NewSample, 0.0, [&](Token, TimeT sec) { return sec + Ts; }); - Time(double sample_rate_hz) + Time(TimeT sample_rate_hz) : Ts(1.0 / sample_rate_hz) { // Nothing } }; -//template -//class Electrode { -//public: -// USING_REACTIVE_DOMAIN(D) -// -// // Samples collected from API -// EventSourceT Out = MakeEventSource(); -// -// Electrode(Time &time) -// : time_(time) -// { -// // Nothing -// } -// -//private: -// Time &time_; -//}; -//template -//class Spike -//{ -//public: -// -// double Waveform[E][L]; -// -// // Note: To be used as a signal value type, -// // values of the type must be comparable -// //bool operator==(const Spike& other) const -// //{ -// // return this == &other; -// //} -//}; +// Transforms LFPs int Spikes +template +class Trode { + +static constexpr size_t L {PRE + POST}; +using Waveform = SpikeWaveform; +using Buffer = std::deque>; -template -class NTrode { public: USING_REACTIVE_DOMAIN(D) - //SignalT> Spikes = Iterate(voltages_, [&]() { - - Signal Spikes - = Iterate(voltages_, 0.0, [&](double v, double spk) { + LFPs lfp; + Spikes spikes = Transform(lfp, [&](LFP l, SpikeWaveform s) { - // If detector is set and we are over threshold - set_ = !(set_ && v > thresh_); + // Update buffer + buffer.push_front(l); + buffer.pop_back(); - // If we are at at the end of detected spike and we are ready to - // transmitted the buffer - if (!set_ && !dead_count_--) { - set_ = true; - dead_count_ = sizeof...(Ts) * SPK_POST_SAMP; - return 42.0; - } else { - return 0.0; + // If not already triggered, check all voltage samples to see any + // crossed threshold + if (!triggered ) { + for (const auto &volt : l) { + triggered = l < threshold; + if (triggered) + break; } - - }); - - // Update buffer - // waveform_buffer_.emplace{ - // voltages_ - // Is current sample over threshold? If so, emit - - NTrode(Time& time, double thresh, Ts& ...sources) - : time_(time) - , thresh_(thresh) + } else if(!--dead_count) { + triggered = false; + dead_count = POST; + return snapshot(buffer); + } + }); + + Trode(Time& t, VoltageT thr) + : time(t) + , threshold(thr) { - voltages_ = Merge(sources...); - waveform_buffer_.resize(SPK_POST_SAMP + SPK_PRE_SAMP); + buffer.resize(L); } private: - Time &time_; - EventsT voltages_; - std::deque> waveform_buffer_; - size_t dead_count_ {sizeof...(Ts) * SPK_POST_SAMP}; - bool set_ {true}; - double thresh_; -}; -template -class BandPassFilter { -public: - USING_REACTIVE_DOMAIN(D) + Time &time; + bool triggered {false}; + Buffer buffer; + VoltageT threshold; + size_t dead_count {POST}; - // Samples collected from API - EventsT In; - EventsT Out - = react::Transform(In, [&](double in) { return filt_.do_sample(in); }); + Waveform snapshot(const Buffer &buffer) { - BandPassFilter(Time &time, const EventsT s) - : time_(time) - , In(s) - //, period(1/time.Ts); - , filt_(dsp::BPF, 21, 30e3, 300, 3e3) - { - // Nothing - std::cout << 1.0/time.Ts; - } + Waveform w; + for (int i = 0; i < L; i++) + w[i] = buffer[i]; -private: - dsp::Filter filt_; - Time &time_; + return w; + } }; +//template +//class BandPassFilter { +//public: +// USING_REACTIVE_DOMAIN(D) +// +// // Samples collected from API +// LFP EventsT In; +// EventsT Out +// = react::Transform(In, [&](double in) { return filt_.do_sample(in); }); +// +// BandPassFilter(Time &time, const EventsT s) +// : time_(time) +// , In(s) +// //, period(1/time.Ts); +// , filt_(dsp::BPF, 21, 30e3, 300, 3e3) +// { +// // Nothing +// std::cout << 1.0/time.Ts; +// } +// +//private: +// dsp::Filter filt_; +// Time &time_; +//}; + //template //class SpikeDetector { //public: @@ -183,3 +164,5 @@ class BandPassFilter { // // // Buffer [pre i post], i is the current sample being checked. One threshold crossing, The whole buffer is sent as a signal //}; +// +} // namespace decoder diff --git a/examples/src/Time.hpp b/examples/src/Time.hpp new file mode 100644 index 00000000..e5d5b810 --- /dev/null +++ b/examples/src/Time.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include "DecoderTypes.h" +#include "react/Algorithm.h" +#include "react/Domain.h" +#include "react/Signal.h" + +namespace decoder { + +using namespace react; +using namespace decoder::types; + +template +struct Incrementer { + T operator()(Token, T v) const { return v + 1; } +}; + +template +class Time +{ +public: + USING_REACTIVE_DOMAIN(D) + + TimeT Ts; + EventSourceT<> NewSample = MakeEventSource(); + SignalT Count + = Iterate(NewSample, (SampleIndexT)0, Incrementer()); + SignalT Seconds + = Iterate(NewSample, 0.0, [&](Token, TimeT sec) { return sec + Ts; }); + + Time(TimeT sample_rate_hz) + : Ts(1.0 / sample_rate_hz) + { + // Nothing + } +}; + +} // namespace decoder diff --git a/examples/src/Trode.hpp b/examples/src/Trode.hpp new file mode 100644 index 00000000..7a3e578e --- /dev/null +++ b/examples/src/Trode.hpp @@ -0,0 +1,81 @@ +#pragma once + +#include + +#include "DecoderTypes.h" +#include "react/Domain.h" + +namespace decoder { + +using namespace react; +using namespace decoder::types; + +// Transforms LFPs int Spikes +template +class Trode { + +static constexpr size_t L {PRE + POST}; +using Waveform = SpikeWaveform; +using Buffer = std::deque>; + +public: + USING_REACTIVE_DOMAIN(D) + + LFPs &lfp; + Spikes spikes = Transform(lfp, [&](LFP l, SpikeWaveform s) { + + // Update buffer + buffer.push_front(l); + buffer.pop_back(); + + // If not already triggered, check all voltage samples to see any + // crossed threshold + if (!triggered ) { + for (const auto &volt : l) { + triggered = l < threshold; + if (triggered) + break; + } + } else if(!--dead_count) { + triggered = false; + dead_count = POST; + return snapshot(buffer); + } + }); + + Trode(Time& t, LFPs &l, VoltageT thr) + : time(t) + , lfp(l) + , threshold(thr) + { + buffer.resize(L); + } + +private: + + Time &time; + bool triggered {false}; + Buffer buffer; + VoltageT threshold; + size_t dead_count {POST}; + + Waveform snapshot(const Buffer &buffer) { + + Waveform w; + for (int i = 0; i < L; i++) + w[i] = buffer[i]; + + return w; + } +}; + +template +using Electrode = Trode; + +template +using StereoTrode = Trode; + +template +using Tetrode = Trode; + +} // namespace decoder From aaf30409b15b5a264c4a699a66f8ec253cc2a0a1 Mon Sep 17 00:00:00 2001 From: jonnew Date: Thu, 8 Dec 2016 23:21:33 -0500 Subject: [PATCH 3/8] Compiles, but segfaults. --- CMakeLists.txt | 2 +- examples/src/BasicReactors.cpp | 6 +- .../src/{DecoderTypes.h => DecoderTypes.hpp} | 0 examples/src/EphysInput.hpp | 14 +++-- examples/src/SpikeDetect.cpp | 11 ++-- examples/src/Time.hpp | 2 +- examples/src/Trode.hpp | 60 ++++++++++--------- examples/src/Utility.hpp | 25 ++++++++ include/react/logging/EventLog.h | 4 +- 9 files changed, 79 insertions(+), 45 deletions(-) rename examples/src/{DecoderTypes.h => DecoderTypes.hpp} (100%) create mode 100644 examples/src/Utility.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 9488f9d3..1e33940a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wpedantic") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -stdlib=libc++ -Wall -Wpedantic") include_directories ("${PROJECT_SOURCE_DIR}/include") diff --git a/examples/src/BasicReactors.cpp b/examples/src/BasicReactors.cpp index 1e30cc1c..c90d7e4b 100644 --- a/examples/src/BasicReactors.cpp +++ b/examples/src/BasicReactors.cpp @@ -35,7 +35,7 @@ namespace example1 ReactorT loop { - [&] (ReactorT::Context ctx) + [] (ReactorT::Context ctx) { PathT points; @@ -101,7 +101,7 @@ namespace example2 ReactorT loop { - [&] (ReactorT::Context ctx) + [] (ReactorT::Context ctx) { PathT points; @@ -158,4 +158,4 @@ int main() example2::Run(); return 0; -} \ No newline at end of file +} diff --git a/examples/src/DecoderTypes.h b/examples/src/DecoderTypes.hpp similarity index 100% rename from examples/src/DecoderTypes.h rename to examples/src/DecoderTypes.hpp diff --git a/examples/src/EphysInput.hpp b/examples/src/EphysInput.hpp index f259ab65..d636c261 100644 --- a/examples/src/EphysInput.hpp +++ b/examples/src/EphysInput.hpp @@ -1,6 +1,8 @@ #pragma once -#include "DecoderTypes.h" +#include "DecoderTypes.hpp" +#include "Time.hpp" +#include "Utility.hpp" #include "react/Domain.h" namespace decoder { @@ -55,10 +57,13 @@ static constexpr size_t N {sizeof...(Vs)}; USING_REACTIVE_DOMAIN(D) Events> voltages; // Input - LFPs lfp = Transform(voltages, [](detail::VTuple v, LFP l) { + LFPs lfp = Transform(voltages, [](detail::VTuple v) { - for (size_t i = 0; i < N; i++) - l[i] = std::get<0>(v); + LFP l; + int k = 0; + for_each(v, [&l, &k](VoltageT value) { + l[k++]= value; + }); return l; @@ -74,7 +79,6 @@ static constexpr size_t N {sizeof...(Vs)}; Time &time; }; - template using EphysInput1 = EphysInput>; diff --git a/examples/src/SpikeDetect.cpp b/examples/src/SpikeDetect.cpp index 0ba7b9ea..142089a8 100644 --- a/examples/src/SpikeDetect.cpp +++ b/examples/src/SpikeDetect.cpp @@ -1,14 +1,13 @@ +#include + +#include "EphysInput.hpp" #include "Time.hpp" #include "Trode.hpp" -#include "EphysInput.hpp" - -#define MakeVoltSource(D) using namespace decoder; int main() { - REACTIVE_DOMAIN(D, sequential) const size_t M = 8; @@ -18,9 +17,9 @@ int main() std::vector> e; for (int i = 0; i < M; i++) - e.emplace_back(MakeEventSource()); + e.push_back(MakeEventSource()); - EphysInput4 lfp(time, e[0], e[1], e[2], e[3]); + //EphysInput4 lfp(time, e[0], e[1], e[2], e[3]); diff --git a/examples/src/Time.hpp b/examples/src/Time.hpp index e5d5b810..f1b350b3 100644 --- a/examples/src/Time.hpp +++ b/examples/src/Time.hpp @@ -1,6 +1,6 @@ #pragma once -#include "DecoderTypes.h" +#include "DecoderTypes.hpp" #include "react/Algorithm.h" #include "react/Domain.h" #include "react/Signal.h" diff --git a/examples/src/Trode.hpp b/examples/src/Trode.hpp index 7a3e578e..73281a37 100644 --- a/examples/src/Trode.hpp +++ b/examples/src/Trode.hpp @@ -2,7 +2,7 @@ #include -#include "DecoderTypes.h" +#include "DecoderTypes.hpp" #include "react/Domain.h" namespace decoder { @@ -10,7 +10,7 @@ namespace decoder { using namespace react; using namespace decoder::types; -// Transforms LFPs int Spikes +// LFPs -> Spikes template class Trode { @@ -22,25 +22,28 @@ using Buffer = std::deque>; USING_REACTIVE_DOMAIN(D) LFPs &lfp; - Spikes spikes = Transform(lfp, [&](LFP l, SpikeWaveform s) { - - // Update buffer - buffer.push_front(l); - buffer.pop_back(); - - // If not already triggered, check all voltage samples to see any - // crossed threshold - if (!triggered ) { - for (const auto &volt : l) { - triggered = l < threshold; - if (triggered) - break; - } - } else if(!--dead_count) { - triggered = false; - dead_count = POST; - return snapshot(buffer); - } + Spikes spikes + = Transform(lfp, [&](LFP l, SpikeWaveform s) { + + // Update buffer + buffer.push_front(l); + buffer.pop_back(); + + // If not already triggered, check all voltage samples to see any + // crossed threshold + if (!triggered) { + for (const auto &volt : l) { + triggered = l < threshold; + if (triggered) + break; + } + } else if (!--dead_count) { + triggered = false; + dead_count = POST; + return snapshot(buffer); + } + // TODO: If I return nothing, there is not propogation of change, + // right? }); Trode(Time& t, LFPs &l, VoltageT thr) @@ -69,13 +72,16 @@ using Buffer = std::deque>; } }; -template -using Electrode = Trode; +template +using Electrode = Trode; -template -using StereoTrode = Trode; +template +using StereoTrode = Trode; -template -using Tetrode = Trode; +template +using Tetrode = Trode; + +template +using Octrode = Trode; } // namespace decoder diff --git a/examples/src/Utility.hpp b/examples/src/Utility.hpp new file mode 100644 index 00000000..2dc565ce --- /dev/null +++ b/examples/src/Utility.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include +#include +#include + +namespace decoder { +// Taken from: +// http://codereview.stackexchange.com/questions/51407/stdtuple-foreach-implementation +template +void for_each_impl(Tuple&& tuple, F&& f, std::index_sequence) { + using swallow = int[]; + (void)swallow{1, + (f(std::get(std::forward(tuple))), void(), int{})... + }; +} + +template +void for_each(Tuple&& tuple, F&& f) { + constexpr std::size_t N = std::tuple_size>::value; + for_each_impl(std::forward(tuple), std::forward(f), + std::make_index_sequence{}); +} + +} // namespace decoder diff --git a/include/react/logging/EventLog.h b/include/react/logging/EventLog.h index e9622c7b..83e1635d 100644 --- a/include/react/logging/EventLog.h +++ b/include/react/logging/EventLog.h @@ -29,7 +29,7 @@ /////////////////////////////////////////////////////////////////////////////////////////////////// class EventLog { - using TimestampT = std::chrono::time_point; + using TimestampT = std::chrono::time_point; class Entry { @@ -97,4 +97,4 @@ class EventLog /****************************************/ REACT_IMPL_END /***************************************/ -#endif // REACT_DETAIL_LOGGING_EVENTLOG_H_INCLUDED \ No newline at end of file +#endif // REACT_DETAIL_LOGGING_EVENTLOG_H_INCLUDED From f5c1a8776b21c37125a963f0396db338a36afd54 Mon Sep 17 00:00:00 2001 From: jonnew Date: Sun, 11 Dec 2016 10:38:48 -0500 Subject: [PATCH 4/8] Merge with ilelann/cpp.react --- CMakeLists.txt | 8 +- benchmarks/CMakeLists.txt | 2 + benchmarks/src/BenchmarkBase.h | 4 +- benchmarks/src/BenchmarkRandom.h | 26 +- benchmarks/src/Main.cpp | 111 +- examples/CMakeLists.txt | 26 +- examples/src/BasicReactors.cpp | 2 +- examples/src/DecoderTypes.hpp | 61 - examples/src/EphysInput.hpp | 102 -- examples/src/SpikeDetect.cpp | 85 -- examples/src/SpikeDetect.h | 168 --- examples/src/Time.hpp | 38 - examples/src/Trode.hpp | 87 -- examples/src/Utility.hpp | 25 - examples/src/filt.cpp | 266 ---- examples/src/filt.h | 162 --- include/react/Algorithm.h | 33 +- include/react/Domain.h | 43 +- include/react/Event.h | 39 +- include/react/Forward.h | 55 + include/react/Observer.h | 33 +- include/react/Signal.h | 1174 +++++------------ include/react/TypeTraits.h | 40 +- include/react/common/Concurrency.h | 96 +- include/react/common/Containers.h | 4 +- include/react/common/SourceIdSet.h | 135 -- include/react/common/Timing.h | 31 +- include/react/common/TopoQueue.h | 60 +- include/react/common/Types.h | 5 +- include/react/common/Util.h | 62 +- include/react/detail/DomainBase.h | 3 +- .../react/detail/graph/ContinuationNodes.h | 2 +- include/react/detail/graph/GraphBase.h | 11 +- include/react/detail/graph/ObserverNodes.h | 6 +- include/react/detail/graph/ReactorNodes.h | 4 +- include/react/detail/graph/SignalNodes.h | 53 +- project/msvc/CppReact.sln | 149 --- project/msvc/CppReact.vcxproj | 206 --- project/msvc/CppReact.vcxproj.filters | 171 --- project/msvc/CppReactBenchmark.vcxproj | 166 --- .../msvc/CppReactBenchmark.vcxproj.filters | 42 - project/msvc/CppReactExample.vcxproj | 162 --- project/msvc/CppReactExample.vcxproj.filters | 22 - project/msvc/CppReactTest.vcxproj | 195 --- project/msvc/CppReactTest.vcxproj.filters | 78 -- project/msvc/Example_BasicAlgorithms.vcxproj | 150 --- .../Example_BasicAlgorithms.vcxproj.filters | 22 - project/msvc/Example_BasicComposition.vcxproj | 150 --- .../Example_BasicComposition.vcxproj.filters | 22 - project/msvc/Example_BasicEvents.vcxproj | 150 --- .../msvc/Example_BasicEvents.vcxproj.filters | 22 - project/msvc/Example_BasicObservers.vcxproj | 150 --- .../Example_BasicObservers.vcxproj.filters | 22 - project/msvc/Example_BasicReactors.vcxproj | 150 --- .../Example_BasicReactors.vcxproj.filters | 22 - project/msvc/Example_BasicSignals.vcxproj | 150 --- .../msvc/Example_BasicSignals.vcxproj.filters | 22 - .../msvc/Example_BasicSynchronization.vcxproj | 151 --- ...ample_BasicSynchronization.vcxproj.filters | 22 - tests/CMakeLists.txt | 47 +- tests/src/MoveTest.h | 33 +- tests/src/OperationsTest.h | 10 +- tests/src/SignalTest.h | 150 ++- tests/src/TransactionTest.cpp | 2 +- 64 files changed, 798 insertions(+), 4902 deletions(-) delete mode 100644 examples/src/DecoderTypes.hpp delete mode 100644 examples/src/EphysInput.hpp delete mode 100644 examples/src/SpikeDetect.cpp delete mode 100644 examples/src/SpikeDetect.h delete mode 100644 examples/src/Time.hpp delete mode 100644 examples/src/Trode.hpp delete mode 100644 examples/src/Utility.hpp delete mode 100644 examples/src/filt.cpp delete mode 100644 examples/src/filt.h create mode 100644 include/react/Forward.h delete mode 100644 include/react/common/SourceIdSet.h delete mode 100644 project/msvc/CppReact.sln delete mode 100644 project/msvc/CppReact.vcxproj delete mode 100644 project/msvc/CppReact.vcxproj.filters delete mode 100644 project/msvc/CppReactBenchmark.vcxproj delete mode 100644 project/msvc/CppReactBenchmark.vcxproj.filters delete mode 100644 project/msvc/CppReactExample.vcxproj delete mode 100644 project/msvc/CppReactExample.vcxproj.filters delete mode 100644 project/msvc/CppReactTest.vcxproj delete mode 100644 project/msvc/CppReactTest.vcxproj.filters delete mode 100644 project/msvc/Example_BasicAlgorithms.vcxproj delete mode 100644 project/msvc/Example_BasicAlgorithms.vcxproj.filters delete mode 100644 project/msvc/Example_BasicComposition.vcxproj delete mode 100644 project/msvc/Example_BasicComposition.vcxproj.filters delete mode 100644 project/msvc/Example_BasicEvents.vcxproj delete mode 100644 project/msvc/Example_BasicEvents.vcxproj.filters delete mode 100644 project/msvc/Example_BasicObservers.vcxproj delete mode 100644 project/msvc/Example_BasicObservers.vcxproj.filters delete mode 100644 project/msvc/Example_BasicReactors.vcxproj delete mode 100644 project/msvc/Example_BasicReactors.vcxproj.filters delete mode 100644 project/msvc/Example_BasicSignals.vcxproj delete mode 100644 project/msvc/Example_BasicSignals.vcxproj.filters delete mode 100644 project/msvc/Example_BasicSynchronization.vcxproj delete mode 100644 project/msvc/Example_BasicSynchronization.vcxproj.filters diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e33940a..63b7e1f5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,6 @@ ### Configuration cmake_minimum_required (VERSION 2.6) +enable_testing() project (CppReact) @@ -12,12 +13,15 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -stdlib=libc++ -Wall -Wpedant include_directories ("${PROJECT_SOURCE_DIR}/include") ### CppReact +file(GLOB_RECURSE CPPREACT_HEADERS include/*.h) + add_library(CppReact src/engine/PulsecountEngine.cpp src/engine/SubtreeEngine.cpp src/engine/ToposortEngine.cpp src/logging/EventLog.cpp - src/logging/EventRecords.cpp) + src/logging/EventRecords.cpp + ${CPPREACT_HEADERS}) target_link_libraries(CppReact tbb) @@ -34,7 +38,7 @@ if(build_benchmarks) endif() ### tests/ -option(build_tests "Build unit tests?" OFF) +option(build_tests "Build unit tests?" ON) if(build_tests) add_subdirectory(tests) endif() diff --git a/benchmarks/CMakeLists.txt b/benchmarks/CMakeLists.txt index b74640e9..773926a3 100644 --- a/benchmarks/CMakeLists.txt +++ b/benchmarks/CMakeLists.txt @@ -2,3 +2,5 @@ add_executable(CppReactBenchmark src/Main.cpp) target_link_libraries(CppReactBenchmark CppReact tbbmalloc_proxy) + +add_test(NAME CppReactBenchmark COMMAND CppReactBenchmark "-r" CONFIGURATIONS Benchmark) diff --git a/benchmarks/src/BenchmarkBase.h b/benchmarks/src/BenchmarkBase.h index deaaf931..48a95aa3 100644 --- a/benchmarks/src/BenchmarkBase.h +++ b/benchmarks/src/BenchmarkBase.h @@ -20,14 +20,14 @@ // Get unique random numbers from range. /////////////////////////////////////////////////////////////////////////////////////////////////// template -const std::vector GetUniqueRandomNumbers(TGen gen, T from, T to, int count) +const std::vector GetUniqueRandomNumbers(TGen gen, T from, T to, T count) { std::vector data(1 + to - from); int c = from; for (auto& p : data) p = c++; - for (int i=0; i dist(i,(to - from)); auto r = dist(gen); diff --git a/benchmarks/src/BenchmarkRandom.h b/benchmarks/src/BenchmarkRandom.h index 63cbd996..3ba59484 100644 --- a/benchmarks/src/BenchmarkRandom.h +++ b/benchmarks/src/BenchmarkRandom.h @@ -53,14 +53,14 @@ class RandomGraphGenerator Func3T Function3; Func4T Function4; - int Width = 1; - int Height = 1; + unsigned int Width = 1; + unsigned int Height = 1; - int SelectSlowCount = 0; - int SelectEdgeCount = 0; + unsigned int SelectSlowCount = 0; + unsigned int SelectEdgeCount = 0; - int EdgeSeed; - int SlowSeed; + unsigned int EdgeSeed; + unsigned int SlowSeed; void Generate() { @@ -76,7 +76,7 @@ class RandomGraphGenerator Func3T f3Fast = [this] (TValue a1, TValue a2, TValue a3) { FastDelayFunc(); return Function3(a1,a2,a3); }; Func4T f4Fast = [this] (TValue a1, TValue a2, TValue a3, TValue a4) { FastDelayFunc(); return Function4(a1,a2,a3,a4); }; - int nodeCount = Width * Height; + auto nodeCount = Width * Height; std::mt19937 edgeGen(EdgeSeed); const auto edgeNodes = GetUniqueRandomNumbers(edgeGen, Width, nodeCount - 1, SelectEdgeCount); @@ -90,17 +90,17 @@ class RandomGraphGenerator auto edgeNodeIt = edgeNodes.begin(); auto slowNodeIt = slowNodes.begin(); - auto cur = 0; + unsigned cur = 0; HandleVect nodes(nodeCount); - for (int w=0; w nodeDist(0, Width*h - 1); - for (int w=0; w return d; } -}; \ No newline at end of file +}; diff --git a/benchmarks/src/Main.cpp b/benchmarks/src/Main.cpp index eb47f33f..4c62ae8c 100644 --- a/benchmarks/src/Main.cpp +++ b/benchmarks/src/Main.cpp @@ -81,14 +81,14 @@ void runBenchmarkRandom(std::ostream& out) void runBenchmarkFanout(std::ostream& out) { - //RUN_BENCHMARK(out, 5, Benchmark_Fanout, BenchmarkParams_Fanout(10, 10000, 0), - // ToposortSTDomain, ToposortDomain, ELMDomain, PulsecountDomain, SourceSetDomain); + RUN_BENCHMARK(out, 5, Benchmark_Fanout, BenchmarkParams_Fanout(10, 10000, 0), + ToposortSTDomain, ToposortDomain, PulsecountDomain); - //RUN_BENCHMARK(out, 5, Benchmark_Fanout, BenchmarkParams_Fanout(100, 10000, 0), - // ToposortSTDomain, ToposortDomain, ELMDomain, PulsecountDomain, SourceSetDomain); + RUN_BENCHMARK(out, 5, Benchmark_Fanout, BenchmarkParams_Fanout(100, 10000, 0), + ToposortSTDomain, ToposortDomain, PulsecountDomain); - //RUN_BENCHMARK(out, 5, Benchmark_Fanout, BenchmarkParams_Fanout(1000, 10000, 0), - // ToposortSTDomain, ToposortDomain, ELMDomain, PulsecountDomain, SourceSetDomain); + RUN_BENCHMARK(out, 5, Benchmark_Fanout, BenchmarkParams_Fanout(1000, 10000, 0), + ToposortSTDomain, ToposortDomain, PulsecountDomain); RUN_BENCHMARK(out, 3, Benchmark_Fanout, BenchmarkParams_Fanout(10, 10, 10), ToposortSTDomain, ToposortDomain, PulsecountDomain); @@ -100,41 +100,41 @@ void runBenchmarkFanout(std::ostream& out) ToposortSTDomain, ToposortDomain, PulsecountDomain); } -void runBenchmarkSequence(std::ostream& out) -{ - //RUN_BENCHMARK(out, 3, Benchmark_Sequence, BenchmarkParams_Sequence(10, 10000, 0), - // ToposortSTDomain, ToposortDomain, ELMDomain, PulsecountDomain, SourceSetDomain); +//void runBenchmarkSequence(std::ostream& out) +//{ +// //RUN_BENCHMARK(out, 3, Benchmark_Sequence, BenchmarkParams_Sequence(10, 10000, 0), +// // ToposortSTDomain, ToposortDomain, ELMDomain, PulsecountDomain, SourceSetDomain); - //RUN_BENCHMARK(out, 3, Benchmark_Sequence, BenchmarkParams_Sequence(100, 10000, 0), - // ToposortSTDomain, ToposortDomain, ELMDomain, PulsecountDomain, SourceSetDomain); +// //RUN_BENCHMARK(out, 3, Benchmark_Sequence, BenchmarkParams_Sequence(100, 10000, 0), +// // ToposortSTDomain, ToposortDomain, ELMDomain, PulsecountDomain, SourceSetDomain); - //RUN_BENCHMARK(out, 3, Benchmark_Sequence, BenchmarkParams_Sequence(1000, 10000, 0), - // ToposortSTDomain, ToposortDomain, ELMDomain, PulsecountDomain, SourceSetDomain); +// //RUN_BENCHMARK(out, 3, Benchmark_Sequence, BenchmarkParams_Sequence(1000, 10000, 0), +// // ToposortSTDomain, ToposortDomain, ELMDomain, PulsecountDomain, SourceSetDomain); - RUN_BENCHMARK(out, 3, Benchmark_Sequence, BenchmarkParams_Sequence(10, 10, 10), - ToposortSTDomain, ToposortDomain, PulsecountDomain); +// RUN_BENCHMARK(out, 3, Benchmark_Sequence, BenchmarkParams_Sequence(10, 10, 10), +// ToposortSTDomain, ToposortDomain, PulsecountDomain); - RUN_BENCHMARK(out, 3, Benchmark_Sequence, BenchmarkParams_Sequence(100, 10, 10), - ToposortSTDomain, ToposortDomain, PulsecountDomain); +// RUN_BENCHMARK(out, 3, Benchmark_Sequence, BenchmarkParams_Sequence(100, 10, 10), +// ToposortSTDomain, ToposortDomain, PulsecountDomain); - RUN_BENCHMARK(out, 3, Benchmark_Sequence, BenchmarkParams_Sequence(1000, 10, 10), - ToposortSTDomain, ToposortDomain, PulsecountDomain); -} +// RUN_BENCHMARK(out, 3, Benchmark_Sequence, BenchmarkParams_Sequence(1000, 10, 10), +// ToposortSTDomain, ToposortDomain, PulsecountDomain); +//} -void runBenchmarkLifeSim(std::ostream& out) -{ - //RUN_BENCHMARK(std::cout, 1, Benchmark_LifeSim, BenchmarkParams_LifeSim(150, 1000), - // ELMDomain); +//void runBenchmarkLifeSim(std::ostream& out) +//{ +// //RUN_BENCHMARK(std::cout, 1, Benchmark_LifeSim, BenchmarkParams_LifeSim(150, 10, 1000), +// // ToposortDomain); - //RUN_BENCHMARK(std::cout, 1, Benchmark_LifeSim, BenchmarkParams_LifeSim(250, 30, 10000), - // SourceSetDomain, PulsecountDomain); +// //RUN_BENCHMARK(std::cout, 1, Benchmark_LifeSim, BenchmarkParams_LifeSim(250, 30, 10000), +// // SourceSetDomain, PulsecountDomain); - RUN_BENCHMARK(out, 1, Benchmark_LifeSim, BenchmarkParams_LifeSim(100, 15, 10000), - ToposortSTDomain, ToposortDomain, PulsecountDomain); +// //RUN_BENCHMARK(out, 1, Benchmark_LifeSim, BenchmarkParams_LifeSim(100, 15, 10000), +// //ToposortSTDomain, ToposortDomain, PulsecountDomain); - //RUN_BENCHMARK(out, 3, Benchmark_LifeSim, BenchmarkParams_LifeSim(100, 50, 100), - // PulsecountDomain, PulsecountDomain); -} +// //RUN_BENCHMARK(out, 3, Benchmark_LifeSim, BenchmarkParams_LifeSim(100, 50, 100), +// // PulsecountDomain, PulsecountDomain); +//} void runBenchmarks() { @@ -144,21 +144,21 @@ void runBenchmarks() logfile.open(path.c_str()); // === GRID - //runBenchmarkGrid(logfile); - - //runBenchmarkFlooding(logfile); + runBenchmarkGrid(logfile); // === RANDOM - //runBenchmarkRandom(logfile); + if (0) + runBenchmarkRandom(logfile); // === FANOUT - //runBenchmarkFanout(logfile); + if (0) + runBenchmarkFanout(logfile); // === SEQUENCE //runBenchmarkSequence(logfile); // === LIFESIM - runBenchmarkLifeSim(logfile); + //runBenchmarkLifeSim(logfile); logfile.close(); } @@ -233,9 +233,34 @@ void profileBenchmark() } // ~anonymous namespace -int main() +#include + +int main(int argc, char * argv[]) { - //runBenchmarks(); - //debugBenchmarks(); - profileBenchmark(); -} \ No newline at end of file + auto begin = argv; + auto end = argv + argc; + +// auto getCmdOption = [&](const std::string & option) -> char* +// { +// char ** itr = std::find(begin, end, option); +// if (itr != end && ++itr != end) +// { +// return *itr; +// } +// return 0; +// }; + + auto cmdOptionExists = [&](const std::string& option) -> bool + { + return std::find(begin, end, option) != end; + }; + + std::cout << "-d to debug, -p to profile. run by default" << std::endl; + + if (cmdOptionExists("-d")) + debugBenchmarks(); + else if (cmdOptionExists("-p")) + profileBenchmark(); + else + runBenchmarks(); +} diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 56747b7a..3ae11c1c 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,10 +1,10 @@ ### Example_BasicAlgorithms -add_executable(Example_BasicAlgorithms src/BasicAlgorithms.cpp) -target_link_libraries(Example_BasicAlgorithms CppReact) +#add_executable(Example_BasicAlgorithms src/BasicAlgorithms.cpp) +#target_link_libraries(Example_BasicAlgorithms CppReact) ### Example_BasicComposition -add_executable(Example_BasicComposition src/BasicComposition.cpp) -target_link_libraries(Example_BasicComposition CppReact) +#add_executable(Example_BasicComposition src/BasicComposition.cpp) +#target_link_libraries(Example_BasicComposition CppReact) ### Example_BasicEvents add_executable(Example_BasicEvents src/BasicEvents.cpp) @@ -15,16 +15,16 @@ add_executable(Example_BasicObservers src/BasicObservers.cpp) target_link_libraries(Example_BasicObservers CppReact) ### Example_BasicReactors -find_package(Boost 1.55 COMPONENTS coroutine context system) +find_package(Boost COMPONENTS coroutine context system) if(Boost_FOUND) - include_directories(${Boost_INCLUDE_DIRS}) - add_executable(Example_BasicReactors src/BasicReactors.cpp) - target_link_libraries(Example_BasicReactors CppReact ${Boost_LIBRARIES}) + include_directories(${Boost_INCLUDE_DIRS}) + add_executable(Example_BasicReactors src/BasicReactors.cpp) + target_link_libraries(Example_BasicReactors CppReact ${Boost_LIBRARIES}) else() - message("boost::coroutine not found. Skipping build of Example_BasicReactors.") + message("boost::coroutine not found. Skipping build of Example_BasicReactors.") + #add_executable(Example_BasicReactors src/BasicReactors.cpp) + #target_link_libraries(Example_BasicReactors CppReact) endif() -#add_exyecutable(Example_BasicReactors src/BasicReactors.cpp) -#target_link_libraries(Example_BasicReactors CppReact) ### Example_BasicSignals add_executable(Example_BasicSignals src/BasicSignals.cpp) @@ -37,7 +37,3 @@ target_link_libraries(Example_BasicSynchronization CppReact) ### Example_Sandbox add_executable(Example_Sandbox src/Main.cpp) target_link_libraries(Example_Sandbox CppReact) - -### Spike det -add_executable(SpikeDetect src/SpikeDetect.cpp src/filt.cpp) -target_link_libraries(SpikeDetect CppReact) diff --git a/examples/src/BasicReactors.cpp b/examples/src/BasicReactors.cpp index c90d7e4b..56fd09a5 100644 --- a/examples/src/BasicReactors.cpp +++ b/examples/src/BasicReactors.cpp @@ -107,7 +107,7 @@ namespace example2 points.emplace_back(ctx.Await(mouseDown)); - auto count = ctx.Get(counter); + ctx.Get(counter); ctx.RepeatUntil(mouseUp, [&] { points.emplace_back(ctx.Await(mouseMove)); diff --git a/examples/src/DecoderTypes.hpp b/examples/src/DecoderTypes.hpp deleted file mode 100644 index cb33e6e0..00000000 --- a/examples/src/DecoderTypes.hpp +++ /dev/null @@ -1,61 +0,0 @@ -#pragma once - -#include -#include "react/Event.h" - -namespace decoder { -namespace types { - -using namespace react; - -// Primatives -using VoltageT = float; -using LocationT = float; -using SampleIndexT = uint64_t; -using TimeT = double; - -// Voltage -template -using VoltageSource = EventSource; - -template -using VoltateSourceVec = std::array, N>; - -template -using Voltages = Events; - -//template -//using VoltagePack = std::tuple; -// -//template -//using VoltagePacks = Events>; - -// LFP -template -using LFP = std::array; - -template -using LFPs = Events>; - -// Spikes -template -using SpikeWaveform = std::array, L>; - -template -using Spikes = Events>; - -// Amplitudes -template -using Amplitude = std::array; - -template -using Amplitudes = Signal>; - -// Position -using Position = std::tuple; - -template -using Positions = Events; - -} // namespace types -} // namespace decoder diff --git a/examples/src/EphysInput.hpp b/examples/src/EphysInput.hpp deleted file mode 100644 index d636c261..00000000 --- a/examples/src/EphysInput.hpp +++ /dev/null @@ -1,102 +0,0 @@ -#pragma once - -#include "DecoderTypes.hpp" -#include "Time.hpp" -#include "Utility.hpp" -#include "react/Domain.h" - -namespace decoder { - -using namespace react; -using namespace decoder::types; - -namespace detail { - - template - struct VoltageTuple { - typedef std::tuple type; - }; - - template <> - struct VoltageTuple<1> { - typedef std::tuple type; - }; - - template <> - struct VoltageTuple<2> { - typedef std::tuple type; - }; - - template <> - struct VoltageTuple<4> { - typedef std::tuple type; - }; - - template <> - struct VoltageTuple<8> { - typedef std::tuple type; - }; - - template - using VTuple = typename VoltageTuple::type; -} - -// Voltage Event streams to LFPs -template -class EphysInput { - -static constexpr size_t N {sizeof...(Vs)}; -public: - USING_REACTIVE_DOMAIN(D) - - Events> voltages; // Input - LFPs lfp = Transform(voltages, [](detail::VTuple v) { - - LFP l; - int k = 0; - for_each(v, [&l, &k](VoltageT value) { - l[k++]= value; - }); - - return l; - - }); // Output - - EphysInput(Time& t, Vs& ...sources) - : time(time) - { - voltages = Join(sources...); - } - -private: - Time &time; -}; - -template -using EphysInput1 = EphysInput>; - -template -using EphysInput2 = EphysInput, VoltageSource>; - -template -using EphysInput4 = EphysInput, - VoltageSource, - VoltageSource, - VoltageSource>; - -template -using EphysInput8 = EphysInput, - VoltageSource, - VoltageSource, - VoltageSource>; -} // namespace decoder - diff --git a/examples/src/SpikeDetect.cpp b/examples/src/SpikeDetect.cpp deleted file mode 100644 index 142089a8..00000000 --- a/examples/src/SpikeDetect.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#include - -#include "EphysInput.hpp" -#include "Time.hpp" -#include "Trode.hpp" - -using namespace decoder; - -int main() -{ - REACTIVE_DOMAIN(D, sequential) - - const size_t M = 8; - - // Time - Time time(30.0e3); - - std::vector> e; - for (int i = 0; i < M; i++) - e.push_back(MakeEventSource()); - - //EphysInput4 lfp(time, e[0], e[1], e[2], e[3]); - - - - // //BandPassFilter filter(time, raw[0]); - // std::vector> filters; - // for (auto &r :raw) - // filters.emplace_back(time, r); - // - // std::cout << "Sample period: " << time.Ts << std::endl; - // //std::cout << "Filter N: " << filters.size() << std::endl; - // - // // Are merged into 1 TT - // using Tetrode = NTrode, - // Events, - // Events, - // Events>; - // - // Tetrode tt(time, - // 0.01, - // filters[0].Out, - // filters[1].Out, - // filters[2].Out, - // filters[3].Out); - - ////SpikeDetector detector(filter.Out, 0.1); - - Observe(time.Count, [](uint64_t count) { - std::cout << "Current sample: " << count << std::endl; - }); - - Observe(time.Seconds, [](double sec) { - std::cout << "Current seconds: " << sec << std::endl; - }); - - //Observe(filter.Out, [](double out) { - // std::cout << "Current value: " << out << std::endl; - //}); - - /////////////////////// - // HARDWARE SIMULATION - ////////////////////// - std::random_device rd; - std::mt19937 gen(rd()); - std::normal_distribution<> d(0, 1); - - // Make a sample block coming from 4 contacts - for (int j = 0; j < 1000; j++) { - - // Graph update step - DoTransaction([&] { - - // Increment sample counter - time.NewSample(); - - // Make noise on all electrodes - for (auto &electrode : e) - electrode << d(gen); - }); - } - - return 0; -} diff --git a/examples/src/SpikeDetect.h b/examples/src/SpikeDetect.h deleted file mode 100644 index 84ed9d97..00000000 --- a/examples/src/SpikeDetect.h +++ /dev/null @@ -1,168 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "filt.h" -#include "react/Algorithm.h" -#include "react/Domain.h" -#include "react/Event.h" -#include "react/Observer.h" -#include "react/Signal.h" -#include "react/common/Util.h" - -#include "DecoderTypes.h" - -#define BLOCKSIZE 10 - -namespace decoder { - -using namespace react; -using namespace decoder::types; - -template -struct Incrementer { - T operator()(Token, T v) const { return v + 1; } -}; - -template -class Time -{ -public: - USING_REACTIVE_DOMAIN(D) - - TimeT Ts; - EventSourceT<> NewSample = MakeEventSource(); - SignalT Count - = Iterate(NewSample, (SampleIndexT)0, Incrementer()); - SignalT Seconds - = Iterate(NewSample, 0.0, [&](Token, TimeT sec) { return sec + Ts; }); - - Time(TimeT sample_rate_hz) - : Ts(1.0 / sample_rate_hz) - { - // Nothing - } -}; - - -// Transforms LFPs int Spikes -template -class Trode { - -static constexpr size_t L {PRE + POST}; -using Waveform = SpikeWaveform; -using Buffer = std::deque>; - -public: - USING_REACTIVE_DOMAIN(D) - - LFPs lfp; - Spikes spikes = Transform(lfp, [&](LFP l, SpikeWaveform s) { - - // Update buffer - buffer.push_front(l); - buffer.pop_back(); - - // If not already triggered, check all voltage samples to see any - // crossed threshold - if (!triggered ) { - for (const auto &volt : l) { - triggered = l < threshold; - if (triggered) - break; - } - } else if(!--dead_count) { - triggered = false; - dead_count = POST; - return snapshot(buffer); - } - }); - - Trode(Time& t, VoltageT thr) - : time(t) - , threshold(thr) - { - buffer.resize(L); - } - -private: - - Time &time; - bool triggered {false}; - Buffer buffer; - VoltageT threshold; - size_t dead_count {POST}; - - Waveform snapshot(const Buffer &buffer) { - - Waveform w; - for (int i = 0; i < L; i++) - w[i] = buffer[i]; - - return w; - } -}; - -//template -//class BandPassFilter { -//public: -// USING_REACTIVE_DOMAIN(D) -// -// // Samples collected from API -// LFP EventsT In; -// EventsT Out -// = react::Transform(In, [&](double in) { return filt_.do_sample(in); }); -// -// BandPassFilter(Time &time, const EventsT s) -// : time_(time) -// , In(s) -// //, period(1/time.Ts); -// , filt_(dsp::BPF, 21, 30e3, 300, 3e3) -// { -// // Nothing -// std::cout << 1.0/time.Ts; -// } -// -//private: -// dsp::Filter filt_; -// Time &time_; -//}; - -//template -//class SpikeDetector { -//public: -// USING_REACTIVE_DOMAIN(D) -// -// // Samples collected from API -// EventsT In; -// EventsT Out = react::Filter(In, [&](double in) { -// -// if (in_spike_ && counter_--) { -// return true; -// } else if (in > threshold_) { -// in_spike_ = true; -// return true; -// } else { -// counter_ = SPK_LEN; -// return false; -// } -// }); -// -// SpikeDetector(const EventsT s, const double threshold) -// : In(s), threshold_(threshold) -// { -// // Nothing -// } -// -//private: -// bool in_spike_{false}; -// int counter_{SPK_LEN}; -// const double threshold_; -// -// // Buffer [pre i post], i is the current sample being checked. One threshold crossing, The whole buffer is sent as a signal -//}; -// -} // namespace decoder diff --git a/examples/src/Time.hpp b/examples/src/Time.hpp deleted file mode 100644 index f1b350b3..00000000 --- a/examples/src/Time.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include "DecoderTypes.hpp" -#include "react/Algorithm.h" -#include "react/Domain.h" -#include "react/Signal.h" - -namespace decoder { - -using namespace react; -using namespace decoder::types; - -template -struct Incrementer { - T operator()(Token, T v) const { return v + 1; } -}; - -template -class Time -{ -public: - USING_REACTIVE_DOMAIN(D) - - TimeT Ts; - EventSourceT<> NewSample = MakeEventSource(); - SignalT Count - = Iterate(NewSample, (SampleIndexT)0, Incrementer()); - SignalT Seconds - = Iterate(NewSample, 0.0, [&](Token, TimeT sec) { return sec + Ts; }); - - Time(TimeT sample_rate_hz) - : Ts(1.0 / sample_rate_hz) - { - // Nothing - } -}; - -} // namespace decoder diff --git a/examples/src/Trode.hpp b/examples/src/Trode.hpp deleted file mode 100644 index 73281a37..00000000 --- a/examples/src/Trode.hpp +++ /dev/null @@ -1,87 +0,0 @@ -#pragma once - -#include - -#include "DecoderTypes.hpp" -#include "react/Domain.h" - -namespace decoder { - -using namespace react; -using namespace decoder::types; - -// LFPs -> Spikes -template -class Trode { - -static constexpr size_t L {PRE + POST}; -using Waveform = SpikeWaveform; -using Buffer = std::deque>; - -public: - USING_REACTIVE_DOMAIN(D) - - LFPs &lfp; - Spikes spikes - = Transform(lfp, [&](LFP l, SpikeWaveform s) { - - // Update buffer - buffer.push_front(l); - buffer.pop_back(); - - // If not already triggered, check all voltage samples to see any - // crossed threshold - if (!triggered) { - for (const auto &volt : l) { - triggered = l < threshold; - if (triggered) - break; - } - } else if (!--dead_count) { - triggered = false; - dead_count = POST; - return snapshot(buffer); - } - // TODO: If I return nothing, there is not propogation of change, - // right? - }); - - Trode(Time& t, LFPs &l, VoltageT thr) - : time(t) - , lfp(l) - , threshold(thr) - { - buffer.resize(L); - } - -private: - - Time &time; - bool triggered {false}; - Buffer buffer; - VoltageT threshold; - size_t dead_count {POST}; - - Waveform snapshot(const Buffer &buffer) { - - Waveform w; - for (int i = 0; i < L; i++) - w[i] = buffer[i]; - - return w; - } -}; - -template -using Electrode = Trode; - -template -using StereoTrode = Trode; - -template -using Tetrode = Trode; - -template -using Octrode = Trode; - -} // namespace decoder diff --git a/examples/src/Utility.hpp b/examples/src/Utility.hpp deleted file mode 100644 index 2dc565ce..00000000 --- a/examples/src/Utility.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace decoder { -// Taken from: -// http://codereview.stackexchange.com/questions/51407/stdtuple-foreach-implementation -template -void for_each_impl(Tuple&& tuple, F&& f, std::index_sequence) { - using swallow = int[]; - (void)swallow{1, - (f(std::get(std::forward(tuple))), void(), int{})... - }; -} - -template -void for_each(Tuple&& tuple, F&& f) { - constexpr std::size_t N = std::tuple_size>::value; - for_each_impl(std::forward(tuple), std::forward(f), - std::make_index_sequence{}); -} - -} // namespace decoder diff --git a/examples/src/filt.cpp b/examples/src/filt.cpp deleted file mode 100644 index 243690bb..00000000 --- a/examples/src/filt.cpp +++ /dev/null @@ -1,266 +0,0 @@ -/* - * FIR filter class, by Mike Perkins - * - * a simple C++ class for linear phase FIR filtering - * - * For background, see the post http://www.cardinalpeak.com/blog?p=1841 - * - * Copyright (c) 2013, Cardinal Peak, LLC. http://www.cardinalpeak.com - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1) Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2) Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * 3) Neither the name of Cardinal Peak nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * CARDINAL PEAK, LLC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "filt.h" -#define ECODE(x) {m_error_flag = x; return;} - -namespace dsp { -// Handles LPF and HPF case -Filter::Filter(filterType filt_t, int num_taps, double Fs, double Fx) -{ - m_error_flag = 0; - m_filt_t = filt_t; - m_num_taps = num_taps; - m_Fs = Fs; - m_Fx = Fx; - m_lambda = M_PI * Fx / (Fs/2); - - if( Fs <= 0 ) ECODE(-1); - if( Fx <= 0 || Fx >= Fs/2 ) ECODE(-2); - if( m_num_taps <= 0 || m_num_taps > MAX_NUM_FILTER_TAPS ) ECODE(-3); - - m_taps = m_sr = NULL; - m_taps = (double*)malloc( m_num_taps * sizeof(double) ); - m_sr = (double*)malloc( m_num_taps * sizeof(double) ); - if( m_taps == NULL || m_sr == NULL ) ECODE(-4); - - init(); - - if( m_filt_t == LPF ) designLPF(); - else if( m_filt_t == HPF ) designHPF(); - else ECODE(-5); - - return; -} - -// Handles BPF case -Filter::Filter(filterType filt_t, int num_taps, double Fs, double Fl, - double Fu) -{ - m_error_flag = 0; - m_filt_t = filt_t; - m_num_taps = num_taps; - m_Fs = Fs; - m_Fx = Fl; - m_Fu = Fu; - m_lambda = M_PI * Fl / (Fs/2); - m_phi = M_PI * Fu / (Fs/2); - - if( Fs <= 0 ) ECODE(-10); - if( Fl >= Fu ) ECODE(-11); - if( Fl <= 0 || Fl >= Fs/2 ) ECODE(-12); - if( Fu <= 0 || Fu >= Fs/2 ) ECODE(-13); - if( m_num_taps <= 0 || m_num_taps > MAX_NUM_FILTER_TAPS ) ECODE(-14); - - m_taps = m_sr = NULL; - m_taps = (double*)malloc( m_num_taps * sizeof(double) ); - m_sr = (double*)malloc( m_num_taps * sizeof(double) ); - if( m_taps == NULL || m_sr == NULL ) ECODE(-15); - - init(); - - if( m_filt_t == BPF ) designBPF(); - else ECODE(-16); - - return; -} - -Filter::~Filter() -{ - if( m_taps != NULL ) free( m_taps ); - if( m_sr != NULL ) free( m_sr ); -} - -void -Filter::designLPF() -{ - int n; - double mm; - - for(n = 0; n < m_num_taps; n++){ - mm = n - (m_num_taps - 1.0) / 2.0; - if( mm == 0.0 ) m_taps[n] = m_lambda / M_PI; - else m_taps[n] = sin( mm * m_lambda ) / (mm * M_PI); - } - - return; -} - -void -Filter::designHPF() -{ - int n; - double mm; - - for(n = 0; n < m_num_taps; n++){ - mm = n - (m_num_taps - 1.0) / 2.0; - if( mm == 0.0 ) m_taps[n] = 1.0 - m_lambda / M_PI; - else m_taps[n] = -sin( mm * m_lambda ) / (mm * M_PI); - } - - return; -} - -void -Filter::designBPF() -{ - int n; - double mm; - - for(n = 0; n < m_num_taps; n++){ - mm = n - (m_num_taps - 1.0) / 2.0; - if( mm == 0.0 ) m_taps[n] = (m_phi - m_lambda) / M_PI; - else m_taps[n] = ( sin( mm * m_phi ) - - sin( mm * m_lambda ) ) / (mm * M_PI); - } - - return; -} - -void -Filter::get_taps( double *taps ) -{ - int i; - - if( m_error_flag != 0 ) return; - - for(i = 0; i < m_num_taps; i++) taps[i] = m_taps[i]; - - return; -} - -int -Filter::write_taps_to_file( char *filename ) -{ - FILE *fd; - - if( m_error_flag != 0 ) return -1; - - int i; - fd = fopen(filename, "w"); - if( fd == NULL ) return -1; - - fprintf(fd, "%d\n", m_num_taps); - for(i = 0; i < m_num_taps; i++){ - fprintf(fd, "%15.6f\n", m_taps[i]); - } - fclose(fd); - - return 0; -} - -// Output the magnitude of the frequency response in dB -#define NP 1000 -int -Filter::write_freqres_to_file( char *filename ) -{ - FILE *fd; - int i, k; - double w, dw; - double y_r[NP], y_i[NP], y_mag[NP]; - double mag_max = -1; - double tmp_d; - - if( m_error_flag != 0 ) return -1; - - dw = M_PI / (NP - 1.0); - for(i = 0; i < NP; i++){ - w = i*dw; - y_r[i] = y_i[i] = 0; - for(k = 0; k < m_num_taps; k++){ - y_r[i] += m_taps[k] * cos(k * w); - y_i[i] -= m_taps[k] * sin(k * w); - } - } - - for(i = 0; i < NP; i++){ - y_mag[i] = sqrt( y_r[i]*y_r[i] + y_i[i]*y_i[i] ); - if( y_mag[i] > mag_max ) mag_max = y_mag[i]; - } - - if( mag_max <= 0.0 ) return -2; - - fd = fopen(filename, "w"); - if( fd == NULL ) return -3; - - for(i = 0; i < NP; i++){ - w = i*dw; - if( y_mag[i] == 0 ) tmp_d = -100; - else{ - tmp_d = 20 * log10( y_mag[i] / mag_max ); - if( tmp_d < -100 ) tmp_d = -100; - } - fprintf(fd, "%10.6e %10.6e\n", w * (m_Fs/2)/M_PI, tmp_d); - } - - fclose(fd); - return 0; -} - -void -Filter::init() -{ - int i; - - if( m_error_flag != 0 ) return; - - for(i = 0; i < m_num_taps; i++) m_sr[i] = 0; - - return; -} - -double -Filter::do_sample(double data_sample) -{ - int i; - double result; - - if( m_error_flag != 0 ) return(0); - - for(i = m_num_taps - 1; i >= 1; i--){ - m_sr[i] = m_sr[i-1]; - } - m_sr[0] = data_sample; - - result = 0; - for(i = 0; i < m_num_taps; i++) result += m_sr[i] * m_taps[i]; - - return result; -} -} diff --git a/examples/src/filt.h b/examples/src/filt.h deleted file mode 100644 index 3b63df36..00000000 --- a/examples/src/filt.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * FIR filter class, by Mike Perkins - * - * a simple C++ class for linear phase FIR filtering - * - * For background, see the post http://www.cardinalpeak.com/blog?p=1841 - * - * Copyright (c) 2013, Cardinal Peak, LLC. http://www.cardinalpeak.com - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1) Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2) Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * 3) Neither the name of Cardinal Peak nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * CARDINAL PEAK, LLC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * - * PURPOSE: - * This object designs digital filters and filters digital data streams - * - * USAGE: - * Invoke an object of type Filter. Two constructors are available. - * One is used for LPF and HPF filters, one is used for BPFs. - * The arguments to the constructors are as follows: - * - * // For LPF or HPF only - * Filter(filterType filt_t, int num_taps, double Fs, double Fx); - * // For BPF only - * Filter(filterType filt_t, int num_taps, double Fs, double Fl, double Fu); - * - * filt_t: is LPF, HPF or BPF - * num_taps: is the number of taps you want the filter to use - * Fs: is the sampling frequency of the digital data being filtered - * Fx: is the "transition" frequency for LPF and HPF filters - * Fl, Fu: are the upper and lower transition frequencies for BPF filters - * - * Once the filter is created, you can start filtering data. Here - * is an example for 51 tap lowpass filtering of an audio stream sampled at - * 44.1Khz (the CD sampling rate), where the goal is to create a signal - * of "telephone" bandwidth (4Khz): - * - * Filter *my_filter; - * - * my_filter = new Filter(LPF, 51, 44.1, 4.0) - * if( my_filter->get_error_flag() != 0 ) // abort in an appropriate manner - * - * while(data_to_be_filtered){ - * next_sample = // Get the next sample from the data stream somehow - * filtered_sample = my_filter->do_sample( next_sample ); - * . - * . - * . - * } - * delete my_filter; - * - * Several helper functions are provided: - * init(): The filter can be re-initialized with a call to this function - * get_taps(double *taps): returns the filter taps in the array "taps" - * write_taps_to_file(char *filename): writes the filter taps to a file - * write_freqres_to_file(char *filename): output frequency response to a file - * - * Finally, a get_error_flag() function is provided. Recommended usage - * is to check the get_error_flag() return value for a non-zero - * value after the new Filter object is created. If it is non-zero, print - * out the non-zero value and look at the following table to see the - * error: - * -1: Fs <= 0 - * -2: Fx <= 0 or Fx >= Fs/2 - * -3: num_taps <= 0 or num_taps >= MAX_NUM_FILTER_TAPS - * -4: memory allocation for the needed arrays failed - * -5: an invalid filterType was passed into a constructor - * -10: Fs <= 0 (BPF case) - * -11: Fl >= Fu - * -12: Fl <= 0 || Fl >= Fs/2 - * -13: Fu <= 0 || Fu >= Fs/2 - * -14: num_taps <= 0 or num_taps >= MAX_NUM_FILTER_TAPS (BPF case) - * -15: memory allocation for the needed arrays failed (BPF case) - * -16: an invalid filterType was passed into a constructor (BPF case) - * - * Note that if a non-zero error code value occurs, every call to do_sample() - * will return the value 0. write_taps_fo_file() will fail and return a -1 (it - * also returns a -1 if it fails to open the tap file passed into it). - * get_taps() will have no effect on the array passed in if the error_flag - * is non-zero. write_freqres_to_file( ) returns different error codes - * depending on the nature of the error...see the function itself for details. - * - * The filters are designed using the "Fourier Series Method". This - * means that the coefficients of a Fourier Series approximation to the - * frequency response of an ideal filter (LPF, HPF, BPF) are used as - * the filter taps. The resulting filters have some ripple in the passband - * due to the Gibbs phenomenon; the filters are linear phase. - */ - -#ifndef _FILTER_H -#define _FILTER_H - -#define MAX_NUM_FILTER_TAPS 1000 - -#include -#include -#include -#include -#include -#include - -namespace dsp { -enum filterType { LPF, HPF, BPF }; - -class Filter { -private: - filterType m_filt_t; - int m_num_taps; - int m_error_flag; - double m_Fs; - double m_Fx; - double m_lambda; - double *m_taps; - double *m_sr; - void designLPF(); - void designHPF(); - - // Only needed for the bandpass filter case - double m_Fu, m_phi; - void designBPF(); - -public: - Filter(filterType filt_t, int num_taps, double Fs, double Fx); - Filter(filterType filt_t, int num_taps, double Fs, double Fl, double Fu); - ~Filter(); - void init(); - double do_sample(double data_sample); - int get_error_flag() { return m_error_flag; }; - void get_taps(double *taps); - int write_taps_to_file(char *filename); - int write_freqres_to_file(char *filename); -}; -} -#endif diff --git a/include/react/Algorithm.h b/include/react/Algorithm.h index 7caed812..a1d20b18 100644 --- a/include/react/Algorithm.h +++ b/include/react/Algorithm.h @@ -19,26 +19,6 @@ /*****************************************/ REACT_BEGIN /*****************************************/ -/////////////////////////////////////////////////////////////////////////////////////////////////// -/// Forward declarations -/////////////////////////////////////////////////////////////////////////////////////////////////// -template -class Signal; - -template -class VarSignal; - -template -class Events; - -template -class EventSource; - -enum class Token; - -template -class SignalPack; - /////////////////////////////////////////////////////////////////////////////////////////////////// /// Hold - Hold the most recent event in a signal /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -63,11 +43,12 @@ auto Hold(const Events& events, V&& init) /////////////////////////////////////////////////////////////////////////////////////////////////// template < - typename D, - typename S + typename SignalT, + typename D = typename SignalT::DomainT, + typename S = typename SignalT::ValueT > -auto Monitor(const Signal& target) - -> Events +auto Monitor(const SignalT& target) + -> Events { using REACT_IMPL::MonitorNode; @@ -140,7 +121,7 @@ template typename S = typename std::decay::type > auto Iterate(const Events& events, V&& init, - const SignalPack& depPack, FIn&& func) + const SignalPack& depPack, FIn&& func) -> Signal { using REACT_IMPL::SyncedIterateNode; @@ -281,4 +262,4 @@ auto ChangedTo(const Signal& target, V&& value) /******************************************/ REACT_END /******************************************/ -#endif // REACT_ALGORITHM_H_INCLUDED \ No newline at end of file +#endif // REACT_ALGORITHM_H_INCLUDED diff --git a/include/react/Domain.h b/include/react/Domain.h index e27c2514..ee638aaa 100644 --- a/include/react/Domain.h +++ b/include/react/Domain.h @@ -19,6 +19,8 @@ #include "react/detail/graph/ContinuationNodes.h" +#include "react/Forward.h" + #ifdef REACT_ENABLE_LOGGING #include "react/logging/EventLog.h" #include "react/logging/EventRecords.h" @@ -26,41 +28,6 @@ /*****************************************/ REACT_BEGIN /*****************************************/ -/////////////////////////////////////////////////////////////////////////////////////////////////// -/// Forward declarations -/////////////////////////////////////////////////////////////////////////////////////////////////// -template -class Signal; - -template -class VarSignal; - -template -class TempSignal; - -template -class Events; - -template -class EventSource; - -template -class TempEvents; - -enum class Token; - -template -class Observer; - -template -class ScopedObserver; - -template -class Reactor; - -template -class SignalPack; - /////////////////////////////////////////////////////////////////////////////////////////////////// /// Common types & constants /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -285,7 +252,7 @@ template typename ... TDepValues > auto MakeContinuation(TransactionFlagsT flags, const Events& trigger, - const SignalPack& depPack, FIn&& func) + const SignalPack& depPack, FIn&& func) -> Continuation { static_assert(DOut::is_concurrent, @@ -349,7 +316,7 @@ template typename ... TDepValues > auto MakeContinuation(const Events& trigger, - const SignalPack& depPack, FIn&& func) + const SignalPack& depPack, FIn&& func) -> Continuation { return MakeContinuation(0, trigger, depPack, std::forward(func)); @@ -461,4 +428,4 @@ void AsyncTransaction(TransactionFlagsT flags, TransactionStatus& status, F&& fu \ using ReactorT = Reactor; -#endif // REACT_DOMAIN_H_INCLUDED \ No newline at end of file +#endif // REACT_DOMAIN_H_INCLUDED diff --git a/include/react/Event.h b/include/react/Event.h index 2c286809..6c94fb9c 100644 --- a/include/react/Event.h +++ b/include/react/Event.h @@ -15,6 +15,7 @@ #include #include +#include "react/Forward.h" #include "react/Observer.h" #include "react/TypeTraits.h" #include "react/common/Util.h" @@ -22,26 +23,6 @@ /*****************************************/ REACT_BEGIN /*****************************************/ -/////////////////////////////////////////////////////////////////////////////////////////////////// -/// Forward declarations -/////////////////////////////////////////////////////////////////////////////////////////////////// -template -class Events; - -template -class EventSource; - -template -class TempEvents; - -enum class Token; - -template -class Signal; - -template -class SignalPack; - using REACT_IMPL::WeightHint; /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -228,7 +209,7 @@ template typename FIn, typename ... TDepValues > -auto Filter(const Events& source, const SignalPack& depPack, FIn&& func) +auto Filter(const Events& source, const SignalPack& depPack, FIn&& func) -> Events { using REACT_IMPL::SyncedEventFilterNode; @@ -313,7 +294,7 @@ template typename ... TDepValues, typename TOut = typename std::result_of::type > -auto Transform(const Events& source, const SignalPack& depPack, FIn&& func) +auto Transform(const Events& source, const SignalPack& depPack, FIn&& func) -> Events { using REACT_IMPL::SyncedEventTransformNode; @@ -379,7 +360,7 @@ template typename FIn, typename ... TDepValues > -auto Process(const Events& source, const SignalPack& depPack, FIn&& func) +auto Process(const Events& source, const SignalPack& depPack, FIn&& func) -> Events { using REACT_IMPL::SyncedEventProcessingNode; @@ -834,14 +815,4 @@ class TempEvents : public Events /******************************************/ REACT_END /******************************************/ -/***************************************/ REACT_IMPL_BEGIN /**************************************/ - -template -bool Equals(const Events& lhs, const Events& rhs) -{ - return lhs.Equals(rhs); -} - -/****************************************/ REACT_IMPL_END /***************************************/ - -#endif // REACT_EVENT_H_INCLUDED \ No newline at end of file +#endif // REACT_EVENT_H_INCLUDED diff --git a/include/react/Forward.h b/include/react/Forward.h new file mode 100644 index 00000000..98ee0742 --- /dev/null +++ b/include/react/Forward.h @@ -0,0 +1,55 @@ + +// Copyright Sebastian Jeckel 2014. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef REACT_FORWARD_H_INCLUDED +#define REACT_FORWARD_H_INCLUDED + +#pragma once + +#include "react/detail/Defs.h" + +/*****************************************/ REACT_BEGIN /*****************************************/ + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/// Forward declarations +/////////////////////////////////////////////////////////////////////////////////////////////////// + +template +class Signal; + +template +class VarSignal; + +template +class OpSignal; + +template +using ValueT = typename std::decay_t::value_type; + +template +struct SignalPack; + +template +class Events; + +template +class EventSource; + +template +class TempEvents; + +template +class Observer; + +template +class ScopedObserver; + +template +class Continuation; + +/******************************************/ REACT_END /******************************************/ + +#endif // REACT_FORWARD_H_INCLUDED diff --git a/include/react/Observer.h b/include/react/Observer.h index 45fd78a1..b955ac15 100644 --- a/include/react/Observer.h +++ b/include/react/Observer.h @@ -18,21 +18,10 @@ #include "react/detail/IReactiveNode.h" #include "react/detail/ObserverBase.h" #include "react/detail/graph/ObserverNodes.h" +#include "react/Forward.h" /*****************************************/ REACT_BEGIN /*****************************************/ -/////////////////////////////////////////////////////////////////////////////////////////////////// -/// Forward declarations -/////////////////////////////////////////////////////////////////////////////////////////////////// -template -class Signal; - -template -class SignalPack; - -template -class Events; - using REACT_IMPL::ObserverAction; using REACT_IMPL::WeightHint; @@ -264,7 +253,7 @@ template typename ... TDepValues > auto Observe(const Events& subject, - const SignalPack& depPack, FIn&& func) + const SignalPack& depPack, FIn&& func) -> Observer { using REACT_IMPL::IObserver; @@ -279,19 +268,19 @@ auto Observe(const Events& subject, using WrapperT = typename std::conditional< - IsCallableWith, TDepValues ...>::value, + IsCallableWith, ValueT ...>::value, F, typename std::conditional< - IsCallableWith::value, - AddObserverRangeWrapper, + IsCallableWith ...>::value, + AddObserverRangeWrapper ...>, typename std::conditional< - IsCallableWith, TDepValues ...>::value, + IsCallableWith, ValueT ...>::value, AddDefaultReturnValueWrapper, typename std::conditional< - IsCallableWith::value, + IsCallableWith ...>::value, AddObserverRangeWrapper, - TDepValues...>, + ValueT...>, void >::type >::type @@ -302,7 +291,7 @@ auto Observe(const Events& subject, ! std::is_same::value, "Observe: Passed function does not match any of the supported signatures."); - using NodeT = SyncedObserverNode; + using NodeT = SyncedObserverNode ...>; struct NodeBuilder_ { @@ -311,7 +300,7 @@ auto Observe(const Events& subject, MyFunc( std::forward(func) ) {} - auto operator()(const Signal& ... deps) + auto operator()(const TDepValues& ... deps) -> ObserverNode* { return new NodeT( @@ -337,4 +326,4 @@ auto Observe(const Events& subject, /******************************************/ REACT_END /******************************************/ -#endif // REACT_OBSERVER_H_INCLUDED \ No newline at end of file +#endif // REACT_OBSERVER_H_INCLUDED diff --git a/include/react/Signal.h b/include/react/Signal.h index 7f211392..578fc0ac 100644 --- a/include/react/Signal.h +++ b/include/react/Signal.h @@ -10,944 +10,432 @@ #pragma once #if _MSC_VER && !__INTEL_COMPILER - #pragma warning(disable : 4503) +#pragma warning(disable : 4503) #endif #include "react/detail/Defs.h" +#include #include #include #include #include +#include "react/Forward.h" #include "react/Observer.h" #include "react/TypeTraits.h" #include "react/detail/SignalBase.h" -/*****************************************/ REACT_BEGIN /*****************************************/ +namespace react { -/////////////////////////////////////////////////////////////////////////////////////////////////// -/// Forward declarations -/////////////////////////////////////////////////////////////////////////////////////////////////// -template -class Signal; +namespace impl { -template -class VarSignal; +template struct DomainTrait; + +template +using domain_t = typename DomainTrait...>::type; + +template +using value_t = typename std::decay_t::value_type; + +template +using if_not_signal_t = std::enable_if_t>::value>; + +template +using if_signal_t = std::enable_if_t>::value>; + +template +using if_not_event_t = std::enable_if_t>::value>; + +template +using if_event_t = std::enable_if_t>::value>; + +template struct DomainTrait { + using type = typename TSignal::DomainT; +}; + +template +struct DomainTrait { + static_assert(std::is_same::type, + typename DomainTrait::type>::value, + "domain mismatch"); + + using type = typename TSignal::DomainT; +}; + +template struct DomainTrait> { + using type = typename DomainTrait::type; +}; + +template +using functor_t = FunctionOp; template -class TempSignal; +using signal_op_node_t = SignalOpNode; + +template +auto make_op_node(F &&f, Args &&... args) { + using TOp = functor_t...>; + return std::make_shared>( + TOp{std::forward(f), std::forward(args)...}); +} + +template +auto make_op_signal(F &&f, TSignals &&... args) { + using D = domain_t; + using S = std::result_of_t...)>; + + return Signal{make_op_node( + std::forward(f), GetNodePtr(std::forward(args))...)}; +} + +using namespace std::placeholders; +} /////////////////////////////////////////////////////////////////////////////////////////////////// /// SignalPack - Wraps several nodes in a tuple. Create with comma operator. /////////////////////////////////////////////////////////////////////////////////////////////////// -template -< - typename D, - typename ... TValues -> -class SignalPack -{ -public: - SignalPack(const Signal& ... deps) : - Data( std::tie(deps ...) ) - {} - - template - SignalPack(const SignalPack& curArgs, const Signal& newArg) : - Data( std::tuple_cat(curArgs.Data, std::tie(newArg)) ) - {} - - std::tuple& ...> Data; + +template struct SignalPack { + SignalPack(const TSignals &... deps) : Data{deps...} {} + + template + SignalPack(const SignalPack &curArgs, const TSignal &newArg) + : Data{std::tuple_cat(curArgs.Data, std::tie(newArg))} {} + + std::tuple Data; }; /////////////////////////////////////////////////////////////////////////////////////////////////// /// With - Utility function to create a SignalPack /////////////////////////////////////////////////////////////////////////////////////////////////// -template -< - typename D, - typename ... TValues -> -auto With(const Signal& ... deps) - -> SignalPack -{ - return SignalPack(deps ...); + +template +auto With(const TSignals &... some_signals) -> SignalPack { + return SignalPack{some_signals...}; } /////////////////////////////////////////////////////////////////////////////////////////////////// /// MakeVar /////////////////////////////////////////////////////////////////////////////////////////////////// -template -< - typename D, - typename V, - typename S = typename std::decay::type, - class = typename std::enable_if< - ! IsSignal::value>::type, - class = typename std::enable_if< - ! IsEvent::value>::type -> -auto MakeVar(V&& value) - -> VarSignal -{ - return VarSignal( - std::make_shared>( - std::forward(value))); -} -template -< - typename D, - typename S -> -auto MakeVar(std::reference_wrapper value) - -> VarSignal -{ - return VarSignal( - std::make_shared>>(value)); +template ::type, + class = impl::if_not_signal_t, class = impl::if_not_event_t> +auto MakeVar(V &&value) -> VarSignal { + return VarSignal( + std::make_shared>(std::forward(value))); } /////////////////////////////////////////////////////////////////////////////////////////////////// /// MakeVar (higher order reactives) /////////////////////////////////////////////////////////////////////////////////////////////////// -template -< - typename D, - typename V, - typename S = typename std::decay::type, - typename TInner = typename S::ValueT, - class = typename std::enable_if< - IsSignal::value>::type -> -auto MakeVar(V&& value) - -> VarSignal> -{ - return VarSignal>( - std::make_shared>>( - std::forward(value))); +template ::type, + typename TInner = typename S::value_type, + class = typename std::enable_if::value>::type> +auto MakeVar(V &&value) -> VarSignal> { + return VarSignal>( + std::make_shared>>( + std::forward(value))); } -template -< - typename D, - typename V, - typename S = typename std::decay::type, - typename TInner = typename S::ValueT, - class = typename std::enable_if< - IsEvent::value>::type -> -auto MakeVar(V&& value) - -> VarSignal> -{ - return VarSignal>( - std::make_shared>>( - std::forward(value))); +template ::type, + typename TInner = typename S::value_type, + class = typename std::enable_if::value>::type> +auto MakeVar(V &&value) -> VarSignal> { + return VarSignal>( + std::make_shared>>( + std::forward(value))); } /////////////////////////////////////////////////////////////////////////////////////////////////// /// MakeSignal /////////////////////////////////////////////////////////////////////////////////////////////////// + // Single arg -template -< - typename D, - typename TValue, - typename FIn, - typename F = typename std::decay::type, - typename S = typename std::result_of::type, - typename TOp = REACT_IMPL::FunctionOp> -> -auto MakeSignal(const Signal& arg, FIn&& func) - -> TempSignal -{ - return TempSignal( - std::make_shared>( - std::forward(func), GetNodePtr(arg))); +template , + typename S = std::result_of_t> +auto MakeSignal(const Signal &arg, FIn &&func) { + return Signal( + impl::make_op_node(std::forward(func), GetNodePtr(arg))); +} + +// Multiple args +template +auto MakeNode(F &&f, const Tuple &tuple, std::index_sequence) { + return impl::make_op_node(std::forward(f), + GetNodePtr(std::get(tuple))...); } // Multiple args -template -< - typename D, - typename ... TValues, - typename FIn, - typename F = typename std::decay::type, - typename S = typename std::result_of::type, - typename TOp = REACT_IMPL::FunctionOp ...> -> -auto MakeSignal(const SignalPack& argPack, FIn&& func) - -> TempSignal -{ - using REACT_IMPL::SignalOpNode; - - struct NodeBuilder_ - { - NodeBuilder_(FIn&& func) : - MyFunc( std::forward(func) ) - {} - - auto operator()(const Signal& ... args) - -> TempSignal - { - return TempSignal( - std::make_shared>( - std::forward(MyFunc), GetNodePtr(args) ...)); - } - - FIn MyFunc; - }; - - return REACT_IMPL::apply( - NodeBuilder_( std::forward(func) ), - argPack.Data); +template , + typename F = std::decay_t, + typename S = std::result_of_t...)>> +auto MakeSignal(const SignalPack &argPack, FIn &&func) { + return Signal{ + MakeNode(std::forward(func), argPack.Data, + impl::indices_t>())}; } /////////////////////////////////////////////////////////////////////////////////////////////////// -/// Unary operators +/// ValueTypeTrait /////////////////////////////////////////////////////////////////////////////////////////////////// -#define REACT_DECLARE_OP(op,name) \ -template \ -struct name ## OpFunctor \ -{ \ - T operator()(const T& v) const { return op v; } \ -}; \ - \ -template \ -< \ - typename TSignal, \ - typename D = typename TSignal::DomainT, \ - typename TVal = typename TSignal::ValueT, \ - class = typename std::enable_if< \ - IsSignal::value>::type, \ - typename F = name ## OpFunctor, \ - typename S = typename std::result_of::type, \ - typename TOp = REACT_IMPL::FunctionOp> \ -> \ -auto operator op(const TSignal& arg) \ - -> TempSignal \ -{ \ - return TempSignal( \ - std::make_shared>( \ - F(), GetNodePtr(arg))); \ -} \ - \ -template \ -< \ - typename D, \ - typename TVal, \ - typename TOpIn, \ - typename F = name ## OpFunctor, \ - typename S = typename std::result_of::type, \ - typename TOp = REACT_IMPL::FunctionOp \ -> \ -auto operator op(TempSignal&& arg) \ - -> TempSignal \ -{ \ - return TempSignal( \ - std::make_shared>( \ - F(), arg.StealOp())); \ -} -REACT_DECLARE_OP(+, UnaryPlus) -REACT_DECLARE_OP(-, UnaryMinus) -REACT_DECLARE_OP(!, LogicalNegation) -REACT_DECLARE_OP(~, BitwiseComplement) -REACT_DECLARE_OP(++, Increment) -REACT_DECLARE_OP(--, Decrement) +template struct ValueTypeTrait { using type = S; }; -#undef REACT_DECLARE_OP +template struct ValueTypeTrait { + using type = std::reference_wrapper; +}; /////////////////////////////////////////////////////////////////////////////////////////////////// -/// Binary operators +/// Signal /////////////////////////////////////////////////////////////////////////////////////////////////// -#define REACT_DECLARE_OP(op,name) \ -template \ -struct name ## OpFunctor \ -{ \ - auto operator()(const L& lhs, const R& rhs) const \ - -> decltype(std::declval() op std::declval()) \ - { \ - return lhs op rhs; \ - } \ -}; \ - \ -template \ -struct name ## OpRFunctor \ -{ \ - name ## OpRFunctor(name ## OpRFunctor&& other) : \ - LeftVal( std::move(other.LeftVal) ) \ - {} \ - \ - template \ - name ## OpRFunctor(T&& val) : \ - LeftVal( std::forward(val) ) \ - {} \ - \ - name ## OpRFunctor(const name ## OpRFunctor& other) = delete; \ - \ - auto operator()(const R& rhs) const \ - -> decltype(std::declval() op std::declval()) \ - { \ - return LeftVal op rhs; \ - } \ - \ - L LeftVal; \ -}; \ - \ -template \ -struct name ## OpLFunctor \ -{ \ - name ## OpLFunctor(name ## OpLFunctor&& other) : \ - RightVal( std::move(other.RightVal) ) \ - {} \ - \ - template \ - name ## OpLFunctor(T&& val) : \ - RightVal( std::forward(val) ) \ - {} \ - \ - name ## OpLFunctor(const name ## OpLFunctor& other) = delete; \ - \ - auto operator()(const L& lhs) const \ - -> decltype(std::declval() op std::declval()) \ - { \ - return lhs op RightVal; \ - } \ - \ - R RightVal; \ -}; \ - \ -template \ -< \ - typename TLeftSignal, \ - typename TRightSignal, \ - typename D = typename TLeftSignal::DomainT, \ - typename TLeftVal = typename TLeftSignal::ValueT, \ - typename TRightVal = typename TRightSignal::ValueT, \ - class = typename std::enable_if< \ - IsSignal::value>::type, \ - class = typename std::enable_if< \ - IsSignal::value>::type, \ - typename F = name ## OpFunctor, \ - typename S = typename std::result_of::type, \ - typename TOp = REACT_IMPL::FunctionOp, \ - REACT_IMPL::SignalNodePtrT> \ -> \ -auto operator op(const TLeftSignal& lhs, const TRightSignal& rhs) \ - -> TempSignal \ -{ \ - return TempSignal( \ - std::make_shared>( \ - F(), GetNodePtr(lhs), GetNodePtr(rhs))); \ -} \ - \ -template \ -< \ - typename TLeftSignal, \ - typename TRightValIn, \ - typename D = typename TLeftSignal::DomainT, \ - typename TLeftVal = typename TLeftSignal::ValueT, \ - typename TRightVal = typename std::decay::type, \ - class = typename std::enable_if< \ - IsSignal::value>::type, \ - class = typename std::enable_if< \ - ! IsSignal::value>::type, \ - typename F = name ## OpLFunctor, \ - typename S = typename std::result_of::type, \ - typename TOp = REACT_IMPL::FunctionOp> \ -> \ -auto operator op(const TLeftSignal& lhs, TRightValIn&& rhs) \ - -> TempSignal \ -{ \ - return TempSignal( \ - std::make_shared>( \ - F( std::forward(rhs) ), GetNodePtr(lhs))); \ -} \ - \ -template \ -< \ - typename TLeftValIn, \ - typename TRightSignal, \ - typename D = typename TRightSignal::DomainT, \ - typename TLeftVal = typename std::decay::type, \ - typename TRightVal = typename TRightSignal::ValueT, \ - class = typename std::enable_if< \ - ! IsSignal::value>::type, \ - class = typename std::enable_if< \ - IsSignal::value>::type, \ - typename F = name ## OpRFunctor, \ - typename S = typename std::result_of::type, \ - typename TOp = REACT_IMPL::FunctionOp> \ -> \ -auto operator op(TLeftValIn&& lhs, const TRightSignal& rhs) \ - -> TempSignal \ -{ \ - return TempSignal( \ - std::make_shared>( \ - F( std::forward(lhs) ), GetNodePtr(rhs))); \ -} \ -template \ -< \ - typename D, \ - typename TLeftVal, \ - typename TLeftOp, \ - typename TRightVal, \ - typename TRightOp, \ - typename F = name ## OpFunctor, \ - typename S = typename std::result_of::type, \ - typename TOp = REACT_IMPL::FunctionOp \ -> \ -auto operator op(TempSignal&& lhs, \ - TempSignal&& rhs) \ - -> TempSignal \ -{ \ - return TempSignal( \ - std::make_shared>( \ - F(), lhs.StealOp(), rhs.StealOp())); \ -} \ - \ -template \ -< \ - typename D, \ - typename TLeftVal, \ - typename TLeftOp, \ - typename TRightSignal, \ - typename TRightVal = typename TRightSignal::ValueT, \ - class = typename std::enable_if< \ - IsSignal::value>::type, \ - typename F = name ## OpFunctor, \ - typename S = typename std::result_of::type, \ - typename TOp = REACT_IMPL::FunctionOp> \ -> \ -auto operator op(TempSignal&& lhs, \ - const TRightSignal& rhs) \ - -> TempSignal \ -{ \ - return TempSignal( \ - std::make_shared>( \ - F(), lhs.StealOp(), GetNodePtr(rhs))); \ -} \ - \ -template \ -< \ - typename TLeftSignal, \ - typename D, \ - typename TRightVal, \ - typename TRightOp, \ - typename TLeftVal = typename TLeftSignal::ValueT, \ - class = typename std::enable_if< \ - IsSignal::value>::type, \ - typename F = name ## OpFunctor, \ - typename S = typename std::result_of::type, \ - typename TOp = REACT_IMPL::FunctionOp, \ - TRightOp> \ -> \ -auto operator op(const TLeftSignal& lhs, TempSignal&& rhs) \ - -> TempSignal \ -{ \ - return TempSignal( \ - std::make_shared>( \ - F(), GetNodePtr(lhs), rhs.StealOp())); \ -} \ - \ -template \ -< \ - typename D, \ - typename TLeftVal, \ - typename TLeftOp, \ - typename TRightValIn, \ - typename TRightVal = typename std::decay::type, \ - class = typename std::enable_if< \ - ! IsSignal::value>::type, \ - typename F = name ## OpLFunctor, \ - typename S = typename std::result_of::type, \ - typename TOp = REACT_IMPL::FunctionOp \ -> \ -auto operator op(TempSignal&& lhs, TRightValIn&& rhs) \ - -> TempSignal \ -{ \ - return TempSignal( \ - std::make_shared>( \ - F( std::forward(rhs) ), lhs.StealOp())); \ -} \ - \ -template \ -< \ - typename TLeftValIn, \ - typename D, \ - typename TRightVal, \ - typename TRightOp, \ - typename TLeftVal = typename std::decay::type, \ - class = typename std::enable_if< \ - ! IsSignal::value>::type, \ - typename F = name ## OpRFunctor, \ - typename S = typename std::result_of::type, \ - typename TOp = REACT_IMPL::FunctionOp \ -> \ -auto operator op(TLeftValIn&& lhs, TempSignal&& rhs) \ - -> TempSignal \ -{ \ - return TempSignal( \ - std::make_shared>( \ - F( std::forward(lhs) ), rhs.StealOp())); \ -} - -REACT_DECLARE_OP(+, Addition) -REACT_DECLARE_OP(-, Subtraction) -REACT_DECLARE_OP(*, Multiplication) -REACT_DECLARE_OP(/, Division) -REACT_DECLARE_OP(%, Modulo) - -REACT_DECLARE_OP(==, Equal) -REACT_DECLARE_OP(!=, NotEqual) -REACT_DECLARE_OP(<, Less) -REACT_DECLARE_OP(<=, LessEqual) -REACT_DECLARE_OP(>, Greater) -REACT_DECLARE_OP(>=, GreaterEqual) - -REACT_DECLARE_OP(&&, LogicalAnd) -REACT_DECLARE_OP(||, LogicalOr) - -REACT_DECLARE_OP(&, BitwiseAnd) -REACT_DECLARE_OP(|, BitwiseOr) -REACT_DECLARE_OP(^, BitwiseXor) -//REACT_DECLARE_OP(<<, BitwiseLeftShift); // MSVC: Internal compiler error -//REACT_DECLARE_OP(>>, BitwiseRightShift); - -#undef REACT_DECLARE_OP -/////////////////////////////////////////////////////////////////////////////////////////////////// -/// Comma operator overload to create signal pack from 2 signals. -/////////////////////////////////////////////////////////////////////////////////////////////////// -template -< - typename D, - typename TLeftVal, - typename TRightVal -> -auto operator,(const Signal& a, const Signal& b) - -> SignalPack -{ - return SignalPack(a, b); +template struct Signal { + using value_type = typename ValueTypeTrait::type; + using ValueT = value_type; + using NodeT = REACT_IMPL::SignalNode; + using NodePtrT = std::shared_ptr; + using DomainT = D; + + Signal() : ptr_{} {} + explicit Signal(NodePtrT p) : ptr_{std::move(p)} {} + + // Signal(const Signal &) = delete; + // Signal& operator =(const Signal &) = delete; + + // Signal(Signal &&) = default; + // Signal& operator =(Signal &&) = default; + + const value_type &Value() const { return ptr_->ValueRef(); } + const value_type &operator()() const { return Value(); } + + template bool Equals(const Signal &other) const { + return ptr_ == other.ptr_; + } + + const NodePtrT &node_ptr() const { return ptr_; } + + bool Equals(const Signal &other) const { return ptr_ == other.ptr_; } + +protected: + using input_manager_type = REACT_IMPL::InputManager; + + static input_manager_type &input_manager() { + return REACT_IMPL::DomainSpecificInputManager::Instance(); + } + +private: + NodePtrT ptr_; +}; + +template +bool Equals(const Signal &lhs, const Signal &rhs) { + return lhs.Equals(rhs); } /////////////////////////////////////////////////////////////////////////////////////////////////// -/// Comma operator overload to append node to existing signal pack. +/// Operators /////////////////////////////////////////////////////////////////////////////////////////////////// -template -< - typename D, - typename ... TCurValues, - typename TAppendValue -> -auto operator,(const SignalPack& cur, const Signal& append) - -> SignalPack -{ - return SignalPack(cur, append); + +template +auto operator+(const Signal &l, const Signal &r) { + return impl::make_op_signal(std::plus<>(), l, r); } -/////////////////////////////////////////////////////////////////////////////////////////////////// -/// operator->* overload to connect signals to a function and return the resulting signal. -/////////////////////////////////////////////////////////////////////////////////////////////////// -// Single arg -template -< - typename D, - typename F, - template class TSignal, - typename TValue, - class = typename std::enable_if< - IsSignal>::value>::type -> -auto operator->*(const TSignal& arg, F&& func) - -> Signal::type> -{ - return REACT::MakeSignal(arg, std::forward(func)); +template > +auto operator+(const Signal &l, RV &&r) { + return impl::make_op_signal( + std::bind(std::plus<>(), impl::_1, std::forward(r)), l); } -// Multiple args -template -< - typename D, - typename F, - typename ... TValues -> -auto operator->*(const SignalPack& argPack, F&& func) - -> Signal::type> -{ - return REACT::MakeSignal(argPack, std::forward(func)); +template > +auto operator+(LV &&l, const Signal &r) { + return impl::make_op_signal( + std::bind(std::plus<>(), std::forward(l), impl::_1), r); +} + +template +auto operator-(const Signal &l, const Signal &r) { + return impl::make_op_signal(std::minus<>(), l, r); +} + +template > +auto operator-(const Signal &l, RV &&r) { + return impl::make_op_signal( + std::bind(std::minus<>(), impl::_1, std::forward(r)), l); +} + +template > +auto operator-(LV &&l, const Signal &r) { + return impl::make_op_signal( + std::bind(std::minus<>(), std::forward(l), impl::_1), r); +} + +template +auto operator*(const Signal &l, const Signal &r) { + return impl::make_op_signal(std::multiplies<>(), l, r); +} + +template > +auto operator*(const Signal &l, RV &&r) { + return impl::make_op_signal( + std::bind(std::multiplies<>(), impl::_1, std::forward(r)), l); +} + +template > +auto operator*(LV &&l, const Signal &r) { + return impl::make_op_signal( + std::bind(std::multiplies<>(), std::forward(l), impl::_1), r); +} + +template +auto operator/(const Signal &l, const Signal &r) { + return impl::make_op_signal(std::divides<>(), l, r); +} + +template > +auto operator/(const Signal &l, RV &&r) { + return impl::make_op_signal( + std::bind(std::divides<>(), impl::_1, std::forward(r)), l); +} + +template > +auto operator/(LV &&l, const Signal &r) { + return impl::make_op_signal( + std::bind(std::divides<>(), std::forward(l), impl::_1), r); +} + +template +Signal operator-(const Signal &in) { + return S{-1} * in; +} + +template +const auto &GetNodePtr(const Signal &s) { + return s.node_ptr(); } /////////////////////////////////////////////////////////////////////////////////////////////////// /// Flatten /////////////////////////////////////////////////////////////////////////////////////////////////// -template -< - typename D, - typename TInnerValue -> -auto Flatten(const Signal>& outer) - -> Signal -{ - return Signal( - std::make_shared, TInnerValue>>( - GetNodePtr(outer), GetNodePtr(outer.Value()))); +template +auto Flatten(const Signal &outer) -> Signal { + return Signal( + std::make_shared< + REACT_IMPL::FlattenNode, TInnerValue>>( + GetNodePtr(outer), GetNodePtr(outer.Value()))); } /////////////////////////////////////////////////////////////////////////////////////////////////// -/// Signal +/// VarSignal /////////////////////////////////////////////////////////////////////////////////////////////////// -template -< - typename D, - typename S -> -class Signal : public REACT_IMPL::SignalBase -{ -private: - using NodeT = REACT_IMPL::SignalNode; - using NodePtrT = std::shared_ptr; - -public: - using ValueT = S; - - // Default ctor - Signal() = default; - - // Copy ctor - Signal(const Signal&) = default; - - // Move ctor - Signal(Signal&& other) : - Signal::SignalBase( std::move(other) ) - {} - - // Node ctor - explicit Signal(NodePtrT&& nodePtr) : - Signal::SignalBase( std::move(nodePtr) ) - {} - - // Copy assignment - Signal& operator=(const Signal&) = default; - - // Move assignment - Signal& operator=(Signal&& other) - { - Signal::SignalBase::operator=( std::move(other) ); - return *this; - } - - const S& Value() const { return Signal::SignalBase::getValue(); } - const S& operator()() const { return Signal::SignalBase::getValue(); } - - bool Equals(const Signal& other) const - { - return Signal::SignalBase::Equals(other); - } - - bool IsValid() const - { - return Signal::SignalBase::IsValid(); - } - - void SetWeightHint(WeightHint weight) - { - Signal::SignalBase::SetWeightHint(weight); - } - - S Flatten() const - { - static_assert(IsSignal::value || IsEvent::value, - "Flatten requires a Signal or Events value type."); - return REACT::Flatten(*this); - } -}; -// Specialize for references -template -< - typename D, - typename S -> -class Signal : public REACT_IMPL::SignalBase> -{ -private: - using NodeT = REACT_IMPL::SignalNode>; - using NodePtrT = std::shared_ptr; - -public: - using ValueT = S; - - // Default ctor - Signal() = default; - - // Copy ctor - Signal(const Signal&) = default; - - // Move ctor - Signal(Signal&& other) : - Signal::SignalBase( std::move(other) ) - {} - - // Node ctor - explicit Signal(NodePtrT&& nodePtr) : - Signal::SignalBase( std::move(nodePtr) ) - {} - - // Copy assignment - Signal& operator=(const Signal&) = default; - - // Move assignment - Signal& operator=(Signal&& other) - { - Signal::SignalBase::operator=( std::move(other) ); - return *this; - } - - const S& Value() const { return Signal::SignalBase::getValue(); } - const S& operator()() const { return Signal::SignalBase::getValue(); } - - bool Equals(const Signal& other) const - { - return Signal::SignalBase::Equals(other); - } - - bool IsValid() const - { - return Signal::SignalBase::IsValid(); - } - - void SetWeightHint(WeightHint weight) - { - Signal::SignalBase::SetWeightHint(weight); - } -}; +template struct VarSignal : Signal { + using NodeT = REACT_IMPL::VarNode; + using NodePtrT = std::shared_ptr; + using typename Signal::value_type; -/////////////////////////////////////////////////////////////////////////////////////////////////// -/// VarSignal -/////////////////////////////////////////////////////////////////////////////////////////////////// -template -< - typename D, - typename S -> -class VarSignal : public Signal -{ -private: - using NodeT = REACT_IMPL::VarNode; - using NodePtrT = std::shared_ptr; - -public: - // Default ctor - VarSignal() = default; - - // Copy ctor - VarSignal(const VarSignal&) = default; - - // Move ctor - VarSignal(VarSignal&& other) : - VarSignal::Signal( std::move(other) ) - {} - - // Node ctor - explicit VarSignal(NodePtrT&& nodePtr) : - VarSignal::Signal( std::move(nodePtr) ) - {} - - // Copy assignment - VarSignal& operator=(const VarSignal&) = default; - - // Move assignment - VarSignal& operator=(VarSignal&& other) - { - VarSignal::SignalBase::operator=( std::move(other) ); - return *this; - } - - void Set(const S& newValue) const - { - VarSignal::SignalBase::setValue(newValue); - } - - void Set(S&& newValue) const - { - VarSignal::SignalBase::setValue(std::move(newValue)); - } - - const VarSignal& operator<<=(const S& newValue) const - { - VarSignal::SignalBase::setValue(newValue); - return *this; - } - - const VarSignal& operator<<=(S&& newValue) const - { - VarSignal::SignalBase::setValue(std::move(newValue)); - return *this; - } - - template - void Modify(const F& func) const - { - VarSignal::SignalBase::modifyValue(func); - } -}; + explicit VarSignal(NodePtrT nodePtr) : Signal{nodePtr} {} + + void Set(const value_type &newValue) const { + Signal::input_manager().AddInput(var_node(), newValue); + } + + void Set(value_type &&newValue) const { + Signal::input_manager().AddInput(var_node(), std::move(newValue)); + } + + const VarSignal &operator<<=(const value_type &newValue) const { + Set(newValue); + return *this; + } + + const VarSignal &operator<<=(value_type &&newValue) const { + Set(std::move(newValue)); + return *this; + } + + template void Modify(const F &func) const { + Signal::input_manager().ModifyInput(var_node(), func); + } -// Specialize for references -template -< - typename D, - typename S -> -class VarSignal : public Signal> -{ private: - using NodeT = REACT_IMPL::VarNode>; - using NodePtrT = std::shared_ptr; - -public: - using ValueT = S; - - // Default ctor - VarSignal() = default; - - // Copy ctor - VarSignal(const VarSignal&) = default; - - // Move ctor - VarSignal(VarSignal&& other) : - VarSignal::Signal( std::move(other) ) - {} - - // Node ctor - explicit VarSignal(NodePtrT&& nodePtr) : - VarSignal::Signal( std::move(nodePtr) ) - {} - - // Copy assignment - VarSignal& operator=(const VarSignal&) = default; - - // Move assignment - VarSignal& operator=(VarSignal&& other) - { - VarSignal::Signal::operator=( std::move(other) ); - return *this; - } - - void Set(std::reference_wrapper newValue) const - { - VarSignal::SignalBase::setValue(newValue); - } - - const VarSignal& operator<<=(std::reference_wrapper newValue) const - { - VarSignal::SignalBase::setValue(newValue); - return *this; - } + NodeT &var_node() const { + return *std::static_pointer_cast(this->node_ptr()); + } }; /////////////////////////////////////////////////////////////////////////////////////////////////// -/// TempSignal +/// Comma operator overload to create signal pack from 2 signals. /////////////////////////////////////////////////////////////////////////////////////////////////// -template -< - typename D, - typename S, - typename TOp -> -class TempSignal : public Signal -{ -private: - using NodeT = REACT_IMPL::SignalOpNode; - using NodePtrT = std::shared_ptr; - -public: - // Default ctor - TempSignal() = default; - - // Copy ctor - TempSignal(const TempSignal&) = default; - - // Move ctor - TempSignal(TempSignal&& other) : - TempSignal::Signal( std::move(other) ) - {} - - // Node ctor - explicit TempSignal(NodePtrT&& ptr) : - TempSignal::Signal( std::move(ptr) ) - {} - - // Copy assignment - TempSignal& operator=(const TempSignal&) = default; - - // Move assignemnt - TempSignal& operator=(TempSignal&& other) - { - TempSignal::Signal::operator=( std::move(other) ); - return *this; - } - - TOp StealOp() - { - return std::move(reinterpret_cast(this->ptr_.get())->StealOp()); - } -}; +template +auto operator,(const Signal &a, const Signal &b) { + return SignalPack, Signal>{a, b}; +} -/******************************************/ REACT_END /******************************************/ +/////////////////////////////////////////////////////////////////////////////////////////////////// +/// Comma operator overload to append node to existing signal pack. +/////////////////////////////////////////////////////////////////////////////////////////////////// +template +auto operator,(const SignalPack &cur, + const Signal &append) { + return SignalPack>{cur, append}; +} -/***************************************/ REACT_IMPL_BEGIN /**************************************/ +/////////////////////////////////////////////////////////////////////////////////////////////////// +/// operator->* overload to connect signals to a function and return the +/// resulting signal. +/////////////////////////////////////////////////////////////////////////////////////////////////// -template -bool Equals(const Signal& lhs, const Signal& rhs) -{ - return lhs.Equals(rhs); +// Single arg +template +auto operator->*(const Signal &arg, F &&func) { + return MakeSignal(arg, std::forward(func)); } -/****************************************/ REACT_IMPL_END /***************************************/ +// Multiple args +template +auto operator->*(const SignalPack &argPack, F &&func) { + return MakeSignal(argPack, std::forward(func)); +} +} /////////////////////////////////////////////////////////////////////////////////////////////////// /// Flatten macros /////////////////////////////////////////////////////////////////////////////////////////////////// -// Note: Using static_cast rather than -> return type, because when using lambda for inline +// Note: Using static_cast rather than -> return type, because when using lambda +// for inline // class initialization, decltype did not recognize the parameter r // Note2: MSVC doesn't like typename in the lambda #if _MSC_VER && !__INTEL_COMPILER - #define REACT_MSVC_NO_TYPENAME +#define REACT_MSVC_NO_TYPENAME #else - #define REACT_MSVC_NO_TYPENAME typename +#define REACT_MSVC_NO_TYPENAME typename #endif -#define REACTIVE_REF(obj, name) \ - Flatten( \ - MakeSignal( \ - obj, \ - [] (const REACT_MSVC_NO_TYPENAME \ - REACT_IMPL::Identity::Type::ValueT& r) \ - { \ - using T = decltype(r.name); \ - using S = REACT_MSVC_NO_TYPENAME REACT::DecayInput::Type; \ - return static_cast(r.name); \ - })) - -#define REACTIVE_PTR(obj, name) \ - Flatten( \ - MakeSignal( \ - obj, \ - [] (REACT_MSVC_NO_TYPENAME \ - REACT_IMPL::Identity::Type::ValueT r) \ - { \ - assert(r != nullptr); \ - using T = decltype(r->name); \ - using S = REACT_MSVC_NO_TYPENAME REACT::DecayInput::Type; \ - return static_cast(r->name); \ - })) - -#endif // REACT_SIGNAL_H_INCLUDED \ No newline at end of file +#define REACTIVE_REF(obj, name) \ + Flatten(MakeSignal( \ + obj, [](const REACT_MSVC_NO_TYPENAME REACT_IMPL::Identity::Type::ValueT &r) { return r.name; })) + +#define REACTIVE_PTR(obj, name) \ + Flatten(MakeSignal( \ + obj, [](REACT_MSVC_NO_TYPENAME \ + REACT_IMPL::Identity::Type::ValueT r) { \ + assert(r != nullptr); \ + using T = decltype(r->name); \ + using S = REACT_MSVC_NO_TYPENAME REACT::DecayInput::Type; \ + return static_cast(r->name); \ + })) + +#endif // REACT_SIGNAL_H_INCLUDED diff --git a/include/react/TypeTraits.h b/include/react/TypeTraits.h index c6b6b7dd..6f46fd14 100644 --- a/include/react/TypeTraits.h +++ b/include/react/TypeTraits.h @@ -11,37 +11,9 @@ #include "react/detail/Defs.h" -/*****************************************/ REACT_BEGIN /*****************************************/ - -/////////////////////////////////////////////////////////////////////////////////////////////////// -/// Forward declarations -/////////////////////////////////////////////////////////////////////////////////////////////////// -template -class Signal; - -template -class VarSignal; - -template -class TempSignal; - -template -class Events; +#include "react/Forward.h" -template -class EventSource; - -template -class TempEvents; - -template -class Observer; - -template -class ScopedObserver; - -template -class Continuation; +/*****************************************/ REACT_BEGIN /*****************************************/ /////////////////////////////////////////////////////////////////////////////////////////////////// /// IsSignal @@ -56,7 +28,7 @@ template struct IsSignal> { static const bool value = true; }; template -struct IsSignal> { static const bool value = true; }; +struct IsSignal> { static const bool value = true; }; /////////////////////////////////////////////////////////////////////////////////////////////////// /// IsEvent @@ -107,7 +79,7 @@ template struct IsObservable> { static const bool value = true; }; template -struct IsObservable> { static const bool value = true; }; +struct IsObservable> { static const bool value = true; }; template struct IsObservable> { static const bool value = true; }; @@ -131,7 +103,7 @@ template struct IsReactive> { static const bool value = true; }; template -struct IsReactive> { static const bool value = true; }; +struct IsReactive> { static const bool value = true; }; template struct IsReactive> { static const bool value = true; }; @@ -165,4 +137,4 @@ struct DecayInput> { using Type = Events; }; /******************************************/ REACT_END /******************************************/ -#endif // REACT_TYPETRAITS_H_INCLUDED \ No newline at end of file +#endif // REACT_TYPETRAITS_H_INCLUDED diff --git a/include/react/common/Concurrency.h b/include/react/common/Concurrency.h index e27fd9ba..9065f9c0 100644 --- a/include/react/common/Concurrency.h +++ b/include/react/common/Concurrency.h @@ -76,19 +76,6 @@ class WaitingStateBase : public IWaitingState }// ~mutex_ } - inline bool IsWaiting() - {// mutex_ - std::lock_guard scopedLock(mutex_); - return isWaiting_; - }// ~mutex_ - - template - auto Run(F&& func) -> decltype(func(false)) - {// mutex_ - std::lock_guard scopedLock(mutex_); - return func(isWaiting_); - }// ~mutex_ - template bool RunIfWaiting(F&& func) {// mutex_ @@ -101,18 +88,6 @@ class WaitingStateBase : public IWaitingState return true; }// ~mutex_ - template - bool RunIfNotWaiting(F&& func) - {// mutex_ - std::lock_guard scopedLock(mutex_); - - if (isWaiting_) - return false; - - func(); - return true; - }// ~mutex_ - private: std::atomic waitCount_{ 0 }; std::condition_variable condition_; @@ -221,75 +196,6 @@ class SharedWaitingStateCollection : public IWaitingState std::vector others_; }; -/////////////////////////////////////////////////////////////////////////////////////////////////// -/// BlockingCondition -/////////////////////////////////////////////////////////////////////////////////////////////////// -class BlockingCondition -{ -public: - inline void Block() - {// mutex_ - std::lock_guard scopedLock(mutex_); - blocked_ = true; - }// ~mutex_ - - inline void Unblock() - {// mutex_ - std::lock_guard scopedLock(mutex_); - blocked_ = false; - condition_.notify_all(); - }// ~mutex_ - - inline void WaitForUnblock() - { - std::unique_lock lock(mutex_); - condition_.wait(lock, [this] { return !blocked_; }); - } - - inline bool IsBlocked() - {// mutex_ - std::lock_guard scopedLock(mutex_); - return blocked_; - }// ~mutex_ - - template - auto Run(F&& func) -> decltype(func(false)) - {// mutex_ - std::lock_guard scopedLock(mutex_); - return func(blocked_); - }// ~mutex_ - - template - bool RunIfBlocked(F&& func) - {// mutex_ - std::lock_guard scopedLock(mutex_); - - if (!blocked_) - return false; - - func(); - return true; - }// ~mutex_ - - template - bool RunIfUnblocked(F&& func) - {// mutex_ - std::lock_guard scopedLock(mutex_); - - if (blocked_) - return false; - - func(); - return true; - }// ~mutex_ - -private: - std::mutex mutex_; - std::condition_variable condition_; - - bool blocked_ = false; -}; - /////////////////////////////////////////////////////////////////////////////////////////////////// /// ConditionalCriticalSection /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -321,4 +227,4 @@ class ConditionalCriticalSection /****************************************/ REACT_IMPL_END /***************************************/ -#endif // REACT_COMMON_CONCURRENCY_H_INCLUDED \ No newline at end of file +#endif // REACT_COMMON_CONCURRENCY_H_INCLUDED diff --git a/include/react/common/Containers.h b/include/react/common/Containers.h index 9b77de06..1064b1b0 100644 --- a/include/react/common/Containers.h +++ b/include/react/common/Containers.h @@ -117,7 +117,7 @@ class NodeBuffer front_( nodes_.begin() ), back_( nodes_.begin() ) { - for (auto i=0; i -#include - -#include "tbb/queuing_mutex.h" - -/***************************************/ REACT_IMPL_BEGIN /**************************************/ - -/////////////////////////////////////////////////////////////////////////////////////////////////// -/// SourceIdSet -/////////////////////////////////////////////////////////////////////////////////////////////////// -template -class SourceIdSet -{ -private: - using MutexT = tbb::queuing_mutex; - using DataT = std::vector; - -public: - void Insert(const T& e) - { - MutexT::scoped_lock lock(mutex_); - - data_.push_back(e); - - isSorted_ = false; - } - - void Insert(SourceIdSet& other) - { - MutexT::scoped_lock myLock(mutex_); - MutexT::scoped_lock otherLock(other.mutex_); - - sort(); - other.sort(); - - auto l = data_.begin(); - auto r = data_.end(); - auto offset = std::distance(l,r); - - // For each element in other, check if it's already contained in this - // if not, add it - for (const auto& e : other.data_) - { - l = std::lower_bound(l, r, e); - - // Already in the set? - if (l < r && *l == e) - continue; - - auto d = std::distance(data_.begin(), l); - - data_.push_back(e); - - // push_back invalidates iterators - l = data_.begin() + d; - r = data_.begin() + offset; - } - - std::inplace_merge(data_.begin(), data_.begin() + offset, data_.end()); - } - - void Erase(const T& e) - { - MutexT::scoped_lock lock(mutex_); - - data_.erase(std::find(data_.begin(), data_.end(), e)); - } - - void Clear() - { - MutexT::scoped_lock lock(mutex_); - - data_.clear(); - isSorted_ = true; - } - - bool IntersectsWith(SourceIdSet& other) - { - MutexT::scoped_lock myLock(mutex_); - MutexT::scoped_lock otherLock(other.mutex_); - - sort(); - other.sort(); - - auto l1 = data_.begin(); - const auto r1 = data_.end(); - - auto l2 = other.data_.begin(); - const auto r2 = other.data_.end(); - - // Is intersection of turn sourceIds and node sourceIds non-empty? - while (l1 != r1 && l2 != r2) - { - if (*l1 < *l2) - l1++; - else if (*l2 < *l1) - l2++; - // Equals => Intersect - else - return true; - } - return false; - } - -private: - MutexT mutex_; - DataT data_; - bool isSorted_ = false; - - void sort() - { - if (isSorted_) - return; - - std::sort(data_.begin(), data_.end()); - isSorted_ = true; - } -}; - -/****************************************/ REACT_IMPL_END /***************************************/ - -#endif // REACT_COMMON_SOURCEIDSET_H_INCLUDED \ No newline at end of file diff --git a/include/react/common/Timing.h b/include/react/common/Timing.h index 3775661d..9440ceaa 100644 --- a/include/react/common/Timing.h +++ b/include/react/common/Timing.h @@ -52,29 +52,15 @@ inline const LARGE_INTEGER& GetPerformanceFrequency() /////////////////////////////////////////////////////////////////////////////////////////////////// template < - long long threshold, + std::chrono::microseconds::rep threshold, bool is_enabled > -class ConditionalTimer -{ -public: - class ScopedTimer - { - public: - // Note: - // Count is passed by ref so it can be set later if it's not known at time of creation - ScopedTimer(const ConditionalTimer&, const size_t& count); - }; - - void Reset(); - void ForceThresholdExceeded(bool isExceeded); - bool IsThresholdExceeded() const; -}; +class ConditionalTimer; // Disabled template < - long long threshold + std::chrono::microseconds::rep threshold > class ConditionalTimer { @@ -83,18 +69,18 @@ class ConditionalTimer class ScopedTimer { public: - ScopedTimer(const ConditionalTimer&, const size_t& count) {} + ScopedTimer(const ConditionalTimer&, const size_t&) {} }; void Reset() {} - void ForceThresholdExceeded(bool isExceeded) {} + void ForceThresholdExceeded(bool) {} bool IsThresholdExceeded() const { return false; } }; // Enabled template < - long long threshold + std::chrono::microseconds::rep threshold > class ConditionalTimer { @@ -103,6 +89,7 @@ class ConditionalTimer using TimestampT = LARGE_INTEGER; #else using ClockT = std::chrono::high_resolution_clock; + using RepT = ClockT::duration::rep; using TimestampT = std::chrono::time_point; #endif @@ -158,7 +145,7 @@ class ConditionalTimer ConditionalTimer& parent_; TimestampT startTime_; - const size_t& count_; + const std::chrono::microseconds::rep& count_; }; static TimestampT now() @@ -198,4 +185,4 @@ class ConditionalTimer /****************************************/ REACT_IMPL_END /***************************************/ -#endif // REACT_COMMON_TIMING_H_INCLUDED \ No newline at end of file +#endif // REACT_COMMON_TIMING_H_INCLUDED diff --git a/include/react/common/TopoQueue.h b/include/react/common/TopoQueue.h index 8084d419..bc05c0dd 100644 --- a/include/react/common/TopoQueue.h +++ b/include/react/common/TopoQueue.h @@ -12,8 +12,6 @@ #include "react/detail/Defs.h" #include -#include -#include #include #include @@ -51,30 +49,30 @@ class TopoQueue bool FetchNext() { - // Throw away previous values - nextData_.clear(); - // Find min level of nodes in queue data - minLevel_ = (std::numeric_limits::max)(); - for (const auto& e : queueData_) - if (minLevel_ > e.Level) - minLevel_ = e.Level; + auto min = std::min_element( + queueData_.begin(), + queueData_.end(), + [](const Entry& a, const Entry& b){ return a.Level < b.Level;}); // Swap entries with min level to the end auto p = std::partition( queueData_.begin(), queueData_.end(), - LevelCompFunctor{ minLevel_ }); + [&min](const Entry& e) { return e.Level != min->Level;}); + + // Throw away any previous values + nextData_.clear(); // Reserve once to avoid multiple re-allocations nextData_.reserve(std::distance(p, queueData_.end())); // Move min level values to next data for (auto it = p; it != queueData_.end(); ++it) - nextData_.push_back(std::move(it->Value)); + nextData_.emplace_back(std::move(it->Value)); // Truncate moved entries - queueData_.resize(std::distance(queueData_.begin(), p)); + queueData_.erase(p, queueData_.end()); return !nextData_.empty(); } @@ -93,21 +91,10 @@ class TopoQueue int Level; }; - struct LevelCompFunctor - { - LevelCompFunctor(int level) : Level( level ) {} - - bool operator()(const Entry& e) const { return e.Level != Level; } - - const int Level; - }; - NextDataT nextData_; QueueDataT queueData_; TLevelFunc levelFunc_; - - int minLevel_ = (std::numeric_limits::max)(); }; /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -226,10 +213,10 @@ class ConcurrentTopoQueue uint totalWeight = 0; // Determine current min level - minLevel_ = (std::numeric_limits::max)(); - for (const auto& buf : collectBuffer_) - if (minLevel_ > buf.MinLevel) - minLevel_ = buf.MinLevel; + auto min = std::min_element( + collectBuffer_.begin(), + collectBuffer_.end(), + [](const ThreadLocalBuffer& a, const ThreadLocalBuffer& b){ return a.MinLevel < b.MinLevel;}); // For each thread local buffer... for (auto& buf : collectBuffer_) @@ -240,17 +227,17 @@ class ConcurrentTopoQueue auto p = std::partition( v.begin(), v.end(), - LevelCompFunctor{ minLevel_ }); + [&min](const Entry& e) { return e.Level != min->MinLevel;}); // Reserve once to avoid multiple re-allocations - nextData_.reserve(std::distance(p, v.end())); + nextData_.reserve(nextData_.size() + std::distance(p, v.end())); // Move min level values to global next data for (auto it = p; it != v.end(); ++it) nextData_.emplace_back(std::move(it->Value), it->Weight); // Truncate remaining - v.resize(std::distance(v.begin(), p)); + v.erase(p, v.end()); // Calc new min level and weight for this buffer buf.MinLevel = (std::numeric_limits::max)(); @@ -296,15 +283,6 @@ class ConcurrentTopoQueue uint Weight; }; - struct LevelCompFunctor - { - LevelCompFunctor(int level) : Level{ level } {} - - bool operator()(const Entry& e) const { return e.Level != Level; } - - const int Level; - }; - struct ThreadLocalBuffer { QueueDataT Data; @@ -312,8 +290,6 @@ class ConcurrentTopoQueue uint Weight = 0; }; - int minLevel_ = (std::numeric_limits::max)(); - NextDataT nextData_; NextRangeT nextRange_; @@ -325,4 +301,4 @@ class ConcurrentTopoQueue /****************************************/ REACT_IMPL_END /***************************************/ -#endif // REACT_COMMON_TOPOQUEUE_H_INCLUDED \ No newline at end of file +#endif // REACT_COMMON_TOPOQUEUE_H_INCLUDED diff --git a/include/react/common/Types.h b/include/react/common/Types.h index 5d747eee..728d683a 100644 --- a/include/react/common/Types.h +++ b/include/react/common/Types.h @@ -11,7 +11,6 @@ #include "react/detail/Defs.h" -#include #include /***************************************/ REACT_IMPL_BEGIN /**************************************/ @@ -24,8 +23,6 @@ ObjectId GetObjectId(const O& obj) return (ObjectId)&obj; } -using UpdateDurationT = std::chrono::duration; - /****************************************/ REACT_IMPL_END /***************************************/ -#endif // REACT_COMMON_TYPES_H_INCLUDED \ No newline at end of file +#endif // REACT_COMMON_TYPES_H_INCLUDED diff --git a/include/react/common/Util.h b/include/react/common/Util.h index 39741ed7..b50b852f 100644 --- a/include/react/common/Util.h +++ b/include/react/common/Util.h @@ -22,62 +22,18 @@ /// http://stackoverflow.com/questions/687490/how-do-i-expand-a-tuple-into-variadic-template-functions-arguments /////////////////////////////////////////////////////////////////////////////////////////////////// -template -struct Apply { - template - static inline auto apply(F && f, T && t, A &&... a) - -> decltype(Apply::apply(std::forward(f), std::forward(t), std::get(std::forward(t)), std::forward(a)...)) - { - return Apply::apply(std::forward(f), std::forward(t), std::get(std::forward(t)), std::forward(a)...); - } -}; - -template<> -struct Apply<0> -{ - template - static inline auto apply(F && f, T &&, A &&... a) - -> decltype(std::forward(f)(std::forward(a)...)) - { - return std::forward(f)(std::forward(a)...); - } -}; - -template -inline auto apply(F && f, T && t) - -> decltype(Apply::type>::value>::apply(std::forward(f), std::forward(t))) -{ - return Apply::type>::value> - ::apply(std::forward(f), std::forward(t)); +template +auto apply_impl(F&& f, Tuple&& t, std::index_sequence) { + return std::forward(f)(std::get(std::forward(t))...); } -template -struct ApplyMemberFn { - template - static inline auto apply(O obj, F f, T && t, A &&... a) - -> decltype(ApplyMemberFn::apply(obj, f, std::forward(t), std::get(std::forward(t)), std::forward(a)...)) - { - return ApplyMemberFn::apply(obj, f, std::forward(t), std::get(std::forward(t)), std::forward(a)...); - } -}; +template +using indices_t = std::make_index_sequence>::value>; -template<> -struct ApplyMemberFn<0> -{ - template - static inline auto apply(O obj, F f, T &&, A &&... a) - -> decltype((obj->*f)(std::forward(a)...)) - { - return (obj->*f)(std::forward(a)...); - } -}; -template -inline auto applyMemberFn(O obj, F f, T&& t) - -> decltype(ApplyMemberFn::type>::value>::apply(obj, f, std::forward(t))) -{ - return ApplyMemberFn::type>::value> - ::apply(obj, f, std::forward(t)); +template +auto apply(F&& f, Tuple&& t) { + return apply_impl(std::forward(f), std::forward(t), indices_t()); } /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -228,4 +184,4 @@ class IsCallableWith // Use comma operator to replace potential void return value with 0 #define REACT_EXPAND_PACK(...) REACT_IMPL::pass((__VA_ARGS__ , 0) ...) -#endif // REACT_COMMON_UTIL_H_INCLUDED \ No newline at end of file +#endif // REACT_COMMON_UTIL_H_INCLUDED diff --git a/include/react/detail/DomainBase.h b/include/react/detail/DomainBase.h index 67c7e8ae..a21f6dc1 100644 --- a/include/react/detail/DomainBase.h +++ b/include/react/detail/DomainBase.h @@ -28,6 +28,7 @@ /////////////////////////////////////////////////////////////////////////////////////////////////// /// Forward declarations /////////////////////////////////////////////////////////////////////////////////////////////////// + template class Signal; @@ -262,4 +263,4 @@ class DomainInitializer /****************************************/ REACT_IMPL_END /***************************************/ -#endif // REACT_DETAIL_DOMAINBASE_H_INCLUDED \ No newline at end of file +#endif // REACT_DETAIL_DOMAINBASE_H_INCLUDED diff --git a/include/react/detail/graph/ContinuationNodes.h b/include/react/detail/graph/ContinuationNodes.h index c841d23f..f5a55331 100644 --- a/include/react/detail/graph/ContinuationNodes.h +++ b/include/react/detail/graph/ContinuationNodes.h @@ -348,4 +348,4 @@ class SyncedContinuationNode : public ContinuationNode /****************************************/ REACT_IMPL_END /***************************************/ -#endif // REACT_DETAIL_GRAPH_CONTINUATIONNODES_H_INCLUDED \ No newline at end of file +#endif // REACT_DETAIL_GRAPH_CONTINUATIONNODES_H_INCLUDED diff --git a/include/react/detail/graph/GraphBase.h b/include/react/detail/graph/GraphBase.h index b7d79d27..bd0e8a81 100644 --- a/include/react/detail/graph/GraphBase.h +++ b/include/react/detail/graph/GraphBase.h @@ -38,7 +38,7 @@ enum class WeightHint template < typename D, - long long threshold + unsigned long long threshold > class UpdateTimingPolicy : private ConditionalTimer @@ -199,7 +199,7 @@ template class ReactiveOpBase { public: - using DepHolderT = std::tuple; + using DepHolderT = std::tuple...>; template ReactiveOpBase(DontMove, TDepsIn&& ... deps) : @@ -264,8 +264,11 @@ class EventRange const_iterator begin() const { return data_.begin(); } const_iterator end() const { return data_.end(); } + size_type size() const { return data_.size(); } + bool empty() const { return data_.empty(); } + size_type Size() const { return data_.size(); } - bool IsEmpty() const { return data_.empty(); } + bool Empty() const { return data_.empty(); } explicit EventRange(const std::vector& data) : data_( data ) @@ -280,4 +283,4 @@ using EventEmitter = std::back_insert_iterator>; /****************************************/ REACT_IMPL_END /***************************************/ -#endif // REACT_DETAIL_GRAPH_GRAPHBASE_H_INCLUDED \ No newline at end of file +#endif // REACT_DETAIL_GRAPH_GRAPHBASE_H_INCLUDED diff --git a/include/react/detail/graph/ObserverNodes.h b/include/react/detail/graph/ObserverNodes.h index 351a54e5..616c3721 100644 --- a/include/react/detail/graph/ObserverNodes.h +++ b/include/react/detail/graph/ObserverNodes.h @@ -240,7 +240,7 @@ class EventObserverNode : TFunc func_; - virtual void detachObserver() + virtual void detachObserver() override { if (auto p = subject_.lock()) { @@ -340,7 +340,7 @@ class SyncedObserverNode : TFunc func_; DepHolderT deps_; - virtual void detachObserver() + virtual void detachObserver() override { if (auto p = subject_.lock()) { @@ -358,4 +358,4 @@ class SyncedObserverNode : /****************************************/ REACT_IMPL_END /***************************************/ -#endif // REACT_DETAIL_GRAPH_OBSERVERNODES_H_INCLUDED \ No newline at end of file +#endif // REACT_DETAIL_GRAPH_OBSERVERNODES_H_INCLUDED diff --git a/include/react/detail/graph/ReactorNodes.h b/include/react/detail/graph/ReactorNodes.h index b693a5f0..ddb2c5f4 100644 --- a/include/react/detail/graph/ReactorNodes.h +++ b/include/react/detail/graph/ReactorNodes.h @@ -245,7 +245,7 @@ class ReactorNode : std::function func_; PullT mainLoop_; - TurnT* turnPtr_; + TurnT* turnPtr_ = nullptr; PushT* curOutPtr_ = nullptr; @@ -256,4 +256,4 @@ class ReactorNode : /****************************************/ REACT_IMPL_END /***************************************/ -#endif // REACT_DETAIL_GRAPH_REACTORNODES_H_INCLUDED \ No newline at end of file +#endif // REACT_DETAIL_GRAPH_REACTORNODES_H_INCLUDED diff --git a/include/react/detail/graph/SignalNodes.h b/include/react/detail/graph/SignalNodes.h index eb438a0c..5accd3c7 100644 --- a/include/react/detail/graph/SignalNodes.h +++ b/include/react/detail/graph/SignalNodes.h @@ -13,6 +13,7 @@ #include #include +#include #include "GraphBase.h" @@ -35,12 +36,10 @@ template class SignalNode : public ObservableNode { public: - SignalNode() = default; template explicit SignalNode(T&& value) : - SignalNode::ObservableNode( ), - value_( std::forward(value) ) + value_{std::forward(value)} {} const S& ValueRef() const @@ -72,8 +71,7 @@ class VarNode : public: template VarNode(T&& value) : - VarNode::SignalNode( std::forward(value) ), - newValue_( value ) + VarNode::SignalNode( std::forward(value) ) { Engine::OnNodeCreate(*this); } @@ -95,7 +93,7 @@ class VarNode : template void AddInput(V&& newValue) { - newValue_ = std::forward(newValue); + pushNewValue(std::forward(newValue)); isInputAdded_ = true; @@ -120,7 +118,7 @@ class VarNode : // in ApplyInput else { - func(newValue_); + func(getNewValue()); } } @@ -133,9 +131,9 @@ class VarNode : { isInputAdded_ = false; - if (! Equals(this->value_, newValue_)) + if (! Equals(this->value_, getNewValue())) { - this->value_ = std::move(newValue_); + popNewValue(); Engine::OnInputChange(*this, turn); return true; } @@ -159,7 +157,26 @@ class VarNode : } private: - S newValue_; + + S & getNewValue() + { + return *reinterpret_cast(newValueData); + } + + template + void pushNewValue(V && v) + { + new (newValueData) S{std::forward(v)}; + } + + void popNewValue() + { + this->value_ = std::move(*reinterpret_cast(newValueData)); + } + + // so that we don't require S to be default constructible + std::aligned_storage_t newValueData[1]; + bool isInputAdded_ = false; bool isInputModified_ = false; }; @@ -182,11 +199,6 @@ class FunctionOp : public ReactiveOpBase func_( std::forward(func) ) {} - FunctionOp(FunctionOp&& other) : - FunctionOp::ReactiveOpBase( std::move(other) ), - func_( std::move(other.func_) ) - {} - S Evaluate() { return apply(EvalFunctor( func_ ), this->deps_); @@ -238,13 +250,10 @@ class SignalOpNode : using Engine = typename SignalOpNode::Engine; public: - template - SignalOpNode(TArgs&& ... args) : - SignalOpNode::SignalNode( ), - op_( std::forward(args) ... ) + explicit SignalOpNode(TOp op) : + SignalOpNode::SignalNode{op.Evaluate()}, + op_{std::move(op)} { - this->value_ = op_.Evaluate(); - Engine::OnNodeCreate(*this); op_.template Attach(*this); } @@ -383,4 +392,4 @@ class FlattenNode : public SignalNode /****************************************/ REACT_IMPL_END /***************************************/ -#endif // REACT_DETAIL_GRAPH_SIGNALNODES_H_INCLUDED \ No newline at end of file +#endif // REACT_DETAIL_GRAPH_SIGNALNODES_H_INCLUDED diff --git a/project/msvc/CppReact.sln b/project/msvc/CppReact.sln deleted file mode 100644 index b414852d..00000000 --- a/project/msvc/CppReact.sln +++ /dev/null @@ -1,149 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.30501.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CppReact", "CppReact.vcxproj", "{5E56AAB9-4E33-4B9E-A315-E85CEDB75CF1}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CppReactBenchmark", "CppReactBenchmark.vcxproj", "{F9115FB9-61DD-4B3C-BCE8-7D26372B05F7}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CppReactTest", "CppReactTest.vcxproj", "{52A9EC67-C6A7-453B-AD65-F027CA07AF44}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3_Examples", "3_Examples", "{518ACABC-E4A7-4E2D-9A04-FFA669A30DBF}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "1_Core", "1_Core", "{91AFD614-F7E6-48CE-9808-642EAF476B66}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "4_Benchmarks", "4_Benchmarks", "{D6F88FF5-E55C-4E65-ABBB-B4298AB84D40}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2_Tests", "2_Tests", "{3F97AA87-0A03-4428-94C1-C9B4007C2C80}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CppReactExample", "CppReactExample.vcxproj", "{CC0CD982-AE7D-4797-A122-58E6BBE70DDB}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Example_BasicAlgorithms", "Example_BasicAlgorithms.vcxproj", "{617019A2-97BE-4A60-8EC4-3547D8C54533}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Example_BasicComposition", "Example_BasicComposition.vcxproj", "{D7B70D3B-F14D-4A85-B164-EAB88C358E85}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Example_BasicEvents", "Example_BasicEvents.vcxproj", "{BD777649-97F1-4810-BF21-CB27F7672BF4}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Example_BasicObservers", "Example_BasicObservers.vcxproj", "{CC66BFA0-D609-46E0-9FD1-F9CC902410B1}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Example_BasicReactors", "Example_BasicReactors.vcxproj", "{D976F4D4-B472-4709-BFB5-B1BEEA1F7E96}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Example_BasicSignals", "Example_BasicSignals.vcxproj", "{230C9137-CCD0-47E2-8F1F-2E1DD19984A1}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Example_BasicSynchronization", "Example_BasicSynchronization.vcxproj", "{269329F8-A9E1-41AC-9C37-3A82A082A62C}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {5E56AAB9-4E33-4B9E-A315-E85CEDB75CF1}.Debug|Win32.ActiveCfg = Debug|Win32 - {5E56AAB9-4E33-4B9E-A315-E85CEDB75CF1}.Debug|Win32.Build.0 = Debug|Win32 - {5E56AAB9-4E33-4B9E-A315-E85CEDB75CF1}.Debug|x64.ActiveCfg = Debug|x64 - {5E56AAB9-4E33-4B9E-A315-E85CEDB75CF1}.Debug|x64.Build.0 = Debug|x64 - {5E56AAB9-4E33-4B9E-A315-E85CEDB75CF1}.Release|Win32.ActiveCfg = Release|Win32 - {5E56AAB9-4E33-4B9E-A315-E85CEDB75CF1}.Release|Win32.Build.0 = Release|Win32 - {5E56AAB9-4E33-4B9E-A315-E85CEDB75CF1}.Release|x64.ActiveCfg = Release|x64 - {5E56AAB9-4E33-4B9E-A315-E85CEDB75CF1}.Release|x64.Build.0 = Release|x64 - {F9115FB9-61DD-4B3C-BCE8-7D26372B05F7}.Debug|Win32.ActiveCfg = Debug|Win32 - {F9115FB9-61DD-4B3C-BCE8-7D26372B05F7}.Debug|Win32.Build.0 = Debug|Win32 - {F9115FB9-61DD-4B3C-BCE8-7D26372B05F7}.Debug|x64.ActiveCfg = Debug|x64 - {F9115FB9-61DD-4B3C-BCE8-7D26372B05F7}.Debug|x64.Build.0 = Debug|x64 - {F9115FB9-61DD-4B3C-BCE8-7D26372B05F7}.Release|Win32.ActiveCfg = Release|Win32 - {F9115FB9-61DD-4B3C-BCE8-7D26372B05F7}.Release|Win32.Build.0 = Release|Win32 - {F9115FB9-61DD-4B3C-BCE8-7D26372B05F7}.Release|x64.ActiveCfg = Release|x64 - {F9115FB9-61DD-4B3C-BCE8-7D26372B05F7}.Release|x64.Build.0 = Release|x64 - {52A9EC67-C6A7-453B-AD65-F027CA07AF44}.Debug|Win32.ActiveCfg = Debug|Win32 - {52A9EC67-C6A7-453B-AD65-F027CA07AF44}.Debug|Win32.Build.0 = Debug|Win32 - {52A9EC67-C6A7-453B-AD65-F027CA07AF44}.Debug|x64.ActiveCfg = Debug|x64 - {52A9EC67-C6A7-453B-AD65-F027CA07AF44}.Debug|x64.Build.0 = Debug|x64 - {52A9EC67-C6A7-453B-AD65-F027CA07AF44}.Release|Win32.ActiveCfg = Release|Win32 - {52A9EC67-C6A7-453B-AD65-F027CA07AF44}.Release|Win32.Build.0 = Release|Win32 - {52A9EC67-C6A7-453B-AD65-F027CA07AF44}.Release|x64.ActiveCfg = Release|x64 - {52A9EC67-C6A7-453B-AD65-F027CA07AF44}.Release|x64.Build.0 = Release|x64 - {CC0CD982-AE7D-4797-A122-58E6BBE70DDB}.Debug|Win32.ActiveCfg = Debug|Win32 - {CC0CD982-AE7D-4797-A122-58E6BBE70DDB}.Debug|Win32.Build.0 = Debug|Win32 - {CC0CD982-AE7D-4797-A122-58E6BBE70DDB}.Debug|x64.ActiveCfg = Debug|x64 - {CC0CD982-AE7D-4797-A122-58E6BBE70DDB}.Debug|x64.Build.0 = Debug|x64 - {CC0CD982-AE7D-4797-A122-58E6BBE70DDB}.Release|Win32.ActiveCfg = Release|Win32 - {CC0CD982-AE7D-4797-A122-58E6BBE70DDB}.Release|Win32.Build.0 = Release|Win32 - {CC0CD982-AE7D-4797-A122-58E6BBE70DDB}.Release|x64.ActiveCfg = Release|x64 - {CC0CD982-AE7D-4797-A122-58E6BBE70DDB}.Release|x64.Build.0 = Release|x64 - {617019A2-97BE-4A60-8EC4-3547D8C54533}.Debug|Win32.ActiveCfg = Debug|Win32 - {617019A2-97BE-4A60-8EC4-3547D8C54533}.Debug|Win32.Build.0 = Debug|Win32 - {617019A2-97BE-4A60-8EC4-3547D8C54533}.Debug|x64.ActiveCfg = Debug|x64 - {617019A2-97BE-4A60-8EC4-3547D8C54533}.Debug|x64.Build.0 = Debug|x64 - {617019A2-97BE-4A60-8EC4-3547D8C54533}.Release|Win32.ActiveCfg = Release|Win32 - {617019A2-97BE-4A60-8EC4-3547D8C54533}.Release|Win32.Build.0 = Release|Win32 - {617019A2-97BE-4A60-8EC4-3547D8C54533}.Release|x64.ActiveCfg = Release|x64 - {617019A2-97BE-4A60-8EC4-3547D8C54533}.Release|x64.Build.0 = Release|x64 - {D7B70D3B-F14D-4A85-B164-EAB88C358E85}.Debug|Win32.ActiveCfg = Debug|Win32 - {D7B70D3B-F14D-4A85-B164-EAB88C358E85}.Debug|Win32.Build.0 = Debug|Win32 - {D7B70D3B-F14D-4A85-B164-EAB88C358E85}.Debug|x64.ActiveCfg = Debug|x64 - {D7B70D3B-F14D-4A85-B164-EAB88C358E85}.Debug|x64.Build.0 = Debug|x64 - {D7B70D3B-F14D-4A85-B164-EAB88C358E85}.Release|Win32.ActiveCfg = Release|Win32 - {D7B70D3B-F14D-4A85-B164-EAB88C358E85}.Release|Win32.Build.0 = Release|Win32 - {D7B70D3B-F14D-4A85-B164-EAB88C358E85}.Release|x64.ActiveCfg = Release|x64 - {D7B70D3B-F14D-4A85-B164-EAB88C358E85}.Release|x64.Build.0 = Release|x64 - {BD777649-97F1-4810-BF21-CB27F7672BF4}.Debug|Win32.ActiveCfg = Debug|Win32 - {BD777649-97F1-4810-BF21-CB27F7672BF4}.Debug|Win32.Build.0 = Debug|Win32 - {BD777649-97F1-4810-BF21-CB27F7672BF4}.Debug|x64.ActiveCfg = Debug|x64 - {BD777649-97F1-4810-BF21-CB27F7672BF4}.Debug|x64.Build.0 = Debug|x64 - {BD777649-97F1-4810-BF21-CB27F7672BF4}.Release|Win32.ActiveCfg = Release|Win32 - {BD777649-97F1-4810-BF21-CB27F7672BF4}.Release|Win32.Build.0 = Release|Win32 - {BD777649-97F1-4810-BF21-CB27F7672BF4}.Release|x64.ActiveCfg = Release|x64 - {BD777649-97F1-4810-BF21-CB27F7672BF4}.Release|x64.Build.0 = Release|x64 - {CC66BFA0-D609-46E0-9FD1-F9CC902410B1}.Debug|Win32.ActiveCfg = Debug|Win32 - {CC66BFA0-D609-46E0-9FD1-F9CC902410B1}.Debug|Win32.Build.0 = Debug|Win32 - {CC66BFA0-D609-46E0-9FD1-F9CC902410B1}.Debug|x64.ActiveCfg = Debug|x64 - {CC66BFA0-D609-46E0-9FD1-F9CC902410B1}.Debug|x64.Build.0 = Debug|x64 - {CC66BFA0-D609-46E0-9FD1-F9CC902410B1}.Release|Win32.ActiveCfg = Release|Win32 - {CC66BFA0-D609-46E0-9FD1-F9CC902410B1}.Release|Win32.Build.0 = Release|Win32 - {CC66BFA0-D609-46E0-9FD1-F9CC902410B1}.Release|x64.ActiveCfg = Release|x64 - {CC66BFA0-D609-46E0-9FD1-F9CC902410B1}.Release|x64.Build.0 = Release|x64 - {D976F4D4-B472-4709-BFB5-B1BEEA1F7E96}.Debug|Win32.ActiveCfg = Debug|Win32 - {D976F4D4-B472-4709-BFB5-B1BEEA1F7E96}.Debug|Win32.Build.0 = Debug|Win32 - {D976F4D4-B472-4709-BFB5-B1BEEA1F7E96}.Debug|x64.ActiveCfg = Debug|x64 - {D976F4D4-B472-4709-BFB5-B1BEEA1F7E96}.Debug|x64.Build.0 = Debug|x64 - {D976F4D4-B472-4709-BFB5-B1BEEA1F7E96}.Release|Win32.ActiveCfg = Release|Win32 - {D976F4D4-B472-4709-BFB5-B1BEEA1F7E96}.Release|Win32.Build.0 = Release|Win32 - {D976F4D4-B472-4709-BFB5-B1BEEA1F7E96}.Release|x64.ActiveCfg = Release|x64 - {D976F4D4-B472-4709-BFB5-B1BEEA1F7E96}.Release|x64.Build.0 = Release|x64 - {230C9137-CCD0-47E2-8F1F-2E1DD19984A1}.Debug|Win32.ActiveCfg = Debug|Win32 - {230C9137-CCD0-47E2-8F1F-2E1DD19984A1}.Debug|Win32.Build.0 = Debug|Win32 - {230C9137-CCD0-47E2-8F1F-2E1DD19984A1}.Debug|x64.ActiveCfg = Debug|x64 - {230C9137-CCD0-47E2-8F1F-2E1DD19984A1}.Debug|x64.Build.0 = Debug|x64 - {230C9137-CCD0-47E2-8F1F-2E1DD19984A1}.Release|Win32.ActiveCfg = Release|Win32 - {230C9137-CCD0-47E2-8F1F-2E1DD19984A1}.Release|Win32.Build.0 = Release|Win32 - {230C9137-CCD0-47E2-8F1F-2E1DD19984A1}.Release|x64.ActiveCfg = Release|x64 - {230C9137-CCD0-47E2-8F1F-2E1DD19984A1}.Release|x64.Build.0 = Release|x64 - {269329F8-A9E1-41AC-9C37-3A82A082A62C}.Debug|Win32.ActiveCfg = Debug|Win32 - {269329F8-A9E1-41AC-9C37-3A82A082A62C}.Debug|Win32.Build.0 = Debug|Win32 - {269329F8-A9E1-41AC-9C37-3A82A082A62C}.Debug|x64.ActiveCfg = Debug|x64 - {269329F8-A9E1-41AC-9C37-3A82A082A62C}.Debug|x64.Build.0 = Debug|x64 - {269329F8-A9E1-41AC-9C37-3A82A082A62C}.Release|Win32.ActiveCfg = Release|Win32 - {269329F8-A9E1-41AC-9C37-3A82A082A62C}.Release|Win32.Build.0 = Release|Win32 - {269329F8-A9E1-41AC-9C37-3A82A082A62C}.Release|x64.ActiveCfg = Release|x64 - {269329F8-A9E1-41AC-9C37-3A82A082A62C}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {5E56AAB9-4E33-4B9E-A315-E85CEDB75CF1} = {91AFD614-F7E6-48CE-9808-642EAF476B66} - {F9115FB9-61DD-4B3C-BCE8-7D26372B05F7} = {D6F88FF5-E55C-4E65-ABBB-B4298AB84D40} - {52A9EC67-C6A7-453B-AD65-F027CA07AF44} = {3F97AA87-0A03-4428-94C1-C9B4007C2C80} - {CC0CD982-AE7D-4797-A122-58E6BBE70DDB} = {518ACABC-E4A7-4E2D-9A04-FFA669A30DBF} - {617019A2-97BE-4A60-8EC4-3547D8C54533} = {518ACABC-E4A7-4E2D-9A04-FFA669A30DBF} - {D7B70D3B-F14D-4A85-B164-EAB88C358E85} = {518ACABC-E4A7-4E2D-9A04-FFA669A30DBF} - {BD777649-97F1-4810-BF21-CB27F7672BF4} = {518ACABC-E4A7-4E2D-9A04-FFA669A30DBF} - {CC66BFA0-D609-46E0-9FD1-F9CC902410B1} = {518ACABC-E4A7-4E2D-9A04-FFA669A30DBF} - {D976F4D4-B472-4709-BFB5-B1BEEA1F7E96} = {518ACABC-E4A7-4E2D-9A04-FFA669A30DBF} - {230C9137-CCD0-47E2-8F1F-2E1DD19984A1} = {518ACABC-E4A7-4E2D-9A04-FFA669A30DBF} - {269329F8-A9E1-41AC-9C37-3A82A082A62C} = {518ACABC-E4A7-4E2D-9A04-FFA669A30DBF} - EndGlobalSection -EndGlobal diff --git a/project/msvc/CppReact.vcxproj b/project/msvc/CppReact.vcxproj deleted file mode 100644 index 16ae1f97..00000000 --- a/project/msvc/CppReact.vcxproj +++ /dev/null @@ -1,206 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {5E56AAB9-4E33-4B9E-A315-E85CEDB75CF1} - CppReact - - - - StaticLibrary - true - v120 - MultiByte - - - StaticLibrary - true - v120 - MultiByte - - - StaticLibrary - false - v120 - true - MultiByte - - - StaticLibrary - false - v120 - true - MultiByte - - - - - - - - - - - - - - - - - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - - Level3 - Disabled - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - true - %(PreprocessorDefinitions) - - - true - - - $(OutDir)$(TargetName)$(TargetExt) - - - - - Level3 - Disabled - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - true - %(PreprocessorDefinitions) - - - true - - - $(OutDir)$(TargetName)$(TargetExt) - - - - - Level3 - MaxSpeed - true - true - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - true - %(PreprocessorDefinitions) - - - true - true - true - - - $(OutDir)$(TargetName)$(TargetExt) - - - - - Level3 - MaxSpeed - true - true - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - true - %(PreprocessorDefinitions) - - - true - true - true - - - $(OutDir)$(TargetName)$(TargetExt) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/project/msvc/CppReact.vcxproj.filters b/project/msvc/CppReact.vcxproj.filters deleted file mode 100644 index 7de3201b..00000000 --- a/project/msvc/CppReact.vcxproj.filters +++ /dev/null @@ -1,171 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {82fd9b9e-0b63-40f7-b245-b5eb0271b0d2} - - - {c7adc39d-d19e-4fe2-b945-332515717bc8} - - - {6883dd62-b27e-4b11-9cc8-cbac096f4723} - - - {11a75126-8bfd-4693-be4b-4e06ab73450c} - - - {f58215db-3a12-432a-a4c1-e24a90df70a9} - - - {3f444875-ab1a-4bbd-99eb-7018c930098a} - - - {22da08e3-fb85-4fed-9fbc-8944ef866ccc} - - - - - Header Files\common - - - Header Files\common - - - Header Files\common - - - Header Files\common - - - Header Files\common - - - Header Files - - - Header Files\common - - - Header Files - - - Header Files\engine - - - Header Files\detail - - - Header Files\detail - - - Header Files\detail - - - Header Files\detail - - - Header Files\detail - - - Header Files\detail\graph - - - Header Files\detail\graph - - - Header Files\detail\graph - - - Header Files\logging - - - Header Files\logging - - - Header Files\logging - - - Header Files - - - Header Files\detail - - - Header Files\detail - - - Header Files\detail\graph - - - Header Files\detail\graph - - - Header Files\detail - - - Header Files - - - Header Files\detail - - - Header Files - - - Header Files\detail\graph - - - Header Files\engine - - - Header Files - - - Header Files - - - Header Files\common - - - Header Files\engine - - - Header Files\detail\graph - - - Header Files\common - - - Header Files\detail - - - - - Source Files\logging - - - Source Files\logging - - - Source Files\engine - - - Source Files\engine - - - Source Files\engine - - - \ No newline at end of file diff --git a/project/msvc/CppReactBenchmark.vcxproj b/project/msvc/CppReactBenchmark.vcxproj deleted file mode 100644 index 7613239a..00000000 --- a/project/msvc/CppReactBenchmark.vcxproj +++ /dev/null @@ -1,166 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {F9115FB9-61DD-4B3C-BCE8-7D26372B05F7} - CppReactBenchmark - - - - Application - true - v120 - MultiByte - - - Application - true - v120 - MultiByte - - - Application - false - v120 - true - MultiByte - - - Application - false - v120 - true - MultiByte - - - - - - - - - - - - - - - - - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - - - Level3 - Disabled - true - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;_VARIADIC_MAX=10;%(PreprocessorDefinitions) - - - true - Console - - - - - Level3 - Disabled - true - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;_VARIADIC_MAX=10;%(PreprocessorDefinitions) - - - true - Console - - - - - Level3 - MaxSpeed - true - true - true - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;_VARIADIC_MAX=10;%(PreprocessorDefinitions) - - - true - true - true - Console - false - - - - - Level3 - MaxSpeed - true - true - true - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;_VARIADIC_MAX=10;%(PreprocessorDefinitions) - - - true - true - true - Console - false - - - - - {5e56aab9-4e33-4b9e-a315-e85cedb75cf1} - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/project/msvc/CppReactBenchmark.vcxproj.filters b/project/msvc/CppReactBenchmark.vcxproj.filters deleted file mode 100644 index cc27f988..00000000 --- a/project/msvc/CppReactBenchmark.vcxproj.filters +++ /dev/null @@ -1,42 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - \ No newline at end of file diff --git a/project/msvc/CppReactExample.vcxproj b/project/msvc/CppReactExample.vcxproj deleted file mode 100644 index 323c777f..00000000 --- a/project/msvc/CppReactExample.vcxproj +++ /dev/null @@ -1,162 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {CC0CD982-AE7D-4797-A122-58E6BBE70DDB} - CppReactSandbox - CppReactExample - - - - Application - true - v120 - MultiByte - - - Application - true - v120 - MultiByte - - - Application - false - v120 - true - MultiByte - - - Application - false - v120 - true - MultiByte - - - - - - - - - - - - - - - - - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - - Level3 - Disabled - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - true - _VARIADIC_MAX=10;%(PreprocessorDefinitions) - - - true - Console - - - - - Level3 - Disabled - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - true - _VARIADIC_MAX=10;%(PreprocessorDefinitions) - - - true - Console - - - - - Level3 - MaxSpeed - true - true - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - true - _VARIADIC_MAX=10;%(PreprocessorDefinitions) - - - true - true - true - Console - false - - - - - Level3 - MaxSpeed - true - true - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - true - _VARIADIC_MAX=10;%(PreprocessorDefinitions) - - - true - true - true - Console - false - - - - - {5e56aab9-4e33-4b9e-a315-e85cedb75cf1} - - - - - - - - - \ No newline at end of file diff --git a/project/msvc/CppReactExample.vcxproj.filters b/project/msvc/CppReactExample.vcxproj.filters deleted file mode 100644 index 4c1c8f03..00000000 --- a/project/msvc/CppReactExample.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - \ No newline at end of file diff --git a/project/msvc/CppReactTest.vcxproj b/project/msvc/CppReactTest.vcxproj deleted file mode 100644 index 7b1cb65f..00000000 --- a/project/msvc/CppReactTest.vcxproj +++ /dev/null @@ -1,195 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {52A9EC67-C6A7-453B-AD65-F027CA07AF44} - CppReactTest - - - - Application - true - v120 - MultiByte - - - Application - true - v120 - MultiByte - - - Application - false - v120 - true - MultiByte - - - Application - false - v120 - true - MultiByte - - - - - - - - - - - - - - - - - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - - Level3 - Disabled - true - $(SolutionDir)..\..\include;$(GTestDir)\include;%(AdditionalIncludeDirectories) - _VARIADIC_MAX=10;%(PreprocessorDefinitions) - true - 4503;%(DisableSpecificWarnings) - - - true - $(GTestDir)\msvc\gtest-md\Debug;%(AdditionalLibraryDirectories) - gtestd.lib;gtest_main-mdd.lib;%(AdditionalDependencies) - Console - - - - - Level3 - Disabled - true - $(SolutionDir)..\..\include;$(GTestDir)\include;%(AdditionalIncludeDirectories) - _VARIADIC_MAX=10;%(PreprocessorDefinitions) - true - 4503;%(DisableSpecificWarnings) - /bigobj %(AdditionalOptions) - - - true - $(GTestDir)\msvc\gtest-md\Debug;%(AdditionalLibraryDirectories) - gtestd.lib;gtest_main-mdd.lib;%(AdditionalDependencies) - Console - - - - - Level3 - MaxSpeed - true - true - true - $(SolutionDir)..\..\include;$(GTestDir)\include;%(AdditionalIncludeDirectories) - _VARIADIC_MAX=10;%(PreprocessorDefinitions) - true - 4503;%(DisableSpecificWarnings) - - - true - true - true - $(GTestDir)\msvc\gtest-md\Release;%(AdditionalLibraryDirectories) - gtest.lib;gtest_main-md.lib;%(AdditionalDependencies) - Console - false - - - - - Level3 - MaxSpeed - true - true - true - $(SolutionDir)..\..\include;$(GTestDir)\include;%(AdditionalIncludeDirectories) - _VARIADIC_MAX=10;%(PreprocessorDefinitions) - true - 4503;%(DisableSpecificWarnings) - /bigobj %(AdditionalOptions) - - - true - true - true - $(GTestDir)\msvc\gtest-md\Release;%(AdditionalLibraryDirectories) - gtest.lib;gtest_main-md.lib;%(AdditionalDependencies) - Console - false - - - - - {5e56aab9-4e33-4b9e-a315-e85cedb75cf1} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/project/msvc/CppReactTest.vcxproj.filters b/project/msvc/CppReactTest.vcxproj.filters deleted file mode 100644 index ae74e006..00000000 --- a/project/msvc/CppReactTest.vcxproj.filters +++ /dev/null @@ -1,78 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/project/msvc/Example_BasicAlgorithms.vcxproj b/project/msvc/Example_BasicAlgorithms.vcxproj deleted file mode 100644 index eeffca5a..00000000 --- a/project/msvc/Example_BasicAlgorithms.vcxproj +++ /dev/null @@ -1,150 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {617019A2-97BE-4A60-8EC4-3547D8C54533} - Example_BasicAlgorithms - - - - Application - true - v120 - MultiByte - - - Application - true - v120 - MultiByte - - - Application - false - v120 - true - MultiByte - - - Application - false - v120 - true - MultiByte - - - - - - - - - - - - - - - - - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - - Level3 - Disabled - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - - - true - Console - - - - - Level3 - Disabled - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - - - true - Console - - - - - Level3 - MaxSpeed - true - true - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - - - true - true - true - Console - - - - - Level3 - MaxSpeed - true - true - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - - - true - true - true - - - - - {5e56aab9-4e33-4b9e-a315-e85cedb75cf1} - - - - - - - - - \ No newline at end of file diff --git a/project/msvc/Example_BasicAlgorithms.vcxproj.filters b/project/msvc/Example_BasicAlgorithms.vcxproj.filters deleted file mode 100644 index b71fc9ed..00000000 --- a/project/msvc/Example_BasicAlgorithms.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - \ No newline at end of file diff --git a/project/msvc/Example_BasicComposition.vcxproj b/project/msvc/Example_BasicComposition.vcxproj deleted file mode 100644 index 01d26c88..00000000 --- a/project/msvc/Example_BasicComposition.vcxproj +++ /dev/null @@ -1,150 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {D7B70D3B-F14D-4A85-B164-EAB88C358E85} - Example_BasicComposition - - - - Application - true - v120 - MultiByte - - - Application - true - v120 - MultiByte - - - Application - false - v120 - true - MultiByte - - - Application - false - v120 - true - MultiByte - - - - - - - - - - - - - - - - - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - - Level3 - Disabled - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - - - true - Console - - - - - Level3 - Disabled - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - - - true - Console - - - - - Level3 - MaxSpeed - true - true - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - - - true - true - true - Console - - - - - Level3 - MaxSpeed - true - true - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - - - true - true - true - - - - - {5e56aab9-4e33-4b9e-a315-e85cedb75cf1} - - - - - - - - - \ No newline at end of file diff --git a/project/msvc/Example_BasicComposition.vcxproj.filters b/project/msvc/Example_BasicComposition.vcxproj.filters deleted file mode 100644 index c7a5255c..00000000 --- a/project/msvc/Example_BasicComposition.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - \ No newline at end of file diff --git a/project/msvc/Example_BasicEvents.vcxproj b/project/msvc/Example_BasicEvents.vcxproj deleted file mode 100644 index d5d13295..00000000 --- a/project/msvc/Example_BasicEvents.vcxproj +++ /dev/null @@ -1,150 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {BD777649-97F1-4810-BF21-CB27F7672BF4} - Example_BasicEvents - - - - Application - true - v120 - MultiByte - - - Application - true - v120 - MultiByte - - - Application - false - v120 - true - MultiByte - - - Application - false - v120 - true - MultiByte - - - - - - - - - - - - - - - - - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - - Level3 - Disabled - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - - - true - Console - - - - - Level3 - Disabled - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - - - true - Console - - - - - Level3 - MaxSpeed - true - true - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - - - true - true - true - Console - - - - - Level3 - MaxSpeed - true - true - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - - - true - true - true - - - - - {5e56aab9-4e33-4b9e-a315-e85cedb75cf1} - - - - - - - - - \ No newline at end of file diff --git a/project/msvc/Example_BasicEvents.vcxproj.filters b/project/msvc/Example_BasicEvents.vcxproj.filters deleted file mode 100644 index 54888eca..00000000 --- a/project/msvc/Example_BasicEvents.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - \ No newline at end of file diff --git a/project/msvc/Example_BasicObservers.vcxproj b/project/msvc/Example_BasicObservers.vcxproj deleted file mode 100644 index 9fa37b8c..00000000 --- a/project/msvc/Example_BasicObservers.vcxproj +++ /dev/null @@ -1,150 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {CC66BFA0-D609-46E0-9FD1-F9CC902410B1} - Example_BasicObservers - - - - Application - true - v120 - MultiByte - - - Application - true - v120 - MultiByte - - - Application - false - v120 - true - MultiByte - - - Application - false - v120 - true - MultiByte - - - - - - - - - - - - - - - - - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - - Level3 - Disabled - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - - - true - Console - - - - - Level3 - Disabled - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - - - true - Console - - - - - Level3 - MaxSpeed - true - true - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - - - true - true - true - Console - - - - - Level3 - MaxSpeed - true - true - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - - - true - true - true - - - - - - - - {5e56aab9-4e33-4b9e-a315-e85cedb75cf1} - - - - - - \ No newline at end of file diff --git a/project/msvc/Example_BasicObservers.vcxproj.filters b/project/msvc/Example_BasicObservers.vcxproj.filters deleted file mode 100644 index a809b186..00000000 --- a/project/msvc/Example_BasicObservers.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - \ No newline at end of file diff --git a/project/msvc/Example_BasicReactors.vcxproj b/project/msvc/Example_BasicReactors.vcxproj deleted file mode 100644 index 07701d98..00000000 --- a/project/msvc/Example_BasicReactors.vcxproj +++ /dev/null @@ -1,150 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {D976F4D4-B472-4709-BFB5-B1BEEA1F7E96} - Example_BasicReactors - - - - Application - true - v120 - MultiByte - - - Application - true - v120 - MultiByte - - - Application - false - v120 - true - MultiByte - - - Application - false - v120 - true - MultiByte - - - - - - - - - - - - - - - - - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - - Level3 - Disabled - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - - - true - Console - - - - - Level3 - Disabled - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - - - true - Console - - - - - Level3 - MaxSpeed - true - true - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - - - true - true - true - Console - - - - - Level3 - MaxSpeed - true - true - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - - - true - true - true - - - - - - - - {5e56aab9-4e33-4b9e-a315-e85cedb75cf1} - - - - - - \ No newline at end of file diff --git a/project/msvc/Example_BasicReactors.vcxproj.filters b/project/msvc/Example_BasicReactors.vcxproj.filters deleted file mode 100644 index 7398067f..00000000 --- a/project/msvc/Example_BasicReactors.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - \ No newline at end of file diff --git a/project/msvc/Example_BasicSignals.vcxproj b/project/msvc/Example_BasicSignals.vcxproj deleted file mode 100644 index e090dd8a..00000000 --- a/project/msvc/Example_BasicSignals.vcxproj +++ /dev/null @@ -1,150 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {230C9137-CCD0-47E2-8F1F-2E1DD19984A1} - Example_BasicSignals - - - - Application - true - v120 - MultiByte - - - Application - true - v120 - MultiByte - - - Application - false - v120 - true - MultiByte - - - Application - false - v120 - true - MultiByte - - - - - - - - - - - - - - - - - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - - Level3 - Disabled - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - - - true - Console - - - - - Level3 - Disabled - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - - - true - Console - - - - - Level3 - MaxSpeed - true - true - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - - - true - true - true - Console - - - - - Level3 - MaxSpeed - true - true - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - - - true - true - true - - - - - {5e56aab9-4e33-4b9e-a315-e85cedb75cf1} - - - - - - - - - \ No newline at end of file diff --git a/project/msvc/Example_BasicSignals.vcxproj.filters b/project/msvc/Example_BasicSignals.vcxproj.filters deleted file mode 100644 index eafb525a..00000000 --- a/project/msvc/Example_BasicSignals.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - \ No newline at end of file diff --git a/project/msvc/Example_BasicSynchronization.vcxproj b/project/msvc/Example_BasicSynchronization.vcxproj deleted file mode 100644 index 2b2edec4..00000000 --- a/project/msvc/Example_BasicSynchronization.vcxproj +++ /dev/null @@ -1,151 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {269329F8-A9E1-41AC-9C37-3A82A082A62C} - Example_BasicSynchronization - - - - Application - true - v120 - MultiByte - - - Application - true - v120 - MultiByte - - - Application - false - v120 - true - MultiByte - - - Application - false - v120 - true - MultiByte - - - - - - - - - - - - - - - - - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - $(SolutionDir)..\..\build\$(Configuration)\ - $(OutDir)$(ProjectName)\ - - - - Level3 - Disabled - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - - - true - Console - - - - - Level3 - Disabled - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - - - true - Console - - - - - Level3 - MaxSpeed - true - true - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - - - true - true - true - Console - - - - - Level3 - MaxSpeed - true - true - true - $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) - - - true - true - true - Console - - - - - - - - {5e56aab9-4e33-4b9e-a315-e85cedb75cf1} - - - - - - \ No newline at end of file diff --git a/project/msvc/Example_BasicSynchronization.vcxproj.filters b/project/msvc/Example_BasicSynchronization.vcxproj.filters deleted file mode 100644 index f19c5061..00000000 --- a/project/msvc/Example_BasicSynchronization.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - \ No newline at end of file diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 1946c5e0..a598d76e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,23 +1,28 @@ -### Configuration -if(DEFINED ENV{GTEST_DIR}) - message("Using gtest found in $ENV{GTEST_DIR}.") -else() - message("GTEST_DIR is not defined. You must tell CMake where to find the gtest source.") - return() -endif() -add_subdirectory($ENV{GTEST_DIR} ${CMAKE_CURRENT_BINARY_DIR}/gtest) +find_package(GTest REQUIRED) +find_package(Threads REQUIRED) -### CppReactTest -add_executable(CppReactTest - src/EventStreamTest.cpp - src/EventStreamTestQ.cpp - src/MoveTest.cpp - src/ObserverTest.cpp - src/ObserverTestQ.cpp - src/OperationsTest.cpp - src/OperationsTestQ.cpp - src/SignalTest.cpp - src/SignalTestQ.cpp - src/TransactionTest.cpp) +function(cppreact_test) + set(options SKIPPED BOOST BENCHMARK) + set(oneValueArgs NAME) + set(multiValueArgs SOURCES) + cmake_parse_arguments(cppreact_test "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) -target_link_libraries(CppReactTest CppReact gtest gtest_main) + add_executable (${cppreact_test_NAME} ${cppreact_test_SOURCES}) + target_link_libraries(${cppreact_test_NAME} CppReact ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) + + # GTEST_ADD_TESTS does not seem to be able to find our tests ... + # pure guess : because of INSTANTIATE_TYPED_TEST_CASE_P usage ? + #GTEST_ADD_TESTS(${cppreact_test_NAME} "" AUTO) + add_test(NAME ${cppreact_test_NAME} COMMAND ${cppreact_test_NAME}) +endfunction(cppreact_test) + +#cppreact_test(NAME EventStreamTest SOURCES src/EventStreamTest.cpp) +#cppreact_test(NAME EventStreamTestQ SOURCES src/EventStreamTestQ.cpp) +cppreact_test(NAME MoveTest SOURCES src/MoveTest.cpp) +cppreact_test(NAME ObserverTest SOURCES src/ObserverTest.cpp) +#cppreact_test(NAME ObserverTestQ SOURCES src/ObserverTestQ.cpp) +#cppreact_test(NAME OperationsTest SOURCES src/OperationsTest.cpp) +#cppreact_test(NAME OperationsTestQ SOURCES src/OperationsTestQ.cpp) +cppreact_test(NAME SignalTest SOURCES src/SignalTest.cpp) +cppreact_test(NAME SignalTestQ SOURCES src/SignalTestQ.cpp) +#cppreact_test(NAME TransactionTest SOURCES src/TransactionTest.cpp) diff --git a/tests/src/MoveTest.h b/tests/src/MoveTest.h index 46e1d39d..960df6ab 100644 --- a/tests/src/MoveTest.h +++ b/tests/src/MoveTest.h @@ -30,7 +30,6 @@ class MoveTest : public testing::Test struct Stats { - int copyCount = 0; int moveCount = 0; }; @@ -39,19 +38,13 @@ class MoveTest : public testing::Test int v = 0; Stats* stats = nullptr; - CopyCounter() = default; - CopyCounter(int x, Stats* s) : v( x ), stats( s ) {} - CopyCounter(const CopyCounter& other) : - v( other.v ), - stats( other.stats ) - { - stats->copyCount++; - } + CopyCounter(const CopyCounter& other) = delete; + CopyCounter& operator=(const CopyCounter& other) = delete; CopyCounter(CopyCounter&& other) : v( other.v ), @@ -60,14 +53,6 @@ class MoveTest : public testing::Test stats->moveCount++; } - CopyCounter& operator=(const CopyCounter& other) - { - v = other.v; - stats = other.stats; - stats->copyCount++; - return *this; - } - CopyCounter& operator=(CopyCounter&& other) { v = other.v; @@ -107,21 +92,17 @@ TYPED_TEST_P(MoveTest, Copy1) auto d = MakeVar(CopyCounter{1000,&stats1}); // 4x move to value_ - // 4x copy to newValue_ (can't be unitialized for references) - ASSERT_EQ(stats1.copyCount, 4); - ASSERT_EQ(stats1.moveCount, 4); + ASSERT_EQ(4, stats1.moveCount); auto x = a + b + c + d; - ASSERT_EQ(stats1.copyCount, 4); - ASSERT_EQ(stats1.moveCount, 7); - ASSERT_EQ(x().v, 1111); + ASSERT_EQ(7, stats1.moveCount); + ASSERT_EQ(1111, x().v); a <<= CopyCounter{2,&stats1}; - ASSERT_EQ(stats1.copyCount, 4); - ASSERT_EQ(stats1.moveCount, 10); - ASSERT_EQ(x().v, 1112); + ASSERT_EQ(10, stats1.moveCount); + ASSERT_EQ(1112, x().v); } /////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/tests/src/OperationsTest.h b/tests/src/OperationsTest.h index 5ef9cc3d..a5f7c83d 100644 --- a/tests/src/OperationsTest.h +++ b/tests/src/OperationsTest.h @@ -30,6 +30,11 @@ struct Incrementer { T operator()(Token, T v) const { return v+1; } }; template struct Decrementer { T operator()(Token, T v) const { return v-1; } }; +template +void repeat(I i, F f) { + while (i--) f(); +} + /////////////////////////////////////////////////////////////////////////////////////////////////// /// EventStreamTest fixture /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -710,11 +715,10 @@ TYPED_TEST_P(OperationsTest, SyncedIterate4) vector{}, With(op1,op2), [] (EventRange range, vector& v, int op1, int op2) -> void { - for (const auto& e : range) - { + repeat(range.size(),[&]{ v.push_back(op1); v.push_back(op2); - } + }); }); auto out2 = Iterate( diff --git a/tests/src/SignalTest.h b/tests/src/SignalTest.h index 8d7a34e2..149c329e 100644 --- a/tests/src/SignalTest.h +++ b/tests/src/SignalTest.h @@ -62,6 +62,77 @@ TYPED_TEST_P(SignalTest, MakeVars) ASSERT_EQ(v4(),40); } +/////////////////////////////////////////////////////////////////////////////////////////////////// +/// Signals0 tests +/////////////////////////////////////////////////////////////////////////////////////////////////// +TYPED_TEST_P(SignalTest, Signals00) +{ + using D = typename Signals00::MyDomain; + + auto v1 = MakeVar(1); + auto v2 = MakeVar(2); + + auto s1 = MakeSignal(With(v1,v2), [] (int a, int b) { + return a + b; + }); + + ASSERT_EQ(s1(),3); +} + +TYPED_TEST_P(SignalTest, Signals01) +{ + using D = typename Signals01::MyDomain; + + auto v1 = MakeVar(1); + auto v2 = MakeVar(2); + + auto s1 = MakeSignal(With(v1,v2), [] (int a, int b) { + return a + b; + }); + + auto v3 = MakeVar(3); + + auto s2 = MakeSignal(With(s1,v3), [] (int a, int b) { + return a + b; + }); + + ASSERT_EQ(s2(),6); +} + +TYPED_TEST_P(SignalTest, Signals02) +{ + using D = typename Signals02::MyDomain; + + auto v1 = MakeVar(1); + auto v2 = MakeVar(2); + + auto s1 = MakeSignal(With(v1,v2), [] (int a, int b) { + return a + b; + }); + + auto v3 = MakeVar(3); + + ASSERT_EQ((s1 + v3)(),6); +} + +TYPED_TEST_P(SignalTest, Signals03) +{ + using D = typename Signals03::MyDomain; + + auto v1 = MakeVar(1); + auto v2 = MakeVar(2); + + auto s1 = MakeSignal(With(v1,v2), [] (int a, int b) { + return a + b; + }); + + auto v3 = MakeVar(3); + + auto s2 = s1 + v3; + + ASSERT_EQ(s2(),6); +} + /////////////////////////////////////////////////////////////////////////////////////////////////// /// Signals1 test /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -274,6 +345,79 @@ TYPED_TEST_P(SignalTest, Signals4) ASSERT_EQ(b2(),12); } +/////////////////////////////////////////////////////////////////////////////////////////////////// +/// Plus tests +/////////////////////////////////////////////////////////////////////////////////////////////////// +TYPED_TEST_P(SignalTest, Plus100) +{ + using D = typename Plus100::MyDomain; + + auto a = MakeVar(1); + + auto b = a + 100; + ASSERT_EQ(b(),101); + + a <<= 10; + ASSERT_EQ(b(),110); +} + +TYPED_TEST_P(SignalTest, UnaryMinus) +{ + using D = typename UnaryMinus::MyDomain; + + auto a = MakeVar(1); + + auto b = -a; + ASSERT_EQ(b(),-1); + + a <<= 10; + ASSERT_EQ(b(),-10); +} + +TYPED_TEST_P(SignalTest, UnaryMinusThenPlus100) +{ + using D = typename UnaryMinusThenPlus100::MyDomain; + + auto a = MakeVar(1); + + auto b = -a; + ASSERT_EQ(b(),-1); + + auto c = b + 100; + ASSERT_EQ(b(),-1); + ASSERT_EQ(c(),99); + + a <<= 10; + ASSERT_EQ(b(),-10); + ASSERT_EQ(c(),90); +} + +TYPED_TEST_P(SignalTest, Plus10Plus100) +{ + using D = typename Plus10Plus100::MyDomain; + + auto a = MakeVar(1); + + auto b = a + 10 + 100; + ASSERT_EQ(111, b()); + + a <<= 10; + ASSERT_EQ(120, b()); +} + +TYPED_TEST_P(SignalTest, UnaryMinusPlus100) +{ + using D = typename UnaryMinusPlus100::MyDomain; + + auto a = MakeVar(1); + + auto b = -a + 100; + ASSERT_EQ(b(),99); + + a <<= 10; + ASSERT_EQ(b(),90); +} + /////////////////////////////////////////////////////////////////////////////////////////////////// /// FunctionBind1 test /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -459,7 +603,7 @@ TYPED_TEST_P(SignalTest, Flatten3) auto result = flattened + a0; - ASSERT_EQ(result(), 10 + 30); + ASSERT_EQ(10 + 30, result()); ASSERT_EQ(observeCount, 0); DoTransaction([&] { @@ -536,7 +680,7 @@ TYPED_TEST_P(SignalTest, Member1) auto outer = MakeVar(10); auto inner = MakeVar(outer); - auto flattened = inner.Flatten(); + auto flattened = Flatten(inner); Observe(flattened, [] (int v) { ASSERT_EQ(v, 30); @@ -653,7 +797,9 @@ REGISTER_TYPED_TEST_CASE_P ( SignalTest, MakeVars, + Signals00, Signals01, Signals02, Signals03, Signals1, Signals2, Signals3, Signals4, + Plus100, UnaryMinusThenPlus100, Plus10Plus100, UnaryMinus,UnaryMinusPlus100, FunctionBind1, FunctionBind2, Flatten1, Flatten2, Flatten3, Flatten4, Member1, diff --git a/tests/src/TransactionTest.cpp b/tests/src/TransactionTest.cpp index 61a51e11..efc476f5 100644 --- a/tests/src/TransactionTest.cpp +++ b/tests/src/TransactionTest.cpp @@ -26,4 +26,4 @@ INSTANTIATE_TYPED_TEST_CASE_P(ParToposort, TransactionTest, P2); INSTANTIATE_TYPED_TEST_CASE_P(Pulsecount, TransactionTest, P3); INSTANTIATE_TYPED_TEST_CASE_P(Subtree, TransactionTest, P4); -} // ~namespace \ No newline at end of file +} // ~namespace From 63ca996bec89ccd2e02606b09f1435ce80c2b2ae Mon Sep 17 00:00:00 2001 From: jonnew Date: Mon, 12 Dec 2016 21:33:58 -0500 Subject: [PATCH 5/8] Fix dangling field warning - Fix binding reference member 'count_' to a temporary value in Timing.h --- include/react/common/Timing.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/react/common/Timing.h b/include/react/common/Timing.h index 9440ceaa..7c6c9158 100644 --- a/include/react/common/Timing.h +++ b/include/react/common/Timing.h @@ -98,7 +98,7 @@ class ConditionalTimer public: ScopedTimer(ConditionalTimer& parent, const size_t& count) : parent_( parent ), - count_( count ) + count_( (std::chrono::microseconds::rep&)count ) { if (!parent_.shouldMeasure_) return; From b47c139702eb5531cd370b01ae7050c372160b98 Mon Sep 17 00:00:00 2001 From: jonnew Date: Sun, 18 Dec 2016 19:11:09 -0500 Subject: [PATCH 6/8] Move Token declaration to privent undefined type - It was being used before being declared in Events.h --- include/react/Event.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/react/Event.h b/include/react/Event.h index 6c94fb9c..d0e46393 100644 --- a/include/react/Event.h +++ b/include/react/Event.h @@ -25,6 +25,7 @@ using REACT_IMPL::WeightHint; +enum class Token { value }; /////////////////////////////////////////////////////////////////////////////////////////////////// /// MakeEventSource /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -431,7 +432,6 @@ auto Join(const Events& ... args) /////////////////////////////////////////////////////////////////////////////////////////////////// /// Token /////////////////////////////////////////////////////////////////////////////////////////////////// -enum class Token { value }; struct Tokenizer { From b5c01c05c2c59abbe50faf0ea0a75a39c5510d19 Mon Sep 17 00:00:00 2001 From: jonnew Date: Fri, 3 Mar 2017 13:14:20 -0500 Subject: [PATCH 7/8] Added some notes. --- include/react/Algorithm.h | 1 + include/react/Event.h | 2 +- include/react/detail/graph/EventNodes.h | 10 +++++----- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/include/react/Algorithm.h b/include/react/Algorithm.h index a1d20b18..5ed9fb9c 100644 --- a/include/react/Algorithm.h +++ b/include/react/Algorithm.h @@ -9,6 +9,7 @@ #pragma once +#include "Event.h" #include "react/detail/Defs.h" #include diff --git a/include/react/Event.h b/include/react/Event.h index 6c94fb9c..8237fe66 100644 --- a/include/react/Event.h +++ b/include/react/Event.h @@ -28,6 +28,7 @@ using REACT_IMPL::WeightHint; /////////////////////////////////////////////////////////////////////////////////////////////////// /// MakeEventSource /////////////////////////////////////////////////////////////////////////////////////////////////// +enum class Token { value }; template auto MakeEventSource() -> EventSource @@ -431,7 +432,6 @@ auto Join(const Events& ... args) /////////////////////////////////////////////////////////////////////////////////////////////////// /// Token /////////////////////////////////////////////////////////////////////////////////////////////////// -enum class Token { value }; struct Tokenizer { diff --git a/include/react/detail/graph/EventNodes.h b/include/react/detail/graph/EventNodes.h index 850b36c2..71390dcf 100644 --- a/include/react/detail/graph/EventNodes.h +++ b/include/react/detail/graph/EventNodes.h @@ -325,13 +325,13 @@ class EventTransformOp : public ReactiveOpBase {} template - void Collect(const TTurn& turn, const TCollector& collector) const + void Collect(const TTurn& turn, const TCollector& collector) const // const NOTE: Shea, 2016-12-16 to all mutable Transform { collectImpl(turn, TransformEventCollector( func_, collector ), getDep()); } template - void CollectRec(const TFunctor& functor) const + void CollectRec(const TFunctor& functor) const // const NOTE: Shea, 2016-12-16 to all mutable Transform { // Can't recycle functor because MyFunc needs replacing Collect(functor.MyTurn, functor.MyCollector); @@ -343,7 +343,7 @@ class EventTransformOp : public ReactiveOpBase template struct TransformEventCollector { - TransformEventCollector(const TFunc& func, const TTarget& target) : + TransformEventCollector(const TFunc& func, const TTarget& target) : // const TFunc& func NOTE: Shea, 2016-12-16 to all mutable Transform MyFunc( func ), MyTarget( target ) {} @@ -353,7 +353,7 @@ class EventTransformOp : public ReactiveOpBase MyTarget(MyFunc(e)); } - const TFunc& MyFunc; + const TFunc& MyFunc; // const NOTE: Shea, 2016-12-16 to all mutable Transform const TTarget& MyTarget; }; @@ -1029,4 +1029,4 @@ class EventJoinNode : /****************************************/ REACT_IMPL_END /***************************************/ -#endif // REACT_DETAIL_GRAPH_EVENTNODES_H_INCLUDED \ No newline at end of file +#endif // REACT_DETAIL_GRAPH_EVENTNODES_H_INCLUDED From 6ad48dcbffbe0245a5eb05e191ab1f9fbfdc8510 Mon Sep 17 00:00:00 2001 From: jonnew Date: Thu, 27 Apr 2017 23:31:22 -0400 Subject: [PATCH 8/8] Removed spurious enum declaration. --- include/react/Event.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/react/Event.h b/include/react/Event.h index 2c8a2e97..8237fe66 100644 --- a/include/react/Event.h +++ b/include/react/Event.h @@ -25,7 +25,6 @@ using REACT_IMPL::WeightHint; -enum class Token { value }; /////////////////////////////////////////////////////////////////////////////////////////////////// /// MakeEventSource ///////////////////////////////////////////////////////////////////////////////////////////////////