diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 0000000000..3e754a4f7b --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,140 @@ +environment: + matrix: +# Only VS2008 [vc9] (no C++11) available for Python 2.7 +# - TARGET_ARCH: x86 +# CONDA_PY: 27 +# CONDA_INSTALL_LOCN: C:\\Miniconda +# APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2008 + +# - TARGET_ARCH: x64 +# CONDA_PY: 27 +# CONDA_INSTALL_LOCN: C:\\Miniconda-x64 +# APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2008 + + - TARGET_ARCH: x86 + CONDA_PY: 35 + CONDA_INSTALL_LOCN: C:\\Miniconda35 + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 + platform: x86 + SHARED: ON + + - TARGET_ARCH: x64 + CONDA_PY: 35 + CONDA_INSTALL_LOCN: C:\\Miniconda35-x64 + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 + platform: x64 + SHARED: ON + + - TARGET_ARCH: x86 + CONDA_PY: 36 + CONDA_INSTALL_LOCN: C:\\Miniconda36 + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 + platform: x86 + SHARED: OFF + + - TARGET_ARCH: x64 + CONDA_PY: 36 + CONDA_INSTALL_LOCN: C:\\Miniconda36-x64 + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 + platform: x64 + SHARED: OFF + +configuration: +# - Debug + - Release + +# Clone directory. +clone_folder: c:\projects\openpmd-api + +# Fetch repository as zip archive. +shallow_clone: false + +# Set the clone depth. +clone_depth: 1 + +# Build tags (GitHub only) +skip_tags: false + +branches: + except: + - gh-pages + +init: + # Print AppVeyor environment variables + - cmd: echo "%APPVEYOR%" + - cmd: echo "%CI%" + - cmd: echo "%APPVEYOR_API_URL%" + - cmd: echo "%APPVEYOR_ACCOUNT_NAME%" + - cmd: echo "%APPVEYOR_BUILD_WORKER_IMAGE%" + - cmd: echo "%APPVEYOR_PROJECT_ID%" + - cmd: echo "%APPVEYOR_PROJECT_NAME%" + - cmd: echo "%APPVEYOR_PROJECT_SLUG%" + - cmd: echo "%APPVEYOR_BUILD_FOLDER%" + - cmd: echo "%APPVEYOR_BUILD_ID%" + - cmd: echo "%APPVEYOR_BUILD_NUMBER%" + - cmd: echo "%APPVEYOR_BUILD_VERSION%" + - cmd: echo "%APPVEYOR_PULL_REQUEST_NUMBER%" + - cmd: echo "%APPVEYOR_PULL_REQUEST_TITLE%" + - cmd: echo "%APPVEYOR_JOB_ID%" + - cmd: echo "%APPVEYOR_REPO_PROVIDER%" + - cmd: echo "%APPVEYOR_REPO_SCM%" + - cmd: echo "%APPVEYOR_REPO_NAME%" + - cmd: echo "%APPVEYOR_REPO_BRANCH%" + - cmd: echo "%APPVEYOR_REPO_TAG%" + - cmd: echo "%APPVEYOR_REPO_TAG_NAME%" + - cmd: echo "%APPVEYOR_REPO_COMMIT%" + - cmd: echo "%APPVEYOR_REPO_COMMIT_TIMESTAMP%" + - cmd: echo "%APPVEYOR_REPO_COMMIT_MESSAGE%" + - cmd: echo "%APPVEYOR_REPO_COMMIT_MESSAGE_EXTENDED%" + - cmd: echo "%APPVEYOR_SCHEDULED_BUILD%" + - cmd: echo "%APPVEYOR_FORCED_BUILD%" + - cmd: echo "%APPVEYOR_RE_BUILD%" + - cmd: echo "%PLATFORM%" + - cmd: echo "%TARGET_ARCH%" + - cmd: echo "%CONFIGURATION%" + - cmd: echo "%SHARED%" + +install: + # Cywin's git breaks conda-build. (see https://github.com/conda-forge/conda-smithy-feedstock/pull/2) + - cmd: rmdir C:\cygwin /s /q + + # Add path, activate `conda` and update conda. + - cmd: call %CONDA_INSTALL_LOCN%\Scripts\activate.bat + - cmd: conda update --yes --quiet conda + + - cmd: set PYTHONUNBUFFERED=1 + + # Add our channels. + - cmd: conda config --set show_channel_urls true + - cmd: conda config --remove channels defaults + - cmd: conda config --add channels defaults + - cmd: conda config --add channels conda-forge + + # Configure the VM. + - cmd: conda install -n root --quiet --yes cmake boost-cpp pybind11 hdf5 + +before_build: + - cmd: cd C:\projects\openpmd-api + - cmd: mkdir build + - cmd: cd build + + # Download example files + - ps: ..\.travis\download_samples.ps1 + + # Compiler & Generator Selection + - cmd: if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2015" set OPENPMD_CMAKE_GENERATOR=Visual Studio 14 2015 + - cmd: if "%TARGET_ARCH%"=="x64" set OPENPMD_CMAKE_GENERATOR=%OPENPMD_CMAKE_GENERATOR% Win64 +# - cmd: if "%TARGET_ARCH%"=="x86" "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64_x86 + - cmd: if "%TARGET_ARCH%"=="x86" "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86 + - cmd: if "%TARGET_ARCH%"=="x64" "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64 + + # CMake configure + - cmd: cmake -G "%OPENPMD_CMAKE_GENERATOR%" -DCMAKE_BUILD_TYPE=%CONFIGURATION% -DBUILD_SHARED_LIBS=%SHARED% -DBUILD_TESTING=ON ".." + +build_script: + - cmd: cmake --build . --config %CONFIGURATION% + - cmd: cmake --build . --config %CONFIGURATION% --target install + +test_script: + - cmd: ctest -V -C %CONFIGURATION% + diff --git a/.travis/download_samples.ps1 b/.travis/download_samples.ps1 new file mode 100755 index 0000000000..266dce059c --- /dev/null +++ b/.travis/download_samples.ps1 @@ -0,0 +1,14 @@ +New-item -ItemType directory -Name samples\git-sample\ +Invoke-WebRequest https://github.com/openPMD/openPMD-example-datasets/raw/draft/example-3d.tar.gz -OutFile example-3d.tar.gz +7z.exe x -r example-3d.tar.gz +7z.exe x -r example-3d.tar +Move-Item -Path example-3d\hdf5\* samples\git-sample\ +Remove-Item -Recurse -Force example-3d* + +# https://github.com/yt-project/yt/pull/1645 +New-item -ItemType directory -Name samples\issue-sample\ +Invoke-WebRequest https://github.com/yt-project/yt/files/1542668/no_fields.zip -OutFile no_fields.zip +Expand-Archive no_fields.zip -DestinationPath samples\issue-sample\ +Invoke-WebRequest https://github.com/yt-project/yt/files/1542670/no_particles.zip -OutFile no_particles.zip +Expand-Archive no_particles.zip -DestinationPath samples\issue-sample\ +Remove-Item *.zip diff --git a/CMakeLists.txt b/CMakeLists.txt index 75fa877c7d..fe73cb1dbd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,9 +18,14 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) # install directories set(CMAKE_INSTALL_BINDIR bin) -set(CMAKE_INSTALL_LIBDIR lib) set(CMAKE_INSTALL_INCLUDEDIR include) -set(CMAKE_INSTALL_CMAKEDIR lib/cmake/openPMD) +if(WIN32) + set(CMAKE_INSTALL_LIBDIR Lib) + set(CMAKE_INSTALL_CMAKEDIR cmake) +else() + set(CMAKE_INSTALL_LIBDIR lib) + set(CMAKE_INSTALL_CMAKEDIR ${CMAKE_INSTALL_LIBDIR}/cmake/openPMD) +endif() # Options and Variants ######################################################## @@ -84,6 +89,10 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic") # silence BOOST filesystem set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-cpp") +elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + # Warning C4503: "decorated name length exceeded, name was truncated" + # Symbols longer than 4096 chars are truncated + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -wd4503") endif () @@ -230,7 +239,7 @@ set(IO_SOURCE src/IO/HDF5/ParallelHDF5IOHandler.cpp) # library -add_Library(openPMD ${CORE_SOURCE} ${IO_SOURCE}) +add_library(openPMD ${CORE_SOURCE} ${IO_SOURCE}) # properties target_compile_features(openPMD @@ -240,7 +249,11 @@ set_target_properties(openPMD PROPERTIES CXX_EXTENSIONS OFF CXX_STANDARD_REQUIRED ON POSITION_INDEPENDENT_CODE ON + WINDOWS_EXPORT_ALL_SYMBOLS ON ) +if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + target_compile_options(openPMD PUBLIC "/bigobj") +endif() # own headers target_include_directories(openPMD PUBLIC @@ -339,9 +352,15 @@ if(openPMD_HAVE_PYTHON) ) target_link_libraries(openPMD.py PRIVATE openPMD) - set(CMAKE_INSTALL_PYTHONDIR - "${CMAKE_INSTALL_LIBDIR}/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages" - ) + if(WIN32) + set(CMAKE_INSTALL_PYTHONDIR + "${CMAKE_INSTALL_LIBDIR}\\site-packages" + ) + else() + set(CMAKE_INSTALL_PYTHONDIR + "${CMAKE_INSTALL_LIBDIR}/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages" + ) + endif() set(CMAKE_INSTALL_PYTHONDIR "${CMAKE_INSTALL_PYTHONDIR}" CACHE INTERNAL "" FORCE ) @@ -400,7 +419,6 @@ if(BUILD_TESTING) if(openPMD_HAVE_INVASIVE_TESTS) target_compile_definitions(${testname}Tests PUBLIC "-DopenPMD_HAVE_INVASIVE_TESTS=1") endif() - if(openPMD_HAVE_MPI) target_compile_definitions(${testname}Tests PUBLIC "-DopenPMD_HAVE_MPI=1") else() @@ -556,11 +574,7 @@ if(openPMD_HAVE_HDF5) endif() endforeach() else() - message(STATUS "Missing samples/git-sample/ directory! " - "Skipping C++ example test!\n\n" - "Note: run\n" - " . ${openPMD_SOURCE_DIR}/.travis/download_samples.sh\n" - "to add example files!") + message(STATUS "Note: Skipping C++ example tests (missing example files)") endif() endif() @@ -580,18 +594,38 @@ if(openPMD_HAVE_PYTHON) WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ) - set_tests_properties(Example.py.${examplename} - PROPERTIES ENVIRONMENT - "PYTHONPATH=${openPMD_BINARY_DIR}/${CMAKE_INSTALL_PYTHONDIR}:$ENV{PYTHONPATH}" - ) + if(WIN32) + string(REGEX REPLACE "/" "\\\\" WIN_BUILD_BASEDIR ${openPMD_BINARY_DIR}) + string(REGEX REPLACE "/" "\\\\" WIN_BUILD_BINDIR ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) + string(REPLACE ";" "\\;" WIN_PATH "$ENV{PATH}") + string(REPLACE ";" "\\;" WIN_PYTHONPATH "$ENV{PYTHONPATH}") + set_property(TEST Example.py.${examplename} + PROPERTY ENVIRONMENT + "PATH=${WIN_BUILD_BINDIR}\\${CMAKE_BUILD_TYPE}\;${WIN_PATH}\n" + "PYTHONPATH=${WIN_BUILD_BASEDIR}\\${CMAKE_INSTALL_PYTHONDIR}\\${CMAKE_BUILD_TYPE}\;${WIN_PYTHONPATH}" + ) + else() + set_tests_properties(Example.py.${examplename} + PROPERTIES ENVIRONMENT + "PYTHONPATH=${openPMD_BINARY_DIR}/${CMAKE_INSTALL_PYTHONDIR}:$ENV{PYTHONPATH}" + ) + endif() endif() endforeach() else() - message(STATUS "Missing samples/git-sample/ directory! " - "Skipping Python example test!\n\n" - "Note: run\n" - " ${openPMD_SOURCE_DIR}/.travis/download_samples.sh\n" - "to add example files!") + message(STATUS "Note: Skipping Python example tests (missing example files)") + endif() +endif() + +if(NOT EXISTS "${openPMD_BINARY_DIR}/samples/git-sample/") + if(WIN32) + message(STATUS "Note: run\n" + " Powershell.exe -File ${openPMD_SOURCE_DIR}/.travis/download_samples.ps1\n" + "to add example files to samples/git-sample/ directory!") + else() + message(STATUS "Note: run\n" + " . ${openPMD_SOURCE_DIR}/.travis/download_samples.sh\n" + "to add example files to samples/git-sample/ directory!") endif() endif() diff --git a/README.md b/README.md index c250f224ff..5cf2f49011 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,8 @@ openPMD - API for Developers [![Supported openPMD Standard](https://img.shields.io/badge/openPMD-1.0.0--1.1.0-blue.svg)](https://github.com/openPMD/openPMD-standard/releases) [![Documentation Status](https://readthedocs.org/projects/openpmd-api/badge/?version=latest)](http://openpmd-api.readthedocs.io/en/latest/?badge=latest) [![Doxygen](https://img.shields.io/badge/API-Doxygen-blue.svg)](http://www.openpmd.org/openPMD-api) -[![Code Status dev](https://img.shields.io/travis/openPMD/openPMD-api/dev.svg?label=dev)](https://travis-ci.org/openPMD/openPMD-api/branches) +[![Linux/OSX Build Status dev](https://img.shields.io/travis/openPMD/openPMD-api/dev.svg?label=dev)](https://travis-ci.org/openPMD/openPMD-api/branches) +[![Windows Build Status dev](https://ci.appveyor.com/api/projects/status/x95q4n620pqk0e0t/branch/dev?svg=true)](https://ci.appveyor.com/project/ax3l/openpmd-api/branch/dev) [![Language](https://img.shields.io/badge/language-C%2B%2B11-orange.svg)](https://isocpp.org/) [![Language](https://img.shields.io/badge/language-Python3-orange.svg)](https://www.python.org/) ![Development Phase](https://img.shields.io/badge/phase-unstable-yellow.svg) diff --git a/include/openPMD/auxiliary/HasToString.hpp b/include/openPMD/auxiliary/HasToString.hpp deleted file mode 100644 index 0a2e4bb288..0000000000 --- a/include/openPMD/auxiliary/HasToString.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include -#include -#include - - -namespace openPMD -{ -namespace auxiliary -{ - /** checks if std::to_string() is defined for a type - */ - class HasToString - { - template< typename T_Key > - [[noreturn]] auto static ok( T_Key key ) -> - std::pair< std::true_type, decltype( std::to_string( key ) ) > {} - - template< typename T_Key > - [[noreturn]] auto static ok( T_Key ) -> - std::pair< std::false_type, bool > {} - - template< typename T_Key > - using type_proto = decltype( ok< T_Key > ); - - public: - template< typename T_Key > - using type = typename type_proto< T_Key >::first_type; - }; - - /** Access to ::type member of HasToString< T_Key > - */ - template< typename T_Key > - using HasToString_t = typename HasToString::type< T_Key >; - -} // auxiliary -} // openPMD diff --git a/include/openPMD/backend/Attributable.hpp b/include/openPMD/backend/Attributable.hpp index ba4350e2d9..da30c2acbb 100644 --- a/include/openPMD/backend/Attributable.hpp +++ b/include/openPMD/backend/Attributable.hpp @@ -23,10 +23,8 @@ #include "openPMD/IO/AbstractIOHandler.hpp" #include "openPMD/backend/Attribute.hpp" #include "openPMD/backend/Writable.hpp" -#include "openPMD/auxiliary/HasToString.hpp" #include -#include #include #include #include @@ -77,12 +75,14 @@ class Attributable friend class Iteration; friend class Series; +#if !defined(_MSC_VER) template< typename T_Key > auto out_of_range_msg(T_Key const& key) -> - typename std::enable_if< auxiliary::HasToString_t::value, std::string >::type + decltype(std::to_string(key)) { return std::string("Attribute '") + std::to_string(key) + std::string("' does not exist (read-only)."); } +#endif template< typename T_Key > auto out_of_range_msg(T_Key const& key) -> decltype(std::string(key)) diff --git a/include/openPMD/backend/Container.hpp b/include/openPMD/backend/Container.hpp index 0c4003b083..9d4fa8e862 100644 --- a/include/openPMD/backend/Container.hpp +++ b/include/openPMD/backend/Container.hpp @@ -21,7 +21,6 @@ #pragma once #include "openPMD/backend/Attributable.hpp" -#include "openPMD/auxiliary/HasToString.hpp" #include #include @@ -72,12 +71,14 @@ class Container : public Attributable friend class ParticleSpecies; friend class Series; +#if !defined(_MSC_VER) template< typename T_Key > auto out_of_range_msg(T_Key const& key) -> - typename std::enable_if< auxiliary::HasToString_t::value, std::string >::type + decltype(std::to_string(key)) { return std::string("Key '") + std::to_string(key) + std::string("' does not exist (read-only)."); } +#endif template< typename T_Key > auto out_of_range_msg(T_Key const& key) -> decltype(std::string(key)) diff --git a/test/SerialIOTest.cpp b/test/SerialIOTest.cpp index 91c815a9ea..97889b21de 100644 --- a/test/SerialIOTest.cpp +++ b/test/SerialIOTest.cpp @@ -19,6 +19,7 @@ using namespace openPMD; #include #include #include +#include #if openPMD_HAVE_HDF5 @@ -832,7 +833,7 @@ TEST_CASE( "hdf5_dtype_test", "[serial][hdf5]" ) s.setAttribute("vecUint64", std::vector< uint64_t >({18446744073709551614u, 18446744073709551615u})); s.setAttribute("vecFloat", std::vector< float >({0.f, 3.40282e+38f})); s.setAttribute("vecDouble", std::vector< double >({0., 1.79769e+308})); - s.setAttribute("vecLongdouble", std::vector< long double >({0.L, 1.18973e+4932L})); + s.setAttribute("vecLongdouble", std::vector< long double >({0.L, std::numeric_limits::max()})); s.setAttribute("vecString", std::vector< std::string >({"vector", "of", "strings"})); s.setAttribute("bool", true); } @@ -849,7 +850,9 @@ TEST_CASE( "hdf5_dtype_test", "[serial][hdf5]" ) REQUIRE(s.getAttribute("uint64").get< uint64_t >() == 64u); REQUIRE(s.getAttribute("float").get< float >() == 16.e10f); REQUIRE(s.getAttribute("double").get< double >() == 1.e64); +#if !defined(_MSC_VER) REQUIRE(s.getAttribute("longdouble").get< long double >() == 1.e80L); +#endif REQUIRE(s.getAttribute("string").get< std::string >() == "string"); REQUIRE(s.getAttribute("vecChar").get< std::vector< char > >() == std::vector< char >({'c', 'h', 'a', 'r'})); REQUIRE(s.getAttribute("vecInt16").get< std::vector< int16_t > >() == std::vector< int16_t >({32766, 32767})); @@ -861,7 +864,9 @@ TEST_CASE( "hdf5_dtype_test", "[serial][hdf5]" ) REQUIRE(s.getAttribute("vecUint64").get< std::vector< uint64_t > >() == std::vector< uint64_t >({18446744073709551614u, 18446744073709551615u})); REQUIRE(s.getAttribute("vecFloat").get< std::vector< float > >() == std::vector< float >({0.f, 3.40282e+38f})); REQUIRE(s.getAttribute("vecDouble").get< std::vector< double > >() == std::vector< double >({0., 1.79769e+308})); - REQUIRE(s.getAttribute("vecLongdouble").get< std::vector< long double > >() == std::vector< long double >({0.L, 1.18973e+4932L})); +#if !defined(_MSC_VER) + REQUIRE(s.getAttribute("vecLongdouble").get< std::vector< long double > >() == std::vector< long double >({0.L, std::numeric_limits::max()})); +#endif REQUIRE(s.getAttribute("vecString").get< std::vector< std::string > >() == std::vector< std::string >({"vector", "of", "strings"})); REQUIRE(s.getAttribute("bool").get< bool >() == true); } @@ -1154,7 +1159,7 @@ TEST_CASE( "adios1_dtype_test", "[serial][adios1]" ) s.setAttribute("vecUint64", std::vector< uint64_t >({18446744073709551614u, 18446744073709551615u})); s.setAttribute("vecFloat", std::vector< float >({0.f, 3.40282e+38f})); s.setAttribute("vecDouble", std::vector< double >({0., 1.79769e+308})); - s.setAttribute("vecLongdouble", std::vector< long double >({0.L, 1.18973e+4932L})); + s.setAttribute("vecLongdouble", std::vector< long double >({0.L, std::numeric_limits::max()})); s.setAttribute("vecString", std::vector< std::string >({"vector", "of", "strings"})); s.setAttribute("bool", true); } @@ -1171,7 +1176,9 @@ TEST_CASE( "adios1_dtype_test", "[serial][adios1]" ) REQUIRE(s.getAttribute("uint64").get< uint64_t >() == 64u); REQUIRE(s.getAttribute("float").get< float >() == 16.e10f); REQUIRE(s.getAttribute("double").get< double >() == 1.e64); +#if !defined(_MSC_VER) REQUIRE(s.getAttribute("longdouble").get< long double >() == 1.e80L); +#endif REQUIRE(s.getAttribute("string").get< std::string >() == "string"); REQUIRE(s.getAttribute("vecChar").get< std::vector< char > >() == std::vector< char >({'c', 'h', 'a', 'r'})); REQUIRE(s.getAttribute("vecInt16").get< std::vector< int16_t > >() == std::vector< int16_t >({32766, 32767})); @@ -1183,7 +1190,9 @@ TEST_CASE( "adios1_dtype_test", "[serial][adios1]" ) REQUIRE(s.getAttribute("vecUint64").get< std::vector< uint64_t > >() == std::vector< uint64_t >({18446744073709551614u, 18446744073709551615u})); REQUIRE(s.getAttribute("vecFloat").get< std::vector< float > >() == std::vector< float >({0.f, 3.40282e+38f})); REQUIRE(s.getAttribute("vecDouble").get< std::vector< double > >() == std::vector< double >({0., 1.79769e+308})); - REQUIRE(s.getAttribute("vecLongdouble").get< std::vector< long double > >() == std::vector< long double >({0.L, 1.18973e+4932L})); +#if !defined(_MSC_VER) + REQUIRE(s.getAttribute("vecLongdouble").get< std::vector< long double > >() == std::vector< long double >({0.L, std::numeric_limits::max()})); +#endif REQUIRE(s.getAttribute("vecString").get< std::vector< std::string > >() == std::vector< std::string >({"vector", "of", "strings"})); REQUIRE(s.getAttribute("bool").get< uint8_t >() == static_cast< uint8_t >(true)); }