diff --git a/CMakeLists.txt b/CMakeLists.txt index 18a0722..1a270e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,8 +3,7 @@ # # SPDX-License-Identifier: MIT -# Works with 3.11 and tested through 3.15 (not tested yet) -cmake_minimum_required(VERSION 3.11...3.15) +cmake_minimum_required(VERSION 3.14) project(CLIPPy @@ -39,41 +38,57 @@ if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME) endif() endif() - # -# Nlohmann JSON +# Threads +find_package(Threads REQUIRED) + # -include(ExternalProject) -ExternalProject_Add(nlohmann_json - URL https://github.com/nlohmann/json/releases/download/v3.9.1/json.hpp - DOWNLOAD_NO_EXTRACT 1 - LOG_DOWNLOAD 1 - DOWNLOAD_DIR nlohmann_json/include/nlohmann/ - BUILD_COMMAND "" - INSTALL_COMMAND "" - CONFIGURE_COMMAND "" - ) -set(NLOHMANN_JSON_INCLUDE_DIR ${PROJECT_BINARY_DIR}/nlohmann_json/include) +# Boost +find_package(Boost 1.75 REQUIRED) # # Metall -#set(METALL_WORK_DIR ${CMAKE_CURRENT_BINARY_DIR}/metall-work) -set(METALL_SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/metall-src) -set(METALL_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/metall-build) -set(METALL_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/metall-install) -ExternalProject_Add(metall +find_package(Metall QUIET) +if (Metall_FOUND) + message(STATUS "Found Metall") +else () + message(STATUS "Could NOT find Metall locally. Download Metall.") + include(FetchContent) + FetchContent_Declare( + Metall GIT_REPOSITORY https://github.com/LLNL/metall.git - GIT_TAG master - SOURCE_DIR ${METALL_SOURCE_DIR} - BINARY_DIR ${METALL_BUILD_DIR} - CMAKE_ARGS -DINSTALL_HEADER_ONLY=ON -DCMAKE_INSTALL_PREFIX=${METALL_INSTALL_DIR} + GIT_TAG develop ) -set(METALL_INCLUDE_DIR ${METALL_INSTALL_DIR}/include) -find_package(Threads REQUIRED) + FetchContent_MakeAvailable(Metall) +endif () # -# Boost -find_package(Boost 1.75 REQUIRED COMPONENTS) +# cereal +FetchContent_Declare(cereal + URL https://github.com/USCiLab/cereal/archive/refs/tags/v1.3.0.zip + ) +FetchContent_GetProperties(cereal) +if (NOT cereal_POPULATED) + FetchContent_Populate(cereal) +endif () +set(cereal_INCLUDE_DIR "${cereal_SOURCE_DIR}/include") + +# +# MPI +find_package(MPI) + +# +# YGM +if (MPI_CXX_FOUND) + FetchContent_Declare(YGM + URL https://github.com/LLNL/ygm/archive/refs/heads/master.zip + ) + FetchContent_GetProperties(YGM) + if (NOT ygm_POPULATED) + FetchContent_Populate(YGM) + endif () + set(YGM_INCLUDE_DIR "${ygm_SOURCE_DIR}/include") +endif () ### Require out-of-source builds file(TO_CMAKE_PATH "${PROJECT_BINARY_DIR}/CMakeLists.txt" LOC_PATH) diff --git a/examples/dataframe/CMakeLists.txt b/examples/dataframe/CMakeLists.txt index 1583e27..fa52987 100644 --- a/examples/dataframe/CMakeLists.txt +++ b/examples/dataframe/CMakeLists.txt @@ -8,15 +8,15 @@ function ( add_df_example example_name ) target_link_libraries(${example_name} PRIVATE libcliprt) endfunction() -include_directories(${Boost_INCLUDE_DIRS}) +include_directories(${Boost_INCLUDE_DIRS}) add_library(libcliprt STATIC clip) target_link_libraries(libcliprt PUBLIC ${Boost_LIBRARIES}) -add_df_example(columninfo) +add_df_example(metadataquery) add_df_example(columnquery) add_df_example(create) -add_df_example(datafind) +add_df_example(extreme) add_df_example(importCSV) add_df_example(rowquery) diff --git a/examples/dataframe/clip.cpp b/examples/dataframe/clip.cpp index 9544a15..a2f0c72 100644 --- a/examples/dataframe/clip.cpp +++ b/examples/dataframe/clip.cpp @@ -1,13 +1,14 @@ #include #include +#include #include "clip.hpp" + #include namespace boostjsn = boost::json; - void resultOK(std::ostream& os, const std::string& msg) { os << "{\n \"text\": \"OK\""; @@ -52,7 +53,7 @@ pretty_print(std::ostream& os, boostjsn::value const& jv, std::string& indent) os << indent << "}"; break; } - + case boostjsn::kind::array: { os << "[\n"; @@ -75,37 +76,37 @@ pretty_print(std::ostream& os, boostjsn::value const& jv, std::string& indent) os << indent << "]"; break; } - + case boostjsn::kind::string: { os << boostjsn::serialize(jv.get_string()); break; } - + case boostjsn::kind::uint64: os << jv.get_uint64(); break; - + case boostjsn::kind::int64: os << jv.get_int64(); break; - + case boostjsn::kind::double_: os << jv.get_double(); break; - + case boostjsn::kind::bool_: if(jv.get_bool()) os << "true"; else os << "false"; break; - + case boostjsn::kind::null: os << "null"; break; } - + if(indent.empty()) os << "\n"; } @@ -117,20 +118,20 @@ parseFile(std::istream& inps) { boostjsn::stream_parser p; std::string line; - + while (inps >> line) { boostjsn::error_code ec; - + p.write(line.c_str(), line.size(), ec); - + if (ec) return nullptr; - } - + } + boostjsn::error_code ec; p.finish(ec); if (ec) return nullptr; - + return p.release(); } @@ -138,7 +139,7 @@ boostjsn::value parseFile(const std::string& filename) { std::ifstream is{filename}; - + return parseFile(is); } @@ -146,7 +147,7 @@ void prettyPrint(std::ostream& os, const boostjsn::value& jv) { std::string indent; - + pretty_print(os, jv, indent); } @@ -154,7 +155,7 @@ void prettyPrint(const boostjsn::value& jv) { std::ofstream os{"jsonin.log"}; - + prettyPrint(os, jv); } @@ -164,7 +165,7 @@ try const boostjsn::object& argsobj = args.as_object(); boostjsn::object::const_iterator pos = argsobj.find(key); if (pos == argsobj.end()) return; - + name = pos->value().as_string().c_str(); } catch (const std::invalid_argument&) {} @@ -175,7 +176,7 @@ try const boostjsn::object& argsobj = args.as_object(); boostjsn::object::const_iterator pos = argsobj.find(key); if (pos == argsobj.end()) return; - + val = pos->value().as_int64(); } catch (const std::invalid_argument&) {} @@ -186,12 +187,25 @@ int columnIndex(const std::vector& all, const std::string& colname) std::vector::const_iterator aa = all.begin(); std::vector::const_iterator zz = all.end(); std::vector::const_iterator pos = std::find(aa, all.end(), colname); - - clippy_assert(pos != zz, "Column name not found: " + colname); + + clippy_assert(pos != zz, "Column name not found: " + colname); return std::distance(aa, pos); } -bool fail(const std::string& msg) +bool fail( const std::string& msg +#if __cpp_lib_source_location + , std::source_location pos = std::source_location::current() +#endif /* __cpp_lib_source_location */ + ) { - clippy_assert(false, msg); + std::stringstream errmsg; + + errmsg << msg +#if __cpp_lib_source_location + << " @ " << pos.file_name + << " : " << pos.line +#endif /* __cpp_lib_source_location */ + ; + + throw std::logic_error{errmsg.str()}; } diff --git a/examples/dataframe/clip.hpp b/examples/dataframe/clip.hpp index cbbd9fc..fee3cae 100644 --- a/examples/dataframe/clip.hpp +++ b/examples/dataframe/clip.hpp @@ -4,16 +4,17 @@ #include #include #include -#include #if defined __has_include #if __has_include () - #include + #include #endif #endif /* defined __has_include */ #include +#include "experimental/cxx-compat.hpp" + constexpr const bool firstMatch = false; void resultOK(std::ostream& os, const std::string& msg = {}); @@ -30,11 +31,15 @@ void setValueIfAvail(const boost::json::value& args, const char* key, int& val); int columnIndex(const std::vector& all, const std::string& colname); -bool fail(const std::string& msg); +CXX_NORETURN +bool fail( const std::string& msg +#if __cpp_lib_source_location + , std::source_location pos = std::source_location::current() +#endif /* __cpp_lib_source_location */ + ); namespace { - template inline void clippy_assert( bool cond , const std::string& msg @@ -43,17 +48,12 @@ namespace #endif /* __cpp_lib_source_location */ ) { - if (cond) return; + if (cond) { CXX_LIKELY; return; } - std::stringstream errmsg; - - errmsg << msg + fail( msg #if __cpp_lib_source_location - << " @ " << pos.file_name - << " : " << pos.line + , pos #endif /* __cpp_lib_source_location */ - ; - - throw EX{errmsg.str()}; + ); } } diff --git a/examples/dataframe/datafind.cpp b/examples/dataframe/extreme.cpp similarity index 93% rename from examples/dataframe/datafind.cpp rename to examples/dataframe/extreme.cpp index 60ad34c..21107f7 100644 --- a/examples/dataframe/datafind.cpp +++ b/examples/dataframe/extreme.cpp @@ -12,7 +12,7 @@ namespace boostjsn = boost::json; namespace xpr = experimental; -const char* const METHOD_NAME = "datafind"; +const char* const METHOD_NAME = "extreme"; const char* const ARG_METALL_LOCATION = "metall_location"; const char* const ARG_DATAFRAME_KEY = "dataframe_key"; const char* const ARG_CRITERIA_FUN = "function"; @@ -27,16 +27,16 @@ void apiJason(std::ostream& out) << " \"method_name\": \"" << METHOD_NAME << "\",\n" << " \"args\":\n" << " {\n"; - + //~ << " \"" << ARG_METALL_INIT << "\": { \"desc\": \"create or connect\", \"position\":0, \"required\":true, \"type\":\"string\"}\n" out << " \"" << ARG_METALL_LOCATION << "\": { \"desc\": \"location of metall file\", \"position\":" << (pos++) << ", \"required\":true, \"type\":\"string\"},\n"; - + out << " \"" << ARG_DATAFRAME_KEY << "\": { \"desc\": \"dataframe name\", \"position\":" << (pos++) << ", \"required\":true, \"type\":\"string\"},\n"; - + out << " \"" << ARG_CRITERIA_COL << "\": { \"desc\": \"column where the criteria shall be applied\", \"position\":" << (pos++) << ", \"required\":false, \"type\":\"int\"},\n"; - + out << " \"" << ARG_CRITERIA_FUN << "\": { \"desc\": \"criteria (min, max)\", \"position\":" << (pos++) << ", \"required\":false, \"type\":\"int\"}\n"; - + out << " },\n" << " \"returns\": { \"desc\": \"status\", \"type\":\"string\"}\n" << "}\n" @@ -52,10 +52,10 @@ struct ConverterFn xpr::dataframe_variant_t operator()(const std::string& s) { DfCellType elem = boost::lexical_cast(s); - - return elem; + + return elem; } - + xpr::DataFrame* df; }; @@ -73,21 +73,21 @@ bool applyColFunctionIf(std::ostream& os, xpr::DataFrame& df, size_t colnum, const xpr::ColumnDesc& desc, const std::string& funname) { using Iterator = xpr::AnyColumnIterator; - + if (desc.column_type != xpr::to_string(xpr::tag())) return false; - + std::pair range = df.get_any_column(colnum); std::string quotes = quote(xpr::tag()); - + Iterator pos = (funname == "min") ? std::min_element(range.first, range.second) : std::max_element(range.first, range.second) ; - - os << "{ \"id\": " << pos.row() << ", \"value\": " << quotes << *pos << quotes - << "}" + + os << "{ \"id\": " << pos.row() << ", \"value\": " << quotes << *pos << quotes + << "}" << std::endl; - + return true; } @@ -98,7 +98,7 @@ void columnFunction(std::ostream& os, xpr::DataFrame& df, int colnum, const xpr: || applyColFunctionIf (os, df, colnum, desc, funname) || applyColFunctionIf (os, df, colnum, desc, funname) || applyColFunctionIf(os, df, colnum, desc, funname) - || fail("internal error: unexpected column type" + desc.column_type); + || fail("internal error: unexpected column type" + desc.column_type); } @@ -113,31 +113,31 @@ int main(int argc, char** argv) apiJason(std::cout); return 0; } - + boostjsn::value input = parseFile(std::cin); - + try - { + { const bool make_new_partition = false; std::string persistent_location; std::string dataframe_key; std::string funname; std::string colname; - + setValueIfAvail(input, ARG_METALL_LOCATION, persistent_location); setValueIfAvail(input, ARG_DATAFRAME_KEY, dataframe_key); setValueIfAvail(input, ARG_CRITERIA_COL, colname); setValueIfAvail(input, ARG_CRITERIA_FUN, funname); - - clippy_assert(funname == "min" || funname == "max", std::string{"Invalid filter function name: "} + funname); + + clippy_assert(funname == "min" || funname == "max", std::string{"Invalid filter function name: "} + funname); std::unique_ptr dfp = makeDataFrame(make_new_partition, persistent_location, dataframe_key); xpr::DataFrame& df = *dfp; int col = columnIndex(df.get_column_names(), colname); std::vector colDescs = df.get_column_descriptors(std::vector{col}); - + clippy_assert(colDescs.size() == 1, "internal error: unexpected number of columns"); - + columnFunction(std::cout, df, col, colDescs.front(), funname); } catch (const std::exception& err) diff --git a/examples/dataframe/columninfo.cpp b/examples/dataframe/metadataquery.cpp similarity index 98% rename from examples/dataframe/columninfo.cpp rename to examples/dataframe/metadataquery.cpp index 26dc357..9b89ac0 100644 --- a/examples/dataframe/columninfo.cpp +++ b/examples/dataframe/metadataquery.cpp @@ -17,7 +17,7 @@ namespace boostjsn = boost::json; namespace xpr = experimental; -const char* const METHOD_NAME = "columnInfo"; +const char* const METHOD_NAME = "metadataquery"; const char* const ARG_METALL_LOCATION = "metall_location"; const char* const ARG_DATAFRAME_KEY = "dataframe_key"; diff --git a/include/experimental/csv-io.hpp b/include/experimental/csv-io.hpp index 30bfc6e..81eb6c9 100644 --- a/include/experimental/csv-io.hpp +++ b/include/experimental/csv-io.hpp @@ -206,7 +206,6 @@ void writeLn(std::ostream& os, std::tuple&& rec, std::index_sequence auto importCSV(DataFrame& frame, std::istream& is) { diff --git a/include/experimental/cxx-compat.hpp b/include/experimental/cxx-compat.hpp new file mode 100644 index 0000000..f960f35 --- /dev/null +++ b/include/experimental/cxx-compat.hpp @@ -0,0 +1,83 @@ +#pragma once + +#if __cplusplus >= 202002L + +#if __has_cpp_attribute(carries_dependency) +#define CXX_CARRIES_DEPENDENCY [[carries_dependency]] +#endif + +#if __has_cpp_attribute(deprecated) +#define CXX_DEPRECATED [[deprecated]] +#endif + +#if __has_cpp_attribute(fallthrough) +#define CXX_FALLTHROUGH [[fallthrough]] +#endif + +#if __has_cpp_attribute(likely) +#define CXX_LIKELY [[likely]] +#endif + +#if __has_cpp_attribute(maybe_unused) +#define CXX_MAYBE_UNUSED [[maybe_unused]] +#endif + +#if __has_cpp_attribute(no_unique_address) +#define CXX_NO_UNIQUE_ADDRESS [[no_unique_address]] +#endif + +#if __has_cpp_attribute(nodiscard) +#define CXX_NODISCARD [[nodiscard]] +#endif + +#if __has_cpp_attribute(noreturn) +#define CXX_NORETURN [[noreturn]] +#endif + +#if __has_cpp_attribute(unlikely) +#define CXX_UNLIKELY [[unlikely]] +#endif + +#endif /* C++20 */ + + +#ifndef CXX_CARRIES_DEPENDENCY +#define CXX_CARRIES_DEPENDENCY +#endif + +#ifndef CXX_DEPRECATED +#define CXX_DEPRECATED +#endif + +#ifndef CXX_FALLTHROUGH +#define CXX_FALLTHROUGH +#endif + +#ifndef CXX_LIKELY +#define CXX_LIKELY +#endif + +#ifndef CXX_MAYBE_UNUSED +#define CXX_MAYBE_UNUSED +#endif + +#ifndef CXX_NO_UNIQUE_ADDRESS +#define CXX_NO_UNIQUE_ADDRESS +#endif + +#ifndef CXX_NODISCARD +#define CXX_NODISCARD +#endif + +#ifndef CXX_NORETURN +#define CXX_NORETURN +#endif + +#ifndef CXX_UNLIKELY +#define CXX_UNLIKELY +#endif + + + + + diff --git a/include/experimental/dataframe.hpp b/include/experimental/dataframe.hpp index 57c62f6..9666ff2 100644 --- a/include/experimental/dataframe.hpp +++ b/include/experimental/dataframe.hpp @@ -4,12 +4,10 @@ #include #include #include -// #include #include +// #include //~ #include -//~ - #include #include #include @@ -18,29 +16,29 @@ #include "metall/tags.hpp" #include "experimental/flat_map.hpp" -#include "experimental/compat.hpp" +#include "experimental/cxx-compat.hpp" namespace experimental { - -//~ using string_t = std::string; -using string_t = boost::container::string; -using int_t = int64_t; -using uint_t = uint64_t; -using real_t = double; -using dataframe_variant_t = std::variant; - -struct runtime_type_error : std::runtime_error + +//~ using string_t = std::string; +using string_t = boost::container::string; +using int_t = int64_t; +using uint_t = uint64_t; +using real_t = double; +using dataframe_variant_t = std::variant; + +struct runtime_type_error : std::runtime_error { using base = std::runtime_error; using base::base; }; -struct unknown_column_error : std::runtime_error +struct unknown_column_error : std::runtime_error { using base = std::runtime_error; using base::base; -}; +}; template @@ -50,14 +48,14 @@ struct DefaultValue { defaultval = std::move(val); } - + const T& default_value() const { return defaultval; } - + private: - T defaultval; + T defaultval; }; template < class KeyT, @@ -93,17 +91,17 @@ template < class ValT, template class Vector = boost::container::vector > struct dense_column : Vector, DefaultValue -{ +{ using defvalbase = DefaultValue; using base = Vector; using allocator_type = typename base::allocator_type; using value_type = typename base::value_type; - + explicit dense_column(const allocator_type& alloc) : base(alloc), defvalbase() - {} -}; + {} +}; template using dense_vector_t = dense_column>; @@ -120,15 +118,15 @@ inline void errTypeMismatch(std::string cell = {}, std::string xpct = {}) { std::string err{"type mismatch:"}; - + if (cell.size()) (err += " got ") += cell; if (xpct.size()) (err += " expected ") += xpct; - + throw runtime_type_error(err); -} +} template -constexpr +constexpr const T* tag() { return nullptr; } } // anonymous namespace @@ -137,7 +135,7 @@ template struct AbstractColumnIterator { using value_type = ElemType; - + virtual ~AbstractColumnIterator() {} virtual value_type& deref() = 0; virtual size_t row() const = 0; @@ -147,86 +145,86 @@ struct AbstractColumnIterator virtual AbstractColumnIterator* clone() const = 0; }; -namespace +namespace { template -struct DenseColumnIterator : AbstractColumnIterator +struct DenseColumnIterator : AbstractColumnIterator { using base = AbstractColumnIterator; using ThisType = DenseColumnIterator; using value_type = typename base::value_type; using VectorRep = dense_vector_t; using Iterator = typename VectorRep::iterator; - + DenseColumnIterator(Iterator pos, size_t rowcnt) : base(), it(pos), rownum(rowcnt) {} - + value_type& deref() override { return *(this->it); } size_t row() const override { return this->rownum; } - void next() override { ++(this->it); ++(this->rownum); } - void prev() override { --(this->it); --(this->rownum); } - + void next() override { ++(this->it); ++(this->rownum); } + void prev() override { --(this->it); --(this->rownum); } + bool equals(const base& other) const override { assert(typeid(*this) == typeid(other)); - + const ThisType& rhs = static_cast(other); - + return this->it == rhs.it; // equal rownum is implied by equal iterators } - - ThisType* clone() const override + + ThisType* clone() const override { return new ThisType(it, rownum); } - + private: Iterator it; size_t rownum; }; template -struct SparseColumnIterator : AbstractColumnIterator +struct SparseColumnIterator : AbstractColumnIterator { using base = AbstractColumnIterator; using ThisType = SparseColumnIterator; using value_type = typename base::value_type; using VectorRep = sparse_vector_t; using Iterator = typename VectorRep::iterator; - + SparseColumnIterator(Iterator pos) : base(), it(pos) {} - + value_type& deref() override { return this->it->second; } size_t row() const override { return this->it->first; } - void next() override { ++(this->it); } - void prev() override { --(this->it); } - + void next() override { ++(this->it); } + void prev() override { --(this->it); } + bool equals(const base& other) const override { assert(typeid(*this) == typeid(other)); - + const ThisType& rhs = static_cast(other); - + return this->it == rhs.it; // equal rownum is implied by equal iterators } - - ThisType* clone() const override + + ThisType* clone() const override { return new ThisType(it); } - + private: Iterator it; }; -const std::string string_type_str{"string_t"}; -const std::string int_type_str{"int_t"}; -const std::string uint_type_str{"uint_t"}; -const std::string real_type_str{"real_t"}; +const std::string string_type_str{"string_t"}; +const std::string int_type_str{"int_t"}; +const std::string uint_type_str{"uint_t"}; +const std::string real_type_str{"real_t"}; inline std::string to_string(const string_t*) { return string_type_str; } inline std::string to_string(const int_t*) { return int_type_str; } @@ -234,15 +232,15 @@ inline std::string to_string(const uint_t*) { return uint_type_str; } inline std::string to_string(const real_t*) { return real_type_str; } template -inline std::string to_string(const T*) -{ - return std::string{"unknown type; mangled name is: "} + typeid(T).name(); +inline std::string to_string(const T*) +{ + return std::string{"unknown type; mangled name is: "} + typeid(T).name(); } } // anonymous namespace template -struct AnyColumnIterator +struct AnyColumnIterator { using iterator_category = std::bidirectional_iterator_tag; using value_type = T; @@ -250,73 +248,73 @@ struct AnyColumnIterator using pointer = value_type*; using reference = value_type&; using ThisType = AnyColumnIterator; - + explicit AnyColumnIterator(AbstractColumnIterator* obj) : pit(obj) {} - + explicit AnyColumnIterator(typename dense_vector_t::iterator it, size_t pos) : AnyColumnIterator(new DenseColumnIterator(it, pos)) {} - + explicit AnyColumnIterator(typename sparse_vector_t::iterator it) : AnyColumnIterator(new SparseColumnIterator(it)) {} - + AnyColumnIterator(const AnyColumnIterator& other) : AnyColumnIterator(other.pit->clone()) {} - + AnyColumnIterator(AnyColumnIterator&& other) : AnyColumnIterator(other.pit) { other.pit = nullptr; } - + AnyColumnIterator& operator=(const AnyColumnIterator& other) { AnyColumnIterator tmp(other.pit->clone()); - + std::swap(tmp.pit, this->pit); return *this; } - + AnyColumnIterator& operator=(AnyColumnIterator&& other) { std::swap(other.pit, this->pit); return *this; } - + ~AnyColumnIterator() { delete pit; } - + T& operator*() { return pit->deref(); } size_t row() const { return pit->row(); } ThisType& operator++() { pit->next(); return *this; } - - ThisType operator++(int) - { + + ThisType operator++(int) + { ThisType res{pit->clone()}; - - pit->next(); - return *this; + + pit->next(); + return *this; } ThisType& operator--() { pit->prev(); return *this; } - - ThisType operator--(int) - { + + ThisType operator--(int) + { ThisType res{pit->clone()}; - - pit->prev(); - return *this; + + pit->prev(); + return *this; } - + bool operator==(AnyColumnIterator& that) const { if (pit == nullptr || that.pit == nullptr) @@ -324,12 +322,12 @@ struct AnyColumnIterator return pit->equals(*(that.pit)); } - + bool operator!=(AnyColumnIterator& that) const { return !(*this == that); } - + private: AbstractColumnIterator* pit; }; @@ -337,80 +335,80 @@ struct AnyColumnIterator namespace { -#if OBSOLETE_CODE -struct VectorAccessorRuntimeInfo + +/// interface for diagnostics +struct VectorAccessorRuntimeInfo { - virtual - std::string type_name() const = 0; + /// returns the type of the element + virtual std::string type_name() const = 0; }; -#endif /* OBSOLETE_CODE */ -/// define operations on columns. +/// define operations on columns. template -struct VectorAccessorBaseT // : VectorAccessorRuntimeInfo +struct VectorAccessorBaseT : virtual VectorAccessorRuntimeInfo { using entry_type = std::pair; - - virtual - dense_vector_t& data(void* /*cont*/, const dense_vector_t* /*tag*/) const - { - errTypeMismatch(type_name(), to_string(tag())); + + virtual + dense_vector_t& data(void* /*cont*/, const dense_vector_t* /*tag*/) const + { + errTypeMismatch(type_name(), to_string(tag())); } - - virtual - sparse_vector_t& data(void* /*cont*/, const sparse_vector_t* /*tag*/) const - { - errTypeMismatch(type_name(), to_string(tag())); + + virtual + sparse_vector_t& data(void* /*cont*/, const sparse_vector_t* /*tag*/) const + { + errTypeMismatch(type_name(), to_string(tag())); } - - virtual - T* at(void* /*cont*/, size_t /*pos*/, const T* /*tag*/) const - { - errTypeMismatch(type_name(), to_string(tag())); + + virtual + T* at(void* /*cont*/, size_t /*pos*/, const T* /*tag*/) const + { + errTypeMismatch(type_name(), to_string(tag())); } - - virtual - const T& default_value(void* /*cont*/, const T* /*tag*/) const - { - errTypeMismatch(type_name(), to_string(tag())); + + virtual + const T& default_value(void* /*cont*/, const T* /*tag*/) const + { + errTypeMismatch(type_name(), to_string(tag())); } - - virtual - T& cell(void* /*cont*/, size_t /*pos*/, const T* /*tag*/) const - { - errTypeMismatch(type_name(), to_string(tag())); + + virtual + T& cell(void* /*cont*/, size_t /*pos*/, const T* /*tag*/) const + { + errTypeMismatch(type_name(), to_string(tag())); } - - virtual - void add(void* /*cont*/, T&&) const - { - errTypeMismatch(type_name(), to_string(tag())); + + virtual + void add(void* /*cont*/, T&&) const + { + errTypeMismatch(type_name(), to_string(tag())); + } + + virtual + std::pair, AnyColumnIterator > + range(void* /*cont*/, const T*) const + { + errTypeMismatch(type_name(), typeid(T).name()); } - - virtual - std::pair, AnyColumnIterator > - range(void* /*cont*/, const T*) const - { - errTypeMismatch(type_name(), typeid(T).name()); - } }; // define the column types struct VectorAccessorBase : VectorAccessorBaseT , VectorAccessorBaseT - , VectorAccessorBaseT + , VectorAccessorBaseT , VectorAccessorBaseT { // // variant based types using value_variant_t = dataframe_variant_t; using pointer_variant_t = std::variant; - using const_reference_variant_t = std::variant; - using iterator_variant_t = std::variant< dense_vector_t::iterator, sparse_vector_t::iterator, - dense_vector_t::iterator, sparse_vector_t::iterator, - dense_vector_t::iterator, sparse_vector_t::iterator, - dense_vector_t::iterator, sparse_vector_t::iterator, + //~ using const_reference_variant_t = std::variant; + using iterator_variant_t = std::variant< dense_vector_t::iterator, sparse_vector_t::iterator + , dense_vector_t::iterator, sparse_vector_t::iterator + , dense_vector_t::iterator, sparse_vector_t::iterator + , dense_vector_t::iterator, sparse_vector_t::iterator >; using range_variant_t = std::pair; @@ -419,21 +417,19 @@ struct VectorAccessorBase : VectorAccessorBaseT /// returns true iff this is a sparse column virtual bool is_sparse() const = 0; - + /// writes back any data held in volatile memory virtual void persist(void* /*cont*/) const = 0; - /// returns the type of the element - virtual std::string type_name() const override = 0; - // // variant-based abstract API - + /// returns a pointer to an element at \ref pos, or nullptr if the value does not exist virtual pointer_variant_t at_variant(void* cont, size_t pos) const = 0; /// returns a reference to variant with a reference to a default value - virtual const_reference_variant_t default_value_variant(void* /*cont*/) const = 0; + virtual value_variant_t default_value_variant(void* /*cont*/) const = 0; + //~ virtual const_reference_variant_t default_value_variant(void* /*cont*/) const = 0; /// returns a variant to a value at \ref pos virtual value_variant_t cell_variant(void* /*cont*/, size_t pos) const = 0; @@ -442,306 +438,417 @@ struct VectorAccessorBase : VectorAccessorBaseT virtual void add_variant(void* /*cont*/, value_variant_t&& /* value */) const = 0; /// returns an iterator pair of the column - virtual std::pair range_variant() const = 0; + virtual range_variant_t range_variant(void* /*cont*/) const = 0; }; template