From d7d545575250f616f0b9e2243e08544ab2794a03 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Sun, 22 Mar 2015 17:29:35 +0100 Subject: o Renaming trygvis::soil_moisture to trygvis::sample. --- README.md | 4 + apps/SoilMoisture.cpp | 2 +- apps/SoilMoisture.h | 7 +- apps/apps.h | 5 +- apps/sample-convert.cpp | 6 +- apps/sample-select.cpp | 4 +- apps/sample-timestamp.cpp | 4 +- apps/sm-get-value.cpp | 4 +- apps/sm-serial-read-all.cpp | 4 +- apps/sm-serial-read.cpp | 4 +- sensor/CMakeLists.txt | 5 +- sensor/include/SensorSample.h | 427 ---------------------------------- sensor/include/trygvis/SensorSample.h | 423 +++++++++++++++++++++++++++++++++ sensor/main/SensorSample.cpp | 6 +- 14 files changed, 450 insertions(+), 455 deletions(-) delete mode 100644 sensor/include/SensorSample.h create mode 100644 sensor/include/trygvis/SensorSample.h diff --git a/README.md b/README.md index ec9c88c..e4603e4 100644 --- a/README.md +++ b/README.md @@ -8,3 +8,7 @@ Building: make -j This will build a Debug release by default. Add `-DCMAKE_BUILD_TYPE=Release` to build a release build. + +# CMake notes + +Header files are added as sources so the IDEs will search/index them properly. diff --git a/apps/SoilMoisture.cpp b/apps/SoilMoisture.cpp index f998d74..89c2fe5 100644 --- a/apps/SoilMoisture.cpp +++ b/apps/SoilMoisture.cpp @@ -1,7 +1,7 @@ #include "SoilMoisture.h" namespace trygvis { -namespace soil_moisture { +namespace sensor { #define BLUETOOTH_UUID_INITIALIZER \ { \ diff --git a/apps/SoilMoisture.h b/apps/SoilMoisture.h index ea64032..2016c9a 100644 --- a/apps/SoilMoisture.h +++ b/apps/SoilMoisture.h @@ -1,11 +1,10 @@ -#ifndef SOIL_MOISTURE_H -#define SOIL_MOISTURE_H +#pragma once #include #include namespace trygvis { -namespace soil_moisture { +namespace sensor { using namespace trygvis::bluetooth; @@ -43,5 +42,3 @@ private: } } - -#endif diff --git a/apps/apps.h b/apps/apps.h index 03ec68f..727e554 100644 --- a/apps/apps.h +++ b/apps/apps.h @@ -1,5 +1,4 @@ -#ifndef UTILS_H -#define UTILS_H +#pragma once #include @@ -47,5 +46,3 @@ static inline void noop_deleter(void *) { } } - -#endif diff --git a/apps/sample-convert.cpp b/apps/sample-convert.cpp index 4834732..6ce83e8 100644 --- a/apps/sample-convert.cpp +++ b/apps/sample-convert.cpp @@ -1,4 +1,4 @@ -#include "SensorSample.h" +#include "trygvis/SensorSample.h" #include "json.hpp" #include "apps.h" #include @@ -9,7 +9,7 @@ namespace apps { using namespace std; using namespace trygvis::apps; -using namespace trygvis::soil_moisture; +using namespace trygvis::sensor; using boost::tokenizer; namespace po = boost::program_options; @@ -66,7 +66,7 @@ public: } std::vector options; - trygvis::soil_moisture::timestamp_field tf(timestamp_field); + trygvis::sensor::timestamp_field tf(timestamp_field); if (!timestamp_field.empty()) { options.push_back(&tf); diff --git a/apps/sample-select.cpp b/apps/sample-select.cpp index 8180709..fc50f41 100644 --- a/apps/sample-select.cpp +++ b/apps/sample-select.cpp @@ -1,4 +1,4 @@ -#include "SensorSample.h" +#include "trygvis/SensorSample.h" #include "apps.h" #include @@ -7,7 +7,7 @@ namespace apps { using namespace std; using namespace trygvis::apps; -using namespace trygvis::soil_moisture; +using namespace trygvis::sensor; using boost::tokenizer; namespace po = boost::program_options; diff --git a/apps/sample-timestamp.cpp b/apps/sample-timestamp.cpp index 018ecb0..c95f7a3 100644 --- a/apps/sample-timestamp.cpp +++ b/apps/sample-timestamp.cpp @@ -1,4 +1,4 @@ -#include "SensorSample.h" +#include "trygvis/SensorSample.h" #include "apps.h" #include #include @@ -8,7 +8,7 @@ namespace apps { using namespace std; using namespace trygvis::apps; -using namespace trygvis::soil_moisture; +using namespace trygvis::sensor; namespace po = boost::program_options; enum class time_resolution { diff --git a/apps/sm-get-value.cpp b/apps/sm-get-value.cpp index b8fa983..25f1c3e 100644 --- a/apps/sm-get-value.cpp +++ b/apps/sm-get-value.cpp @@ -5,7 +5,7 @@ #include #include "ble/Bluetooth.h" #include "SoilMoisture.h" -#include "SensorSample.h" +#include "trygvis/SensorSample.h" #include "json.hpp" #include "apps.h" @@ -14,7 +14,7 @@ using namespace std; using namespace std::chrono; using namespace trygvis::apps; using namespace trygvis::bluetooth; -using namespace trygvis::soil_moisture; +using namespace trygvis::sensor; namespace po = boost::program_options; using json = nlohmann::json; diff --git a/apps/sm-serial-read-all.cpp b/apps/sm-serial-read-all.cpp index 7241864..eb1f112 100644 --- a/apps/sm-serial-read-all.cpp +++ b/apps/sm-serial-read-all.cpp @@ -1,4 +1,4 @@ -#include "SensorSample.h" +#include "trygvis/SensorSample.h" #include "json.hpp" #include "apps.h" #include @@ -11,7 +11,7 @@ using namespace boost::asio; using namespace std; using namespace std::chrono; using namespace trygvis::apps; -using namespace trygvis::soil_moisture; +using namespace trygvis::sensor; namespace po = boost::program_options; using json = nlohmann::json; diff --git a/apps/sm-serial-read.cpp b/apps/sm-serial-read.cpp index a8d528a..68cdea7 100644 --- a/apps/sm-serial-read.cpp +++ b/apps/sm-serial-read.cpp @@ -1,4 +1,4 @@ -#include "SensorSample.h" +#include "trygvis/SensorSample.h" #include "json.hpp" #include "apps.h" #include @@ -12,7 +12,7 @@ using namespace boost::asio; using namespace std; using namespace std::chrono; using namespace trygvis::apps; -using namespace trygvis::soil_moisture; +using namespace trygvis::sensor; namespace po = boost::program_options; using json = nlohmann::json; diff --git a/sensor/CMakeLists.txt b/sensor/CMakeLists.txt index 5d7612f..7cee42b 100644 --- a/sensor/CMakeLists.txt +++ b/sensor/CMakeLists.txt @@ -1,5 +1,8 @@ +file(GLOB INCLUDES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} include/*.h) + add_library(trygvis-sensor - main/SensorSample.cpp) + main/SensorSample.cpp + ${INCLUDES}) include_directories("${PROJECT_SOURCE_DIR}/json/src") include_directories(include) diff --git a/sensor/include/SensorSample.h b/sensor/include/SensorSample.h deleted file mode 100644 index 386296a..0000000 --- a/sensor/include/SensorSample.h +++ /dev/null @@ -1,427 +0,0 @@ -#ifndef SOIL_MOISTURE_IO_H -#define SOIL_MOISTURE_IO_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// TODO: rename to trygvis::sample -namespace trygvis { -namespace soil_moisture { - -using namespace std; -using namespace boost::asio; - -template -using o = boost::optional; - -enum class sample_format_type { - AUTO, - CSV, - KEY_VALUE, - JSON, - SQL, - RRD, -}; - -string to_string(const sample_format_type &arg); - -std::ostream& operator<<(std::ostream& os, sample_format_type const& type); - -std::istream& operator>>(std::istream& is, sample_format_type& type); - -class SampleStreamParser; - -class SampleOutputStream; - -class KeyDictionary; - -class SampleKey; - -// TODO: rename to open_sample_stream_parser -unique_ptr open_sample_input_stream( - shared_ptr output, - KeyDictionary &dict, - sample_format_type type = sample_format_type::AUTO); - -class sample_output_stream_option { -public: - virtual ~sample_output_stream_option() { - }; -}; - -class output_fields : public sample_output_stream_option { -public: -// output_fields() { -// } -// -// output_fields(std::vector::iterator begin, std::vector::iterator end) : -// fields(begin, end) { -// } - - ~output_fields() { - } - - vector fields; -}; - - -class timestamp_field : public sample_output_stream_option { -public: - timestamp_field(string name) : name(name) { - } - - ~timestamp_field() { - } - - string name; -}; - -unique_ptr open_sample_output_stream( - shared_ptr output, - KeyDictionary &dict, - sample_format_type type, - vector options); - -static inline -unique_ptr open_sample_output_stream( - shared_ptr output, - KeyDictionary &dict, - sample_format_type type) { - return open_sample_output_stream(output, dict, type); -} - -class ThreadSafeSampleOutputStream; - -static inline -unique_ptr thread_safe_sample_output_stream(unique_ptr underlying) { - return make_unique(move(underlying)); -}; - -class sample_exception : public runtime_error { -public: - sample_exception(const string &what) : runtime_error(what) { - } -}; - -class KeyDictionary; - -using SampleKeyVector = vector; -using SampleKeyIndex = SampleKeyVector::size_type; - -struct SampleKey { -private: - SampleKey(const SampleKey& that) = delete; - SampleKey(SampleKeyIndex index, const string &name) : index(index), name(name) { - if (name.length() == 0) { - throw sample_exception("Bad sample key."); - } - } - -public: - friend class KeyDictionary; - - inline - bool operator==(const SampleKey &that) const { - return name == that.name; - } - - const SampleKeyIndex index; - const string name; -}; - -class KeyDictionary { -public: - KeyDictionary() { - } - - ~KeyDictionary() { - std::for_each(keys.begin(), keys.end(), std::default_delete()); - } - KeyDictionary(KeyDictionary& that) = delete; - - SampleKey *indexOf(const string key) { - SampleKeyIndex i = 0; - for (auto ptr = keys.cbegin(); ptr != keys.cend(); ptr++, i++) { - if ((*ptr)->name == key) { - return *ptr; - } - } - - i = keys.size(); - auto sample_key = new SampleKey(i, key); - keys.push_back(sample_key); - - return sample_key; - } - - SampleKey *at(SampleKeyIndex i) const { - if (i >= keys.size()) { - throw sample_exception("Out of bounds"); - } - - return keys.at(i); - } - - vector findIndexes(SampleKeyVector &keys) { - vector indexes; - - for (auto &key: keys) { - auto index = indexOf(key->name); - indexes.push_back(index); - } - - return indexes; - } - - inline - SampleKeyVector::const_iterator end() const { - return keys.cend(); - } - - inline - SampleKeyVector::const_iterator begin() const { - return keys.cbegin(); - } - -// string nameOf(SampleKeyIndex index) { -// return keys.at(index).name; -// } - - inline - SampleKeyVector::size_type size() const { - return keys.size(); - } - - inline - bool empty() const { - return keys.empty(); - } - -private: - SampleKeyVector keys; -}; - -class SampleRecord { -public: - typedef vector> vec; - - SampleRecord(KeyDictionary &dict) : dict(dict) { - } - - SampleRecord(KeyDictionary &dict, vec values) - : dict(dict), values(values) { - } - - inline - vec::const_iterator cbegin() const { - return values.cbegin(); - } - - inline - vec::const_iterator cend() const { - return values.cend(); - } - - inline - bool empty() const { - return values.empty(); - } - - const o at(const SampleKey *key) const { - SampleKeyIndex index = key->index; - if (index >= values.size()) { - return o(); - } - - return values.at(index); - } - - void set(const SampleKey *key, const std::string &value) { - values.resize(max(values.size(), key->index + 1)); - - values.at(key->index).reset(value); - } - - template - const o lexical_at(const SampleKey *key) const { - auto value = at(key); - - if (!value) { - return o(); - } - - return o(boost::lexical_cast(value.get())); - } - - string to_string() const { - SampleKeyIndex i = 0; - string s; - for (auto ptr = values.begin(); ptr != values.end(); ptr++, i++) { - auto o = *ptr; - - if (!o) { - continue; - } - - auto value = o.get(); - - s += dict.at(i)->name + " = " + value + ", "; - } - return s; - } - - KeyDictionary &dict; -private: - vec values; -}; - -class SampleOutputStream { -public: - virtual void write(SampleRecord const &sample) = 0; -}; - -class VectorSampleOutputStream : public SampleOutputStream { - -public: - virtual void write(SampleRecord const &sample) override; - -public: - vector samples; -}; - -class ThreadSafeSampleOutputStream : public SampleOutputStream { -public: - ThreadSafeSampleOutputStream(unique_ptr underlying); - - ~ThreadSafeSampleOutputStream() { - } - - void write(SampleRecord const &sample) override; - -private: - unique_ptr underlying; - std::mutex mutex; -}; - -class CsvSampleOutputStream : public SampleOutputStream { -public: - CsvSampleOutputStream(shared_ptr stream, KeyDictionary &dict); - - void write(SampleRecord const &sample); - - const KeyDictionary &getDict() { - return dict; - } - -private: - void writeHeader(); - - KeyDictionary &dict; - shared_ptr stream; - bool headerWritten; -}; - -class JsonSampleOutputStream : public SampleOutputStream { -public: - JsonSampleOutputStream(shared_ptr stream, KeyDictionary &dict); - - void write(SampleRecord const &sample) override; - -private: - KeyDictionary &dict; - shared_ptr stream; -}; - -class KeyValueSampleOutputStream : public SampleOutputStream { -public: - KeyValueSampleOutputStream(shared_ptr stream, KeyDictionary &dict); - - void write(SampleRecord const &sample) override; - -private: - KeyDictionary &dict; - shared_ptr stream; -}; - -class RrdSampleOutputStream : public SampleOutputStream { -public: - RrdSampleOutputStream(shared_ptr stream, KeyDictionary &dict, const SampleKey *timestamp_key, o output_fields); - - void write(SampleRecord const &sample) override; - -private: - vector keys; - shared_ptr stream; - const SampleKey *timestamp_key; -}; - -class SqlSampleOutputStream : public SampleOutputStream { -public: - SqlSampleOutputStream(shared_ptr stream, KeyDictionary &dict, string table_name); - - void write(SampleRecord const &sample) override; - -private: - KeyDictionary &dict; - shared_ptr stream; - const string table_name; -}; - -class SampleStreamParser { -public: - // TODO: return number of samples found for progress indication? - virtual void process(mutable_buffers_1 buffer) = 0; - - virtual sample_format_type type() { - return type_; - } - -protected: - sample_format_type type_; - - SampleStreamParser(const sample_format_type type) : type_(type) { - } -}; - -class KeyValueSampleStreamParser : public SampleStreamParser { - -public: - KeyValueSampleStreamParser(shared_ptr output, KeyDictionary &dict) : - SampleStreamParser(sample_format_type::CSV), output(output), dict(dict), - line(make_shared>()) { - } - - void process(mutable_buffers_1 buffer) override; - -private: - void process_line(shared_ptr> packet); - - static const uint8_t packet_delimiter = '\n'; - KeyDictionary &dict; - shared_ptr output; - shared_ptr> line; -}; - -class AutoSampleParser : public SampleStreamParser { -public: - AutoSampleParser(shared_ptr output, KeyDictionary &dict); - -private: - unique_ptr parser; - unique_ptr keyValueParser; -public: - virtual void process(mutable_buffers_1 buffer); -}; - -} -} - -#endif diff --git a/sensor/include/trygvis/SensorSample.h b/sensor/include/trygvis/SensorSample.h new file mode 100644 index 0000000..438e2ae --- /dev/null +++ b/sensor/include/trygvis/SensorSample.h @@ -0,0 +1,423 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace trygvis { +namespace sensor { + +using namespace std; +using namespace boost::asio; + +template +using o = boost::optional; + +enum class sample_format_type { + AUTO, + CSV, + KEY_VALUE, + JSON, + SQL, + RRD, +}; + +string to_string(const sample_format_type &arg); + +std::ostream& operator<<(std::ostream& os, sample_format_type const& type); + +std::istream& operator>>(std::istream& is, sample_format_type& type); + +class SampleStreamParser; + +class SampleOutputStream; + +class KeyDictionary; + +class SampleKey; + +// TODO: rename to open_sample_stream_parser +unique_ptr open_sample_input_stream( + shared_ptr output, + KeyDictionary &dict, + sample_format_type type = sample_format_type::AUTO); + +class sample_output_stream_option { +public: + virtual ~sample_output_stream_option() { + }; +}; + +class output_fields : public sample_output_stream_option { +public: +// output_fields() { +// } +// +// output_fields(std::vector::iterator begin, std::vector::iterator end) : +// fields(begin, end) { +// } + + ~output_fields() { + } + + vector fields; +}; + + +class timestamp_field : public sample_output_stream_option { +public: + timestamp_field(string name) : name(name) { + } + + ~timestamp_field() { + } + + string name; +}; + +unique_ptr open_sample_output_stream( + shared_ptr output, + KeyDictionary &dict, + sample_format_type type, + vector options); + +static inline +unique_ptr open_sample_output_stream( + shared_ptr output, + KeyDictionary &dict, + sample_format_type type) { + return open_sample_output_stream(output, dict, type); +} + +class ThreadSafeSampleOutputStream; + +static inline +unique_ptr thread_safe_sample_output_stream(unique_ptr underlying) { + return make_unique(move(underlying)); +}; + +class sample_exception : public runtime_error { +public: + sample_exception(const string &what) : runtime_error(what) { + } +}; + +class KeyDictionary; + +using SampleKeyVector = vector; +using SampleKeyIndex = SampleKeyVector::size_type; + +struct SampleKey { +private: + SampleKey(const SampleKey& that) = delete; + SampleKey(SampleKeyIndex index, const string &name) : index(index), name(name) { + if (name.length() == 0) { + throw sample_exception("Bad sample key."); + } + } + +public: + friend class KeyDictionary; + + inline + bool operator==(const SampleKey &that) const { + return name == that.name; + } + + const SampleKeyIndex index; + const string name; +}; + +class KeyDictionary { +public: + KeyDictionary() { + } + + ~KeyDictionary() { + std::for_each(keys.begin(), keys.end(), std::default_delete()); + } + KeyDictionary(KeyDictionary& that) = delete; + + SampleKey *indexOf(const string key) { + SampleKeyIndex i = 0; + for (auto ptr = keys.cbegin(); ptr != keys.cend(); ptr++, i++) { + if ((*ptr)->name == key) { + return *ptr; + } + } + + i = keys.size(); + auto sample_key = new SampleKey(i, key); + keys.push_back(sample_key); + + return sample_key; + } + + SampleKey *at(SampleKeyIndex i) const { + if (i >= keys.size()) { + throw sample_exception("Out of bounds"); + } + + return keys.at(i); + } + + vector findIndexes(SampleKeyVector &keys) { + vector indexes; + + for (auto &key: keys) { + auto index = indexOf(key->name); + indexes.push_back(index); + } + + return indexes; + } + + inline + SampleKeyVector::const_iterator end() const { + return keys.cend(); + } + + inline + SampleKeyVector::const_iterator begin() const { + return keys.cbegin(); + } + +// string nameOf(SampleKeyIndex index) { +// return keys.at(index).name; +// } + + inline + SampleKeyVector::size_type size() const { + return keys.size(); + } + + inline + bool empty() const { + return keys.empty(); + } + +private: + SampleKeyVector keys; +}; + +class SampleRecord { +public: + typedef vector> vec; + + SampleRecord(KeyDictionary &dict) : dict(dict) { + } + + SampleRecord(KeyDictionary &dict, vec values) + : dict(dict), values(values) { + } + + inline + vec::const_iterator cbegin() const { + return values.cbegin(); + } + + inline + vec::const_iterator cend() const { + return values.cend(); + } + + inline + bool empty() const { + return values.empty(); + } + + const o at(const SampleKey *key) const { + SampleKeyIndex index = key->index; + if (index >= values.size()) { + return o(); + } + + return values.at(index); + } + + void set(const SampleKey *key, const std::string &value) { + values.resize(max(values.size(), key->index + 1)); + + values.at(key->index).reset(value); + } + + template + const o lexical_at(const SampleKey *key) const { + auto value = at(key); + + if (!value) { + return o(); + } + + return o(boost::lexical_cast(value.get())); + } + + string to_string() const { + SampleKeyIndex i = 0; + string s; + for (auto ptr = values.begin(); ptr != values.end(); ptr++, i++) { + auto o = *ptr; + + if (!o) { + continue; + } + + auto value = o.get(); + + s += dict.at(i)->name + " = " + value + ", "; + } + return s; + } + + KeyDictionary &dict; +private: + vec values; +}; + +class SampleOutputStream { +public: + virtual void write(SampleRecord const &sample) = 0; +}; + +class VectorSampleOutputStream : public SampleOutputStream { + +public: + virtual void write(SampleRecord const &sample) override; + +public: + vector samples; +}; + +class ThreadSafeSampleOutputStream : public SampleOutputStream { +public: + ThreadSafeSampleOutputStream(unique_ptr underlying); + + ~ThreadSafeSampleOutputStream() { + } + + void write(SampleRecord const &sample) override; + +private: + unique_ptr underlying; + std::mutex mutex; +}; + +class CsvSampleOutputStream : public SampleOutputStream { +public: + CsvSampleOutputStream(shared_ptr stream, KeyDictionary &dict); + + void write(SampleRecord const &sample); + + const KeyDictionary &getDict() { + return dict; + } + +private: + void writeHeader(); + + KeyDictionary &dict; + shared_ptr stream; + bool headerWritten; +}; + +class JsonSampleOutputStream : public SampleOutputStream { +public: + JsonSampleOutputStream(shared_ptr stream, KeyDictionary &dict); + + void write(SampleRecord const &sample) override; + +private: + KeyDictionary &dict; + shared_ptr stream; +}; + +class KeyValueSampleOutputStream : public SampleOutputStream { +public: + KeyValueSampleOutputStream(shared_ptr stream, KeyDictionary &dict); + + void write(SampleRecord const &sample) override; + +private: + KeyDictionary &dict; + shared_ptr stream; +}; + +class RrdSampleOutputStream : public SampleOutputStream { +public: + RrdSampleOutputStream(shared_ptr stream, KeyDictionary &dict, const SampleKey *timestamp_key, o output_fields); + + void write(SampleRecord const &sample) override; + +private: + vector keys; + shared_ptr stream; + const SampleKey *timestamp_key; +}; + +class SqlSampleOutputStream : public SampleOutputStream { +public: + SqlSampleOutputStream(shared_ptr stream, KeyDictionary &dict, string table_name); + + void write(SampleRecord const &sample) override; + +private: + KeyDictionary &dict; + shared_ptr stream; + const string table_name; +}; + +class SampleStreamParser { +public: + // TODO: return number of samples found for progress indication? + virtual void process(mutable_buffers_1 buffer) = 0; + + virtual sample_format_type type() { + return type_; + } + +protected: + sample_format_type type_; + + SampleStreamParser(const sample_format_type type) : type_(type) { + } +}; + +class KeyValueSampleStreamParser : public SampleStreamParser { + +public: + KeyValueSampleStreamParser(shared_ptr output, KeyDictionary &dict) : + SampleStreamParser(sample_format_type::CSV), output(output), dict(dict), + line(make_shared>()) { + } + + void process(mutable_buffers_1 buffer) override; + +private: + void process_line(shared_ptr> packet); + + static const uint8_t packet_delimiter = '\n'; + KeyDictionary &dict; + shared_ptr output; + shared_ptr> line; +}; + +class AutoSampleParser : public SampleStreamParser { +public: + AutoSampleParser(shared_ptr output, KeyDictionary &dict); + +private: + unique_ptr parser; + unique_ptr keyValueParser; +public: + virtual void process(mutable_buffers_1 buffer); +}; + +} +} diff --git a/sensor/main/SensorSample.cpp b/sensor/main/SensorSample.cpp index 6ec6dfc..5f0e9c6 100644 --- a/sensor/main/SensorSample.cpp +++ b/sensor/main/SensorSample.cpp @@ -1,4 +1,4 @@ -#include "SensorSample.h" +#include "trygvis/SensorSample.h" #include "json.hpp" #include @@ -6,7 +6,7 @@ #include namespace trygvis { -namespace soil_moisture { +namespace sensor { using namespace std; using json = nlohmann::json; @@ -441,11 +441,9 @@ unique_ptr open_sample_output_stream( } } -//template ThreadSafeSampleOutputStream::ThreadSafeSampleOutputStream(unique_ptr underlying) : underlying(move(underlying)) { } -//template void ThreadSafeSampleOutputStream::write(SampleRecord const &sample) { std::unique_lock lock(mutex); -- cgit v1.2.3