diff --git a/BUILD.txt b/BUILD.txt new file mode 100644 index 0000000..75414ad --- /dev/null +++ b/BUILD.txt @@ -0,0 +1,16 @@ +Redshift: + +mkdir build && cd build +env "PATH=$HOME/src/spack-view/bin:$PATH" cmake -DCMAKE_INSTALL_PREFIX=$HOME/asdf-cxx -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -G Ninja .. + +env "PATH=$HOME/src/spack-view/bin:$PATH" cmake --build . +for lib in *.so; do install_name_tool -change '@rpath/libyaml-cpp.0.6.dylib' "$HOME/src/spack-view/lib/libyaml-cpp.0.6.2.dylib" $lib; done +for exe in ./asdf-*; do install_name_tool -change '@rpath/libyaml-cpp.0.6.dylib' "$HOME/src/spack-view/lib/libyaml-cpp.0.6.2.dylib" $exe; done + +env "PATH=$HOME/src/spack-view/bin:$PATH" "DYLD_LIBRARY_PATH=$HOME/src/spack-view/lib:$DYLD_LIBRARY_PATH" ./asdf-demo +env "PATH=$HOME/src/spack-view/bin:$PATH" "DYLD_LIBRARY_PATH=$HOME/src/spack-view/lib:$DYLD_LIBRARY_PATH" ./asdf-demo-external + +env "PATH=$HOME/src/spack-view/bin:$PATH" "DYLD_LIBRARY_PATH=$HOME/src/spack-view/lib:$DYLD_LIBRARY_PATH" "PYTHONHOME=$HOME/src/spack-view" "PYTHONPATH=$(pwd)" $HOME/src/spack-view/bin/python ../asdf-demo-python.py +env "PATH=$HOME/src/spack-view/bin:$PATH" "DYLD_LIBRARY_PATH=$HOME/src/spack-view/lib:$DYLD_LIBRARY_PATH" "PYTHONHOME=$HOME/src/spack-view" "PYTHONPATH=$(pwd)" $HOME/src/spack-view/bin/python ../asdf-demo-external-python.py + +env "PATH=$HOME/src/spack-view/bin:$PATH" cmake --build . --target install diff --git a/CMakeLists.txt b/CMakeLists.txt index f6e7e20..f5fc569 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ cmake_policy(SET CMP0048 NEW) set(CMAKE_DISABLE_IN_SOURCE_BUILD ON) set(CMAKE_DISABLE_SOURCE_CHANGES ON) -project(asdf-cxx VERSION 7.0.0 LANGUAGES CXX) +project(asdf-cxx VERSION 7.1.0 LANGUAGES CXX) set(PROJECT_DESCRIPTION "asdf-cxx (Advanced Scientific Data Format), C++ implementation") set(PROJECT_URL "https://github.com/eschnett/asdf-cxx") @@ -57,9 +57,25 @@ else() set(HAVE_ZLIB 0) endif() +set(Python_ADDITIONAL_VERSIONS 3.0) +# This sets PYTHONINTERP_FOUND +find_package(PythonInterp) +# This sets PYTHONLIBS_FOUND +find_package(PythonLibs) +if(PYTHONINTERP_FOUND AND PYTHONLIBS_FOUND) + include_directories(${PYTHON_INCLUDE_DIRS}) +endif() + +if(PYTHONINTERP_FOUND AND PYTHONLIBS_FOUND) + find_package(SWIG) +endif() +if(SWIG_FOUND) + include(${SWIG_USE_FILE}) +endif() + # Main project -set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED ON) string(REPLACE "-DNDEBUG" "" @@ -115,6 +131,14 @@ target_link_libraries(asdf-demo-large asdf-cxx ${LIBS}) add_executable(asdf-ls ls.cpp) target_link_libraries(asdf-ls asdf-cxx ${LIBS}) +# SWIG bindings + +if(PYTHONINTERP_FOUND AND PYTHONLIBS_FOUND AND SWIG_FOUND) + set_source_files_properties(asdf.i PROPERTIES CPLUSPLUS ON) + swig_add_library(asdf LANGUAGE python SOURCES asdf.i) + swig_link_libraries(asdf asdf-cxx ${LIBS} ${PYTHON_LIBRARIES}) +endif() + # Tests enable_testing() @@ -122,11 +146,28 @@ add_test(NAME demo COMMAND ./asdf-demo) add_test(NAME ls COMMAND ./asdf-ls demo.asdf) add_test(NAME copy COMMAND ./asdf-copy demo.asdf demo2.asdf) add_test(NAME ls2 COMMAND ./asdf-ls demo2.asdf) -add_test(NAME compare +add_test(NAME compare-demo COMMAND ${CMAKE_SOURCE_DIR}/diff-commands.sh - "./asdf-ls demo.asdf" "./asdf-ls demo2.asdf") + "./asdf-ls demo.asdf" "./asdf-ls demo2.asdf") add_test(NAME external COMMAND ./asdf-demo-external) +if(PYTHONINTERP_FOUND AND PYTHONLIBS_FOUND AND SWIG_FOUND) + add_test(NAME demo-python + COMMAND + env "PYTHONPATH=${PROJECT_BINARY_DIR}:$ENV{PYTHONPATH}" + ${PYTHON_EXECUTABLE} "${PROJECT_SOURCE_DIR}/asdf-demo-python.py") + add_test(NAME compare-demo-python + COMMAND ${CMAKE_SOURCE_DIR}/diff-commands.sh + "./asdf-ls demo.asdf" "./asdf-ls demo-python.asdf") + add_test(NAME demo-external-python + COMMAND + env "PYTHONPATH=${PROJECT_BINARY_DIR}:$ENV{PYTHONPATH}" + ${PYTHON_EXECUTABLE} "${PROJECT_SOURCE_DIR}/asdf-demo-external-python.py") + add_test(NAME compare-demo-external-python + COMMAND ${CMAKE_SOURCE_DIR}/diff-commands.sh + "./asdf-ls demo-external.asdf" "./asdf-ls demo-external-python.asdf") +endif() + # Coverage # We don't want this to run on every build @@ -145,6 +186,10 @@ install(FILES "${PROJECT_BINARY_DIR}/asdf_config.hpp" DESTINATION include) install(TARGETS asdf-cxx DESTINATION lib) install(TARGETS asdf-copy asdf-demo asdf-demo-external asdf-demo-large asdf-ls DESTINATION bin) +if(PYTHONINTERP_FOUND AND PYTHONLIBS_FOUND AND SWIG_FOUND) + install(PROGRAMS asdf-demo-python.py asdf-demo-external-python.py + DESTINATION bin) +endif() set(PKG_CONFIG_REQUIRES "yaml-cpp") set(PKG_CONFIG_INCLUDEDIR "\${prefix}/include") diff --git a/asdf-demo-external-python.py b/asdf-demo-external-python.py new file mode 100755 index 0000000..1c4ead0 --- /dev/null +++ b/asdf-demo-external-python.py @@ -0,0 +1,90 @@ +#! /usr/bin/env python + +from __future__ import print_function +import numpy as np + +from asdf import * + + + +def write_external(): + print("Writing external file...") + + # The actual dataset + alpha = ndarray.create_int64( + np.array([1, 2, 3], np.int64), block_format_t_inline_array, + compression_t_none, 0, np.array([]), [3]) + # A local reference + beta = reference.create_from_path("", ["group", "alpha", "data"]) + + grp = group.create( + {"alpha": entry.create_from_ndarray("alpha", alpha, ""), + "beta": entry.create_from_reference("beta", beta, "")}) + + project = asdf.create_from_group({}, grp) + project.write("external.asdf") + + + +def write_metadata(): + print("Writing metadata file...") + + # A remote reference + gamma = reference.create_from_path("external.asdf", + ["group", "alpha", "data"]) + # A local reference + delta = reference.create_from_path("", ["group", "gamma", "reference"]) + # A remote reference to a local reference + epsilon = reference.create_from_path("external.asdf", + ["group", "beta", "reference"]) + + grp = group.create( + {"gamma": entry.create_from_reference("gamma", gamma, ""), + "delta": entry.create_from_reference("delta", delta, ""), + "epsilon": entry.create_from_reference("epsilon", epsilon, "")}) + + project = asdf.create_from_group({}, grp) + project.write("metadata.asdf") + + + +def read_metadata(): + print("Reading metadata file...") + + project = asdf.read("metadata.asdf") + grp = project.get_group() + + gamma = grp.get_entries()["gamma"].get_reference() + print("gamma: <" + gamma.get_target() + ">") + rs_node = gamma.resolve() + arr = ndarray.read(rs_node) + print("gamma': [ndarray] " + str(arr.get_data_vector_int64())) + + delta = grp.get_entries()["delta"].get_reference() + print("delta: <" + delta.get_target() + ">") + rs_node = delta.resolve() + ref = reference.create_from_reader_state_node(rs_node) + print("delta': [reference] " + ref.get_target()) + rs_node1 = ref.resolve() + arr = ndarray.read(rs_node1) + print("delta'': [ndarray] " + str(arr.get_data_vector_int64())) + + epsilon = grp.get_entries()["epsilon"].get_reference() + print("epsilon: <" + epsilon.get_target() + ">") + rs_node = epsilon.resolve() + ref = reference.create_from_reader_state_node(rs_node) + print("epsilon': [reference] " + ref.get_target()) + rs_node1 = ref.resolve() + arr = ndarray.read(rs_node1) + print("epsilon'': [ndarray] " + str(arr.get_data_vector_int64())) + + + +print("asdf-demo-external-python:") +print(" Create a simple ASDF file with external references from Python") + +write_external() +write_metadata() +read_metadata() + +print("Done.") diff --git a/asdf-demo-python.py b/asdf-demo-python.py new file mode 100755 index 0000000..95e657a --- /dev/null +++ b/asdf-demo-python.py @@ -0,0 +1,68 @@ +#! /usr/bin/env python + +from __future__ import print_function +import numpy as np + +from asdf import * + +print("asdf-demo-python: Create a simple ASDF file from Python") + +array0d = ndarray.create_int64(np.array([42], np.int64), + block_format_t_inline_array, + compression_t_none, + 0, + np.array([]), + np.array([])) +ent0 = entry.create_from_ndarray("alpha", array0d, "") + +array1d = ndarray.create_int64(np.array([1, 2, 3], np.int64), + block_format_t_block, + compression_t_none, + 0, + np.array([]), + np.array([3])) +ent1 = entry.create_from_ndarray("beta", array1d, "") + +array2d = ndarray.create_float64(np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], + np.float64), + block_format_t_inline_array, + compression_t_none, 0, + np.array([]), + np.array([2, 3])) +ent2 = entry.create_from_ndarray("gamma", array2d, "") + +array3d = ndarray.create_complex128(np.array([1, -2, 3j, -4j, 5 + 1j, 6 - 1j], + np.complex128), + block_format_t_block, + compression_t_bzip2, + 9, + np.array([]), + np.array([1, 2, 3])) +ent3 = entry.create_from_ndarray("delta", array3d, "") + +array8d = ndarray.create_bool(np.array([True], np.int), + block_format_t_block, + compression_t_zlib, + 9, + np.array([]), + np.array([1, 1, 1, 1, 1, 1, 1, 1])) +ent8 = entry.create_from_ndarray("epsilon", array8d, "") + +seq = sequence.create([ent0, ent1, ent2]) +ents = entry.create_from_sequence("zeta", seq, "") + +ref = reference.create_from_path("", ["group", "1"]) +entr = entry.create_from_reference("eta", ref, "") + +grp = group.create({"alpha": ent0, + "beta": ent1, + "gamma": ent2, + "delta": ent3, + "epsilon": ent8, + "zeta": ents, + "eta": entr}) + +project = asdf.create_from_group({}, grp) +project.write("demo-python.asdf") + +print("Done.") diff --git a/asdf.i b/asdf.i new file mode 100644 index 0000000..c756db1 --- /dev/null +++ b/asdf.i @@ -0,0 +1,352 @@ +// SWIG interface file + +%module asdf + +%{ + #include "asdf.hpp" + using namespace ASDF; +%} + +%include +%include +%include +%include +%include + +using std::string; + +%shared_ptr(asdf); +%shared_ptr(datatype_t); +%shared_ptr(entry); +%shared_ptr(field_t); +%shared_ptr(group); +%shared_ptr(ndarray); +%shared_ptr(reference); +%shared_ptr(sequence); +%shared_ptr(std::vector); + +%template(map_string_string) + std::map; +%template(map_string_shared_ptr_entry) + std::map>; +%template(map_string_shared_ptr_ndarray) + std::map>; + +%template(vector_bool) std::vector; +%template(vector_complex_float) std::vector>; +%template(vector_complex_double) std::vector>; +%template(vector_double) std::vector; +%template(vector_float) std::vector; +// %template(vector_int32_t) std::vector; +// %template(vector_int64_t) std::vector; +%template(vector_int) std::vector; +%template(vector_long_long) std::vector; +%template(vector_shared_ptr_entry) std::vector>; +%template(vector_string) std::vector; + +%nodefaultctor; + + + +enum class block_format_t { undefined, block, inline_array }; +enum class compression_t { undefined, none, bzip2, zlib }; + + + +%{ +struct reader_state_node { + std::shared_ptr rs; + YAML::Node node; +}; +%} +struct reader_state_node { +}; + + + +enum scalar_type_id_t { + id_bool8, + id_int8, + id_int16, + id_int32, + id_int64, + id_uint8, + id_uint16, + id_uint32, + id_uint64, + id_float32, + id_float64, + id_complex64, + id_complex128, + id_ascii, + id_ucs4, +}; + +%{ + constexpr scalar_type_id_t get_scalar_type_id_int32() { return get_scalar_type_id(); } + constexpr scalar_type_id_t get_scalar_type_id_int64() { return get_scalar_type_id(); } + constexpr scalar_type_id_t get_scalar_type_id_float32() { return get_scalar_type_id(); } + constexpr scalar_type_id_t get_scalar_type_id_float64() { return get_scalar_type_id(); } + constexpr scalar_type_id_t get_scalar_type_id_complex64() { return get_scalar_type_id(); } + constexpr scalar_type_id_t get_scalar_type_id_complex128() { return get_scalar_type_id(); } +%} +constexpr scalar_type_id_t get_scalar_type_id_int32(); +constexpr scalar_type_id_t get_scalar_type_id_int64(); +constexpr scalar_type_id_t get_scalar_type_id_float32(); +constexpr scalar_type_id_t get_scalar_type_id_float64(); +constexpr scalar_type_id_t get_scalar_type_id_complex64(); +constexpr scalar_type_id_t get_scalar_type_id_complex128(); + +class datatype_t; + +class field_t { + public: +}; + +class datatype_t { + public: + bool is_scalar; + scalar_type_id_t scalar_type_id; + // std::vector> fields; +}; + + + +class ndarray { + public: + + %extend { + // TODO: accept bool + static std::shared_ptr + create_bool(const std::vector& data1, + block_format_t block_format, + compression_t compression, + int compression_level, + std::vector mask, + std::vector shape) + { + // TODO: Avoid this copy + std::vector data(data1.size()); + for (size_t i=0; i + (std::move(data), block_format, compression, compression_level, + std::move(mask), std::move(shape)); + } + static std::shared_ptr + create_int64(std::vector data, + block_format_t block_format, + compression_t compression, + int compression_level, + std::vector mask, + std::vector shape) + { + return std::make_shared + (std::move(data), block_format, compression, compression_level, + std::move(mask), std::move(shape)); + } + static std::shared_ptr + create_float64(std::vector data, + block_format_t block_format, + compression_t compression, + int compression_level, + std::vector mask, + std::vector shape) + { + return std::make_shared + (std::move(data), block_format, compression, compression_level, + std::move(mask), std::move(shape)); + } + static std::shared_ptr + create_complex128(std::vector> data, + block_format_t block_format, + compression_t compression, + int compression_level, + std::vector mask, + std::vector shape) + { + return std::make_shared + (std::move(data), block_format, compression, compression_level, + std::move(mask), std::move(shape)); + } + + static std::shared_ptr + read(const reader_state_node &&rs_node) + { + return std::make_shared(rs_node.rs, rs_node.node); + } + } + + %extend { + std::vector get_data_vector_int32() const + { + return self->get_data_vector(); + } + std::vector get_data_vector_int64() const + { + return self->get_data_vector(); + } + std::vector get_data_vector_float32() const + { + return self->get_data_vector(); + } + std::vector get_data_vector_float64() const + { + return self->get_data_vector(); + } + std::vector> get_data_vector_complex64() const + { + return self->get_data_vector(); + } + std::vector> get_data_vector_complex128() const + { + return self->get_data_vector(); + } + } + + std::shared_ptr get_datatype() const; + std::vector get_shape() const; + int64_t get_offset() const; + std::vector get_strides() const; +}; + + + +class reference { + public: + + %extend { + static std::shared_ptr + create_from_target(string target) + { + return std::make_shared(std::move(target)); + } + static std::shared_ptr + create_from_path(const string &base_target, + const std::vector &doc_path) + { + return std::make_shared(base_target, doc_path); + } + static std::shared_ptr + create_from_reader_state_node(const reader_state_node &rs_node) + { + return std::make_shared(rs_node.rs, rs_node.node); + } + } + + string get_target() const; + std::pair> get_split_target() const; + + %extend { + reader_state_node resolve() const + { + auto rs_node = self->resolve(); + return reader_state_node{std::get<0>(rs_node), std::get<1>(rs_node)}; + } + } +}; + + + +class sequence; +class group; + +class entry { + public: + + %extend { + static std::shared_ptr + create_from_ndarray(const string& name, + const std::shared_ptr& arr, + const string& description) + { + return std::make_shared(name, arr, description); + } + static std::shared_ptr + create_from_reference(const string& name, + const std::shared_ptr& ref, + const string& description) + { + return std::make_shared(name, ref, description); + } + static std::shared_ptr + create_from_sequence(const string& name, + const std::shared_ptr& seq, + const string& description) + { + return std::make_shared(name, seq, description); + } + static std::shared_ptr + create_from_group(const string& name, + const std::shared_ptr& grp, + const string& description) + { + return std::make_shared(name, grp, description); + } + } + + string get_name() const; + std::shared_ptr get_array() const; + std::shared_ptr get_reference() const; + std::shared_ptr get_sequence() const; + std::shared_ptr get_group() const; + string get_description() const; +}; + +class sequence { + public: + + %extend { + static std::shared_ptr + create(std::vector> entries) + { + return std::make_shared(std::move(entries)); + } + } + + const vector> &get_entries() const; +}; + +class group { + public: + + %extend { + static std::shared_ptr + create(std::map> entries) + { + return std::make_shared(std::move(entries)); + } + } + + const std::map> &get_entries() const; +}; + + + +class asdf { + public: + + %extend { + static std::shared_ptr + create_from_ndarrays(std::map tags, + std::map> data) + { + return std::make_shared(std::move(tags), std::move(data)); + } + static std::shared_ptr + create_from_group(std::map tags, + std::shared_ptr grp) + { + return std::make_shared(std::move(tags), std::move(grp)); + } + static std::shared_ptr + read(const string &filename) + { + return std::make_shared(filename); + } + } + + void write(const string &filename) const; + + std::shared_ptr get_group() const; +}; diff --git a/asdf_datatype.hpp b/asdf_datatype.hpp index 1621d51..5446e64 100644 --- a/asdf_datatype.hpp +++ b/asdf_datatype.hpp @@ -7,6 +7,7 @@ #include #include +#include #include namespace ASDF { @@ -16,6 +17,7 @@ using namespace std; // Define an id for every type enum scalar_type_id_t { + id_error = -1, id_bool8, id_int8, id_int16, @@ -51,52 +53,50 @@ typedef vector ascii_t; typedef vector ucs4_t; // Convert a type to its id enum -template struct get_scalar_type_id; -template <> struct get_scalar_type_id { - constexpr static scalar_type_id_t value = id_bool8; -}; -template <> struct get_scalar_type_id { - constexpr static scalar_type_id_t value = id_int8; -}; -template <> struct get_scalar_type_id { - constexpr static scalar_type_id_t value = id_int16; -}; -template <> struct get_scalar_type_id { - constexpr static scalar_type_id_t value = id_int32; -}; -template <> struct get_scalar_type_id { - constexpr static scalar_type_id_t value = id_int64; -}; -template <> struct get_scalar_type_id { - constexpr static scalar_type_id_t value = id_uint8; -}; -template <> struct get_scalar_type_id { - constexpr static scalar_type_id_t value = id_uint16; -}; -template <> struct get_scalar_type_id { - constexpr static scalar_type_id_t value = id_uint32; -}; -template <> struct get_scalar_type_id { - constexpr static scalar_type_id_t value = id_uint64; -}; -template <> struct get_scalar_type_id { - constexpr static scalar_type_id_t value = id_float32; -}; -template <> struct get_scalar_type_id { - constexpr static scalar_type_id_t value = id_float64; -}; -template <> struct get_scalar_type_id { - constexpr static scalar_type_id_t value = id_complex64; -}; -template <> struct get_scalar_type_id { - constexpr static scalar_type_id_t value = id_complex128; -}; -template <> struct get_scalar_type_id { - constexpr static scalar_type_id_t value = id_ascii; -}; -template <> struct get_scalar_type_id { - constexpr static scalar_type_id_t value = id_ucs4; -}; +namespace { +template struct is_complex : false_type {}; +template struct is_complex> : is_floating_point {}; +// template inline constexpr bool is_complex_v = +// is_complex::value; +} // namespace + +template +struct get_scalar_type_id + : integral_constant< + scalar_type_id_t, + is_same::value + ? id_bool8 + : is_integral::value && is_signed::value + ? (sizeof(T) == 1 + ? id_int8 + : sizeof(T) == 2 + ? id_int16 + : sizeof(T) == 4 + ? id_int32 + : sizeof(T) == 8 ? id_int64 : id_error) + : is_integral::value && is_unsigned::value + ? (sizeof(T) == 1 + ? id_uint8 + : sizeof(T) == 2 + ? id_uint16 + : sizeof(T) == 4 + ? id_uint32 + : sizeof(T) == 8 ? id_uint64 + : id_error) + : is_floating_point::value + ? (sizeof(T) == 4 + ? id_float32 + : sizeof(T) == 8 ? id_float64 : id_error) + : is_complex::value + ? (sizeof(T) == 8 + ? id_complex64 + : sizeof(T) == 16 ? id_complex128 + : id_error) + : is_same::value + ? id_ascii + : is_same::value + ? id_ucs4 + : id_error> {}; // Convert an enum id to its type template struct get_scalar_type; diff --git a/asdf_group.hpp b/asdf_group.hpp index 5d76395..933386f 100644 --- a/asdf_group.hpp +++ b/asdf_group.hpp @@ -46,18 +46,18 @@ class entry { assert(ref); } - entry(string name1, shared_ptr grp1, string description1) - : name(move(name1)), grp(move(grp1)), description(move(description1)) { - assert(!name.empty()); - assert(grp); - } - entry(string name1, shared_ptr seq1, string description1) : name(move(name1)), seq(move(seq1)), description(move(description1)) { assert(!name.empty()); assert(seq); } + entry(string name1, shared_ptr grp1, string description1) + : name(move(name1)), grp(move(grp1)), description(move(description1)) { + assert(!name.empty()); + assert(grp); + } + entry(const shared_ptr &rs, const YAML::Node &node); entry(const copy_state &cs, const entry &ent); writer &to_yaml(writer &w) const; diff --git a/asdf_ndarray.hpp b/asdf_ndarray.hpp index a4c97b4..9d41128 100644 --- a/asdf_ndarray.hpp +++ b/asdf_ndarray.hpp @@ -164,7 +164,7 @@ class ndarray { : ndarray(make_constant_memoized(shared_ptr( make_shared>(move(data1)))), block_format, compression, compression_level, move(mask1), - make_shared(get_scalar_type_id::value), + make_shared(get_scalar_type_id()), host_byteorder(), move(shape1), offset, move(strides1)) {} ndarray(const shared_ptr &rs, const YAML::Node &node); @@ -187,6 +187,21 @@ class ndarray { return mdata; } + template vector get_data_vector() const { + assert(datatype->is_scalar); + assert(datatype->scalar_type_id == get_scalar_type_id()); + int64_t npoints = 1; + for (size_t d = 0; d < shape.size(); ++d) + npoints *= shape.at(d); + const T *ptr = static_cast(mdata->ptr()); + size_t nbytes = mdata->nbytes(); + assert(nbytes == npoints * sizeof(T)); + vector data(npoints); + for (size_t i = 0; i < npoints; ++i) + data[i] = ptr[i]; + return data; + } + shared_ptr get_datatype() const { return datatype; } vector get_shape() const { return shape; } int64_t get_offset() const { return offset; } diff --git a/datatype.cpp b/datatype.cpp index 1323302..6ff9cd9 100644 --- a/datatype.cpp +++ b/datatype.cpp @@ -6,22 +6,6 @@ namespace ASDF { // Scalar types -constexpr scalar_type_id_t get_scalar_type_id::value; -constexpr scalar_type_id_t get_scalar_type_id::value; -constexpr scalar_type_id_t get_scalar_type_id::value; -constexpr scalar_type_id_t get_scalar_type_id::value; -constexpr scalar_type_id_t get_scalar_type_id::value; -constexpr scalar_type_id_t get_scalar_type_id::value; -constexpr scalar_type_id_t get_scalar_type_id::value; -constexpr scalar_type_id_t get_scalar_type_id::value; -constexpr scalar_type_id_t get_scalar_type_id::value; -constexpr scalar_type_id_t get_scalar_type_id::value; -constexpr scalar_type_id_t get_scalar_type_id::value; -constexpr scalar_type_id_t get_scalar_type_id::value; -constexpr scalar_type_id_t get_scalar_type_id::value; -constexpr scalar_type_id_t get_scalar_type_id::value; -constexpr scalar_type_id_t get_scalar_type_id::value; - // Check consistency between id enum and tuple element static_assert(is_same, bool8_t>::value, ""); static_assert(is_same, int8_t>::value, ""); @@ -40,21 +24,21 @@ static_assert(is_same, complex128_t>::value, static_assert(is_same, ascii_t>::value, ""); static_assert(is_same, ucs4_t>::value, ""); -static_assert(get_scalar_type_id::value == id_bool8, ""); -static_assert(get_scalar_type_id::value == id_int8, ""); -static_assert(get_scalar_type_id::value == id_int16, ""); -static_assert(get_scalar_type_id::value == id_int32, ""); -static_assert(get_scalar_type_id::value == id_int64, ""); -static_assert(get_scalar_type_id::value == id_uint8, ""); -static_assert(get_scalar_type_id::value == id_uint16, ""); -static_assert(get_scalar_type_id::value == id_uint32, ""); -static_assert(get_scalar_type_id::value == id_uint64, ""); -static_assert(get_scalar_type_id::value == id_float32, ""); -static_assert(get_scalar_type_id::value == id_float64, ""); -static_assert(get_scalar_type_id::value == id_complex64, ""); -static_assert(get_scalar_type_id::value == id_complex128, ""); -static_assert(get_scalar_type_id::value == id_ascii, ""); -static_assert(get_scalar_type_id::value == id_ucs4, ""); +static_assert(get_scalar_type_id() == id_bool8, ""); +static_assert(get_scalar_type_id() == id_int8, ""); +static_assert(get_scalar_type_id() == id_int16, ""); +static_assert(get_scalar_type_id() == id_int32, ""); +static_assert(get_scalar_type_id() == id_int64, ""); +static_assert(get_scalar_type_id() == id_uint8, ""); +static_assert(get_scalar_type_id() == id_uint16, ""); +static_assert(get_scalar_type_id() == id_uint32, ""); +static_assert(get_scalar_type_id() == id_uint64, ""); +static_assert(get_scalar_type_id() == id_float32, ""); +static_assert(get_scalar_type_id() == id_float64, ""); +static_assert(get_scalar_type_id() == id_complex64, ""); +static_assert(get_scalar_type_id() == id_complex128, ""); +static_assert(get_scalar_type_id() == id_ascii, ""); +static_assert(get_scalar_type_id() == id_ucs4, ""); size_t get_scalar_type_size(scalar_type_id_t scalar_type_id) { switch (scalar_type_id) { @@ -287,10 +271,12 @@ YAML::Node yaml_encode(float64_t val) { return node; } template YAML::Node yaml_encode(const complex &val) { + // Work around libstdc++ const-handling bug in gcc 4.8 + auto val1(val); YAML::Emitter re; - re << val.real(); + re << val1.real(); YAML::Emitter im; - im << val.imag(); + im << val1.imag(); ostringstream buf; buf << re.c_str(); if (im.c_str()[0] != '-') diff --git a/demo-external.cpp b/demo-external.cpp index 29c571d..6608ded 100644 --- a/demo-external.cpp +++ b/demo-external.cpp @@ -57,7 +57,7 @@ void write_metadata() { template vector read_array(const shared_ptr &arr) { auto datatype = arr->get_datatype(); assert(datatype->is_scalar); - assert(datatype->scalar_type_id == get_scalar_type_id::value); + assert(datatype->scalar_type_id == get_scalar_type_id()); auto shape = arr->get_shape(); assert(shape.size() == 1); auto npoints = shape.at(0); diff --git a/demo.cpp b/demo.cpp index 2d5b7cd..b5bae88 100644 --- a/demo.cpp +++ b/demo.cpp @@ -28,10 +28,10 @@ int main(int argc, char **argv) { block_format_t::inline_array, compression_t::none, 0, vector(), vector{2, 3}); auto ent2 = make_shared("gamma", array2d, string()); - auto array3d = - make_shared(vector{1, -2, 3i, -4i, 5 + 1i, 6 - 1i}, - block_format_t::block, compression_t::bzip2, 9, - vector(), vector{1, 2, 3}); + auto array3d = make_shared( + vector{{1, 0}, {-2, 0}, {0, 3}, {-4, 0}, {5, 1}, {6, -1}}, + block_format_t::block, compression_t::bzip2, 9, vector(), + vector{1, 2, 3}); auto ent3 = make_shared("delta", array3d, string()); auto array8d = make_shared( vector{true}, block_format_t::block, compression_t::zlib, 9, diff --git a/ndarray.cpp b/ndarray.cpp index 367ce9e..f95d3ec 100644 --- a/ndarray.cpp +++ b/ndarray.cpp @@ -149,7 +149,7 @@ template void input(istream &is, T &data) { } shared_ptr -read_block_data(const shared_ptr &pis, ios::streamoff block_begin, +read_block_data(const shared_ptr &pis, streamoff block_begin, uint64_t allocated_space, uint64_t data_space, compression_t compression, const array &want_checksum) { @@ -319,7 +319,7 @@ memoized ndarray::read_block(const shared_ptr &pis) { // fdata.fill_cache(); // skip padding - is.seekg(block_begin + ios::streamoff(used_space)); + is.seekg(block_begin + streamoff(used_space)); return move(fdata); }