diff -Nru scram-0.16.1/.clang-tidy scram-0.16.2/.clang-tidy --- scram-0.16.1/.clang-tidy 1970-01-01 00:00:00.000000000 +0000 +++ scram-0.16.2/.clang-tidy 2018-01-12 11:42:47.000000000 +0000 @@ -0,0 +1,27 @@ +Checks: 'google-*' +WarningsAsErrors: '' +HeaderFilterRegex: '' +AnalyzeTemporaryDtors: false +FormatStyle: none +User: user +CheckOptions: + - key: google-readability-braces-around-statements.ShortStatementLines + value: '2' + - key: google-readability-function-size.StatementThreshold + value: '800' + - key: google-readability-namespace-comments.ShortNamespaceLines + value: '10' + - key: google-readability-namespace-comments.SpacesBeforeComments + value: '2' + - key: modernize-loop-convert.MaxCopySize + value: '16' + - key: modernize-loop-convert.MinConfidence + value: reasonable + - key: modernize-loop-convert.NamingStyle + value: CamelCase + - key: modernize-pass-by-value.IncludeStyle + value: llvm + - key: modernize-replace-auto-ptr.IncludeStyle + value: llvm + - key: modernize-use-nullptr.NullMacros + value: 'NULL' diff -Nru scram-0.16.1/CMakeLists.txt scram-0.16.2/CMakeLists.txt --- scram-0.16.1/CMakeLists.txt 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/CMakeLists.txt 2018-01-12 11:42:47.000000000 +0000 @@ -1,10 +1,10 @@ -cmake_minimum_required(VERSION 3.5) +cmake_minimum_required(VERSION 3.8) # In-source build prevention. set(CMAKE_DISABLE_SOURCE_CHANGES ON) set(CMAKE_DISABLE_IN_SOURCE_BUILD ON) -project(SCRAM VERSION 0.16.1 LANGUAGES CXX) +project(SCRAM VERSION 0.16.2 LANGUAGES CXX) ####################### Begin Options ################### @@ -27,8 +27,8 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # Needed for Clang Tooling. -# Default to C++14. -set(CMAKE_CXX_STANDARD 14) +# Default to C++17. +set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) @@ -40,32 +40,37 @@ add_definitions(-DPROJECT_SOURCE_DIR="${PROJECT_SOURCE_DIR}") # Needed to print file paths. -set(CMAKE_CXX_FLAGS_DEBUG - "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Wextra -Werror -Wno-sign-compare -Wnon-virtual-dtor -Wno-missing-field-initializers -Wold-style-cast") +# Strict debug flags for SCRAM targets (opt-in, must subscribe to quality checks explicitly). +# NOTE: This is a list unlike CMAKE_CXX_FLAGS. +set(SCRAM_CXX_FLAGS_DEBUG + -Wall -Wextra -Werror -Wno-sign-compare -Wnon-virtual-dtor + -Wno-missing-field-initializers -Wold-style-cast + ) if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - CHECK_COMPILER_VERSION("4.9") # TODO: Wpedantic with gcc 4.9 errors with default arg lambdas. - set(CMAKE_CXX_FLAGS_DEBUG - "${CMAKE_CXX_FLAGS_DEBUG} -Wredundant-decls -Wcast-align -Wlogical-op -Wvla -Wuseless-cast -Wunreachable-code") - - if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 5) - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wshadow -Wpedantic -Wmissing-declarations") - endif() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-new-ttp-matching") # TODO: Boost ICL failure. + CHECK_COMPILER_VERSION("7.1") + list(APPEND SCRAM_CXX_FLAGS_DEBUG + -Wredundant-decls -Wcast-align -Wlogical-op -Wvla -Wuseless-cast -Wunreachable-code + -Wshadow -Wpedantic -Wmissing-declarations + -Wimplicit-fallthrough=0 # TODO: Consider explicit fallthrough. + ) elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - CHECK_COMPILER_VERSION("3.6") - set(CMAKE_CXX_FLAGS_DEBUG - "${CMAKE_CXX_FLAGS_DEBUG} -Wno-missing-braces -Wshadow -Wunused-exception-parameter") + CHECK_COMPILER_VERSION("5.0") + list(APPEND SCRAM_CXX_FLAGS_DEBUG -Wno-missing-braces -Wshadow -Wunused-exception-parameter) elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") - CHECK_COMPILER_VERSION("6.1") + CHECK_COMPILER_VERSION("9.0") elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") - CHECK_COMPILER_VERSION("17.0.2") - # TODO: CMAKE_CXX_STANDARD has no effect on icc. - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") + CHECK_COMPILER_VERSION("18.0.1") # TODO: Warning with overload of private override. - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -diag-disable=1125") + list(APPEND SCRAM_CXX_FLAGS_DEBUG -diag-disable=1125) +endif() + +if(WIN32) + list(APPEND SCRAM_CXX_FLAGS_DEBUG -Wno-error) endif() if(WITH_COVERAGE) @@ -76,20 +81,11 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg") endif() -if(WIN32) - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wno-error") -endif() - find_program(CCACHE_FOUND ccache) if(CCACHE_FOUND) message(STATUS "Using CCache for builds") set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) - - if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR - "${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") - add_definitions("-Qunused-arguments") # TODO: CCache bug with not splitting args. - endif() endif() ######################## End compiler configurations #################### @@ -153,24 +149,21 @@ # Include the boost header files and the program_options library. # Please be sure to use Boost rather than BOOST. -if(CMAKE_SYSTEM_NAME STREQUAL "Linux") - set(BOOST_MIN_VERSION "1.58.0") - list(APPEND LIBS ${CMAKE_DL_LIBS}) -else() - set(BOOST_MIN_VERSION "1.61.0") -endif() +set(BOOST_MIN_VERSION "1.61.0") if(NOT WIN32) set(Boost_USE_MULTITHREADED OFF) endif() find_package(Boost ${BOOST_MIN_VERSION} REQUIRED COMPONENTS - program_options filesystem system date_time random + program_options filesystem system random ) message(STATUS "Boost Include directory: ${Boost_INCLUDE_DIR}") message(STATUS "Boost Library directories: ${Boost_LIBRARY_DIRS}") list(APPEND LIBS ${Boost_LIBRARIES}) +list(APPEND LIBS ${CMAKE_DL_LIBS}) + message(STATUS "Libraries: ${LIBS}") ########################## End of find libraries ######################## diff -Nru scram-0.16.1/debian/changelog scram-0.16.2/debian/changelog --- scram-0.16.1/debian/changelog 2018-01-04 10:55:10.000000000 +0000 +++ scram-0.16.2/debian/changelog 2018-01-12 12:28:58.000000000 +0000 @@ -1,3 +1,17 @@ +scram (0.16.2-1) unstable; urgency=medium + + * New upstream release + * Require g++ 7.1 or later (for C++17) + * Bump CMake required version to 3.8 + * Bump Boost required version to 1.61 + * Bump Qt required version to 5.9.1 + * Update copyright years w/ 2018 + * Update man pages + * Add copyright to boost.scope_guard source + * Update VCS control fields to point to Salsa + + -- Olzhas Rakhimov Fri, 12 Jan 2018 04:28:58 -0800 + scram (0.16.1-1) unstable; urgency=medium * New upstream release diff -Nru scram-0.16.1/debian/control scram-0.16.2/debian/control --- scram-0.16.1/debian/control 2018-01-04 10:55:10.000000000 +0000 +++ scram-0.16.2/debian/control 2018-01-12 12:28:58.000000000 +0000 @@ -4,19 +4,20 @@ Maintainer: Debian Science Maintainers Uploaders: Olzhas Rakhimov Build-Depends: debhelper (>= 10), - cmake (>= 3.5), + g++ (>= 4:7.1), + cmake (>= 3.8), libxml2-dev (>= 2.9.1), - libboost-all-dev (>= 1.58.0), + libboost-all-dev (>= 1.61.0), libgoogle-perftools-dev, - qtbase5-dev (>= 5.2.1), + qtbase5-dev (>= 5.9.1), qtbase5-dev-tools, qttools5-dev, qttools5-dev-tools, libqt5svg5-dev, libqt5opengl5-dev Standards-Version: 4.1.3 -Vcs-Git: https://anonscm.debian.org/git/debian-science/packages/scram.git -Vcs-Browser: https://anonscm.debian.org/git/debian-science/packages/scram.git +Vcs-Git: https://salsa.debian.org/science-team/scram.git +Vcs-Browser: https://salsa.debian.org/science-team/scram Homepage: https://scram-pra.org Package: scram diff -Nru scram-0.16.1/debian/copyright scram-0.16.2/debian/copyright --- scram-0.16.1/debian/copyright 2017-11-22 10:24:14.000000000 +0000 +++ scram-0.16.2/debian/copyright 2018-01-12 12:28:58.000000000 +0000 @@ -3,7 +3,7 @@ Source: https://github.com/rakhimov/scram Files: * -Copyright: Copyright © 2014-2017 Olzhas Rakhimov +Copyright: Copyright © 2014-2018 Olzhas Rakhimov License: GPL-3+ This package is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,3 +20,33 @@ . On Debian systems, the complete text of the GNU General Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". + +Files: src/ext/scope_guard.h +Copyright: Copyright © 2017-2018 Yuri Kilochek +License: Boost + Boost Software License - Version 1.0 + ------------------------------------ + . + Boost Software License - Version 1.0 - August 17th, 2003 + . + Permission is hereby granted, free of charge, to any person or organization + obtaining a copy of the software and accompanying documentation covered by + this license (the "Software") to use, reproduce, display, distribute, + execute, and transmit the Software, and to prepare derivative works of the + Software, and to permit third-parties to whom the Software is furnished to + do so, all subject to the following: + . + The copyright notices in the Software and this entire statement, including + the above license grant, this restriction and the following disclaimer, + must be included in all copies of the Software, in whole or in part, and + all derivative works of the Software, unless such copies or derivative + works are solely in the form of machine-executable object code generated by + a source language processor. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. diff -Nru scram-0.16.1/debian/scram.1 scram-0.16.2/debian/scram.1 --- scram-0.16.1/debian/scram.1 2018-01-04 10:55:10.000000000 +0000 +++ scram-0.16.2/debian/scram.1 2018-01-12 12:28:58.000000000 +0000 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.3. -.TH SCRAM "1" "January 2018" "SCRAM 0.16.1" "SCRAM Manual" +.TH SCRAM "1" "January 2018" "SCRAM 0.16.2" "SCRAM Manual" .SH NAME SCRAM \- Command-line Risk Analysis Multi-tool .SH SYNOPSIS diff -Nru scram-0.16.1/debian/scram-gui.1 scram-0.16.2/debian/scram-gui.1 --- scram-0.16.1/debian/scram-gui.1 2018-01-04 10:55:10.000000000 +0000 +++ scram-0.16.2/debian/scram-gui.1 2018-01-12 12:28:58.000000000 +0000 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.3. -.TH SCRAM\-GUI "1" "January 2018" "SCRAM\-GUI 0.16.1" "SCRAM GUI Manual" +.TH SCRAM\-GUI "1" "January 2018" "SCRAM\-GUI 0.16.2" "SCRAM GUI Manual" .SH NAME SCRAM\-GUI \- The GUI front-end for SCRAM .SH SYNOPSIS diff -Nru scram-0.16.1/doc/coding_standards.rst scram-0.16.2/doc/coding_standards.rst --- scram-0.16.1/doc/coding_standards.rst 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/doc/coding_standards.rst 2018-01-12 11:42:47.000000000 +0000 @@ -30,6 +30,7 @@ Deviations from the GCSG ------------------------ +- Use ``pragma once`` instead of header guards. - Exceptions are allowed. - Name mutator functions without ``set_`` prefix. - Multiple *implementation* inheritance is allowed (mostly for mixins). @@ -60,42 +61,17 @@ * Sections are grouped by a blank line. * Within each section the includes are ordered alphabetically. -- Class Format: +- The GCSG-style `declaration order`_ in class definition. - * Section order: +- Use ``nullptr`` instead of literal ``0`` or ``NULL``. - #. ``public:`` member functions - #. ``signals:`` (public by default in Qt5) - #. ``public slots:`` - #. ``protected:`` member functions - #. ``protected slots:`` - #. ``private:`` member functions - #. ``private slots:`` - #. ``private:`` all data members - - * No blank lines after access specifiers. - - * One blank line before access specifiers except for the first one. - - * Declaration order (the GCSG style): - - #. Using declarations, Typedefs, Structs/Classes, and Enums. - #. Static const data members - #. Constructors - #. Destructors - #. Methods - #. Data members - -- Automatic connection of signals and slots is forbidden. - -- Using literal ``0`` for pointers is forbidden. - Only ``nullptr`` is allowed for null pointers. +.. _declaration order: https://google.github.io/styleguide/cppguide.html#Declaration_Order Additional Coding Conventions ----------------------------- -- Use *modern C++* (C++14). +- Use *modern C++* (C++17). Refer to `C++ Core Guidelines`_ for best practices. - Do not use ``inline`` @@ -133,7 +109,7 @@ - Prefer implicit dereference in a function call through a pointer. -.. _C++ Core Guidelines: https://github.com/isocpp/CppCoreGuidelines +.. _C++ Core Guidelines: https://isocpp.github.io/CppCoreGuidelines Core C++ Code @@ -155,7 +131,7 @@ they are never null pointers unless explicitly specified. Null-based logic must be - rare, localized, and explicit (consider using ``boost::optional`` instead). + rare, localized, and explicit (consider using ``std::optional`` instead). - Consider supplying a typedef or alias declaration for common smart pointers. @@ -247,10 +223,6 @@ - Avoid default arguments in signals and slots. -- Prefer Qt5 style connections without ``SIGNAL``/``SLOT`` macros. - -- Prefer normalized signatures in connect statements with ``SIGNAL``/``SLOT`` macros. - - Prefer Qt Designer UI forms over hand-coded GUI. - Common Qt includes may be omitted, @@ -262,6 +234,8 @@ - Avoid ``qobject_cast`` and its flavors. Avoid the RTTI in general. +- Automatic (implicit) connection of signals and slots is forbidden. + Monitoring Code Quality ======================= @@ -337,9 +311,9 @@ through unit, integration, regression, and benchmarking tests. The following tools are used for this purpose: -- GoogleTest_ +- Catch2_ - `Qt Test`_ -- Nose_ +- Pytest_ These tests are automated, and continuous integration is provided by `Travis CI`_ and AppVeyor_. @@ -348,9 +322,9 @@ with auto-generated analysis input files to discover bugs, bottlenecks, and assumption failures. -.. _GoogleTest: https://github.com/google/googletest +.. _Catch2: https://github.com/catchorg/Catch2 .. _Qt Test: http://doc.qt.io/qt-5/qtest-overview.html -.. _Nose: httpss://nose.readthedocs.io/en/latest/ +.. _Pytest: https://pytest.org .. _Travis CI: https://travis-ci.org/rakhimov/scram .. _AppVeyor: https://ci.appveyor.com/project/rakhimov/scram diff -Nru scram-0.16.1/doc/design_description.rst scram-0.16.2/doc/design_description.rst --- scram-0.16.1/doc/design_description.rst 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/doc/design_description.rst 2018-01-12 11:42:47.000000000 +0000 @@ -95,6 +95,4 @@ cppdep Component Dependency Report ================================== -.. image:: ../build/scram_core.svg - .. literalinclude:: ../build/dep_report.txt diff -Nru scram-0.16.1/doc/release/v0.16.2.md scram-0.16.2/doc/release/v0.16.2.md --- scram-0.16.1/doc/release/v0.16.2.md 1970-01-01 00:00:00.000000000 +0000 +++ scram-0.16.2/doc/release/v0.16.2.md 2018-01-12 11:42:47.000000000 +0000 @@ -0,0 +1,29 @@ +# Release Notes v0.16.2 : Transition to C++17 + +With this release, the codebase transitions to C++17, +requiring more modern compilers (gcc 7, clang 5) and dependencies. + + +## Minor Changes + +- Transition to C++17 (#250) +- Replace header guards w/ '#pragma once' (#253) +- Replace Nose w/ Pytest (#252) +- Replace GoogleTest w/ Catch2 (#251) + + +## Removed Features + +- Non-MEF, API-only random deviates (use STL or Boost ``random`` directly). + + +## Since v0.16.1 + +80 commits resulted in 193 files changed, 3321 insertions(+), 4040 deletions(-) + +- Core: 96 files changed, 1061 insertions(+), 1613 deletions(-) +- Scripts: 1 file changed, 111 insertions(+), 88 deletions(-) +- GUI: 39 files changed, 240 insertions(+), 443 deletions(-) +- Tests: 40 files changed, 1724 insertions(+), 1727 deletions(-) +- Documentation: 4 files changed, 41 insertions(+), 61 deletions(-) +- Schemas: No change diff -Nru scram-0.16.1/doc/uncertainty_analysis.rst scram-0.16.2/doc/uncertainty_analysis.rst --- scram-0.16.1/doc/uncertainty_analysis.rst 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/doc/uncertainty_analysis.rst 2018-01-12 11:42:47.000000000 +0000 @@ -27,6 +27,8 @@ but this parameter can be changed by a user, for example, to test the analysis tool. +Available statistical distributions are specified in Open-PSA [MEF]_. + .. _MT 19937: https://en.wikipedia.org/wiki/Mersenne_twister @@ -45,26 +47,6 @@ mean, sigma, quantiles, probability density histogram. -Statistical Distributions -------------------------- - -- Uniform -- Triangular (only via API) -- Piecewise Linear (only via API) -- Histogram -- Discrete (only via API) -- Normal -- Log-Normal -- Poisson (only via API) -- Binomial (only via API) -- Beta -- Gamma -- Weibull -- Exponential (only via API) -- Log-Uniform (only via API) -- Log-Triangular (only via API) - - Adjustment of Invalid Samples ----------------------------- diff -Nru scram-0.16.1/Dockerfile scram-0.16.2/Dockerfile --- scram-0.16.1/Dockerfile 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/Dockerfile 2018-01-12 11:42:47.000000000 +0000 @@ -1,8 +1,19 @@ -FROM alpine:edge -RUN apk add --update --no-cache g++ make cmake binutils boost-dev jemalloc-dev \ - libxml2-dev +FROM ubuntu:17.10 +ENV BUILD_PACKAGES \ + make cmake g++ libxml2-dev \ + libgoogle-perftools-dev libboost-program-options-dev \ + libboost-math-dev libboost-random-dev libboost-filesystem-dev \ + libboost-date-time-dev +ENV RUNTIME_PACKAGES \ + libxml2 libboost-filesystem1.62.0 libboost-program-options1.62.0 \ + libtcmalloc-minimal4 ADD . scram/ -RUN cd scram && mkdir -p build && cd build && \ - cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_GUI=OFF && make install -RUN rm -rf scram /var/cache/* +RUN apt-get update && \ + apt-get install -y --no-install-recommends $BUILD_PACKAGES && \ + cd scram && mkdir -p build && cd build && \ + cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_GUI=OFF && make install && \ + cd ../.. && rm -rf ./scram && \ + apt-get remove --purge -y $BUILD_PACKAGES $(apt-mark showauto) && \ + apt-get install -y --no-install-recommends $RUNTIME_PACKAGES && \ + rm -rf /var/lib/apt/lists/* ENTRYPOINT ["scram"] diff -Nru scram-0.16.1/.gitignore scram-0.16.2/.gitignore --- scram-0.16.1/.gitignore 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/.gitignore 2018-01-12 11:42:47.000000000 +0000 @@ -20,3 +20,6 @@ # Python compiled files *.pyc + +# Pytest cache +.cache diff -Nru scram-0.16.1/.gitmodules scram-0.16.2/.gitmodules --- scram-0.16.1/.gitmodules 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/.gitmodules 2018-01-12 11:42:47.000000000 +0000 @@ -1,9 +1,9 @@ -[submodule "tests/googletest"] - path = tests/googletest - url = https://github.com/rakhimov/googletest [submodule "scripts/translators"] path = scripts/translators url = https://github.com/rakhimov/translators [submodule "gui/qtango"] path = gui/qtango url = https://github.com/rakhimov/qtango +[submodule "tests/catch2"] + path = tests/catch2 + url = https://github.com/catchorg/Catch2 diff -Nru scram-0.16.1/gui/align.h scram-0.16.2/gui/align.h --- scram-0.16.1/gui/align.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/align.h 2018-01-12 11:42:47.000000000 +0000 @@ -18,18 +18,13 @@ /// @file /// Text alignment common conventions. -#include +#pragma once -#ifndef ALIGN_H -#define ALIGN_H +#include -namespace scram { -namespace gui { +namespace scram::gui { /// Default alignment of numerical values in tables. const int ALIGN_NUMBER_IN_TABLE = Qt::AlignRight | Qt::AlignVCenter; -} // namespace gui -} // namespace scram - -#endif // ALIGN_H +} // namespace scram::gui diff -Nru scram-0.16.1/gui/CMakeLists.txt scram-0.16.2/gui/CMakeLists.txt --- scram-0.16.1/gui/CMakeLists.txt 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/CMakeLists.txt 2018-01-12 11:42:47.000000000 +0000 @@ -3,27 +3,12 @@ # Qt5 with Homebrew. list(APPEND CMAKE_PREFIX_PATH /usr/local/opt/qt5) endif() -find_package(Qt5 "5.2.1" REQUIRED COMPONENTS +find_package(Qt5 "5.9.1" REQUIRED COMPONENTS Core Widgets Svg OpenGL PrintSupport Concurrent ) message(STATUS "Found Qt5") message(STATUS "Qt5 Version: ${Qt5_VERSION}") -# Prevent implicit QString(const char*), string concat with "+", and other anti-patterns. -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII -DQT_NO_CAST_FROM_BYTEARRAY -DQT_NO_URL_CAST_FROM_STRING -DQT_USE_QSTRINGBUILDER") - -if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - # TODO: MOC generated code has some useless casts. - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wno-useless-cast") -elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") - # TODO: Qt moc offsetof applied to non-POD types is nonstandard. - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -diag-disable=1875") -elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - if(Qt5Widgets_VERSION_STRING VERSION_LESS 5.4) - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wno-inconsistent-missing-override") - endif() -endif() - set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) @@ -70,6 +55,11 @@ target_link_libraries(scram-gui ${LIBS} scram Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Svg Qt5::OpenGL Qt5::PrintSupport Qt5::Concurrent) +target_compile_options(scram-gui PUBLIC $<$:${SCRAM_CXX_FLAGS_DEBUG} -Wno-useless-cast>) # TODO: MOC failure. +# Prevent implicit QString(const char*), string concat with "+", and other anti-patterns. +target_compile_definitions(scram-gui PRIVATE + $<$:QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_BYTEARRAY QT_NO_URL_CAST_FROM_STRING QT_USE_QSTRINGBUILDER> + ) add_executable(scram-gui-bin WIN32 main.cpp scram.rc ${SCRAM_GUI_RES}) set_target_properties(scram-gui-bin PROPERTIES OUTPUT_NAME scram-gui) @@ -81,24 +71,26 @@ ) if(UNIX AND NOT APPLE) - foreach (size IN ITEMS 32 128) + foreach(size IN ITEMS 32 128) install( FILES images/scram_solid${size}x${size}.png DESTINATION share/icons/hicolor/${size}x${size}/apps - COMPONENT gui + COMPONENT gui RENAME scram.png) - endforeach () + endforeach() + install( FILES images/scram_solid.svg DESTINATION share/icons/hicolor/scalable/apps - COMPONENT gui + COMPONENT gui RENAME scram.svg) # Install a desktop file # so that SCRAM appears in the application start menu with an icon. - install(FILES scram-gui.desktop + install( + FILES scram-gui.desktop DESTINATION share/applications - COMPONENT gui) + COMPONENT gui) endif() if(PACKAGE) @@ -116,7 +108,8 @@ set(_qt_plugin_dir "plugins") endif() set(_qt_plugin_dest "${_qt_plugin_dir}/${_qt_plugin_type}") - install(FILES "${_qt_plugin_path}" + install( + FILES "${_qt_plugin_path}" DESTINATION "${_qt_plugin_dest}" COMPONENT gui) set(${_qt_plugins_var} @@ -138,7 +131,8 @@ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf" "[Paths]\nPlugins = ../${_qt_plugin_dir}\nTranslations = ../translations\n") - install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf" + install( + FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf" DESTINATION bin COMPONENT gui) endif() diff -Nru scram-0.16.1/gui/command.h scram-0.16.2/gui/command.h --- scram-0.16.1/gui/command.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/command.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -42,15 +42,13 @@ /// after its corresponding constructive/destructive commands are destroyed /// (e.g., by being popped/removed from the undo stack). -#ifndef COMMAND_H -#define COMMAND_H +#pragma once #include #include -namespace scram { -namespace gui { +namespace scram::gui { /// The function inverse is the function itself (i.e., f(f(x)) = id(x)). /// In other words, undo and redo codes are exactly the same, @@ -74,7 +72,7 @@ template class Inverse : public T { - static_assert(std::is_base_of::value, ""); + static_assert(std::is_base_of_v); public: /// Applies the command. @@ -87,7 +85,4 @@ using T::T; }; -} // namespace gui -} // namespace scram - -#endif // COMMAND_H +} // namespace scram::gui diff -Nru scram-0.16.1/gui/diagram.cpp scram-0.16.2/gui/diagram.cpp --- scram-0.16.1/gui/diagram.cpp 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/diagram.cpp 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2017 Olzhas Rakhimov + * Copyright (C) 2016-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -42,9 +42,7 @@ #include "guiassert.h" #include "overload.h" -namespace scram { -namespace gui { -namespace diagram { +namespace scram::gui::diagram { const QSizeF Event::m_size = {16, 11}; const double Event::m_baseHeight = 6.5; @@ -224,7 +222,7 @@ double linkY = (m_size.height() - 1) * units().height(); std::vector> children; for (const mef::Formula::EventArg &eventArg : event->args()) { - auto *child = boost::apply_visitor(formula_visitor, eventArg); + auto *child = std::visit(formula_visitor, eventArg); auto *link = new QGraphicsLineItem(0, 0, 0, units().height(), this); if (!children.empty()) m_width += m_space * units().height(); @@ -417,7 +415,7 @@ connect(gate, &model::Gate::formulaChanged, this, &DiagramScene::redraw, Qt::UniqueConnection); for (const mef::Formula::EventArg &arg : gate->args()) - boost::apply_visitor(visitor, arg); + std::visit(visitor, arg); }; /// @todo Finer signal tracking. @@ -426,6 +424,4 @@ link(m_model->gates().find(entry.first)->get()); } -} // namespace diagram -} // namespace gui -} // namespace scram +} // namespace scram::gui::diagram diff -Nru scram-0.16.1/gui/diagram.h scram-0.16.2/gui/diagram.h --- scram-0.16.1/gui/diagram.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/diagram.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2017 Olzhas Rakhimov + * Copyright (C) 2016-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,7 @@ /// @file /// Graphics classes to draw diagrams. -#ifndef DIAGRAM_H -#define DIAGRAM_H +#pragma once #include #include @@ -32,9 +31,7 @@ #include "model.h" -namespace scram { -namespace gui { -namespace diagram { +namespace scram::gui::diagram { /// The base class for probabilistic events in a fault tree. /// @@ -207,8 +204,4 @@ model::Model *m_model; ///< The proxy model providing change signals. }; -} // namespace diagram -} // namespace gui -} // namespace scram - -#endif // DIAGRAM_H +} // namespace scram::gui::diagram diff -Nru scram-0.16.1/gui/elementcontainermodel.cpp scram-0.16.2/gui/elementcontainermodel.cpp --- scram-0.16.1/gui/elementcontainermodel.cpp 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/elementcontainermodel.cpp 2018-01-12 11:42:47.000000000 +0000 @@ -27,9 +27,7 @@ #include "guiassert.h" #include "overload.h" -namespace scram { -namespace gui { -namespace model { +namespace scram::gui::model { template ElementContainerModel::ElementContainerModel(const T &container, Model *model, @@ -404,6 +402,4 @@ return QSortFilterProxyModel::lessThan(lhs, rhs); } -} // namespace model -} // namespace gui -} // namespace scram +} // namespace scram::gui::model diff -Nru scram-0.16.1/gui/elementcontainermodel.h scram-0.16.2/gui/elementcontainermodel.h --- scram-0.16.1/gui/elementcontainermodel.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/elementcontainermodel.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,7 @@ /// @file /// The table model for elements. -#ifndef ELEMENTCONTAINERMODEL_H -#define ELEMENTCONTAINERMODEL_H +#pragma once #include @@ -34,9 +33,7 @@ #include "model.h" -namespace scram { -namespace gui { -namespace model { +namespace scram::gui::model { /// The base class for models to list elements in a table. /// @@ -216,8 +213,4 @@ /// @} }; -} // namespace model -} // namespace gui -} // namespace scram - -#endif // ELEMENTCONTAINERMODEL_H +} // namespace scram::gui::model diff -Nru scram-0.16.1/gui/eventdialog.cpp scram-0.16.2/gui/eventdialog.cpp --- scram-0.16.1/gui/eventdialog.cpp 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/eventdialog.cpp 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -39,8 +39,7 @@ #include "overload.h" #include "validator.h" -namespace scram { -namespace gui { +namespace scram::gui { QString EventDialog::redBackground(QStringLiteral("background : red;")); QString EventDialog::yellowBackground(QStringLiteral("background : yellow;")); @@ -211,7 +210,7 @@ for (const mef::Formula::EventArg &arg : gate->formula().event_args()) { if (ext::as(arg) == m_event) return true; - if (boost::apply_visitor(visitor, arg)) + if (std::visit(visitor, arg)) return true; } return false; @@ -273,7 +272,7 @@ { setupData(element, element.data()); typeBox->setCurrentIndex(ext::one_bit_index(BasicEvent) + element.flavor()); - auto &basicEvent = static_cast(*element.data()); + const mef::BasicEvent &basicEvent = *element.data(); if (basicEvent.HasExpression()) { expressionBox->setChecked(true); if (auto *constExpr = dynamic_cast( @@ -508,5 +507,4 @@ addArgLine->setCompleter(completer); } -} // namespace gui -} // namespace scram +} // namespace scram::gui diff -Nru scram-0.16.1/gui/eventdialog.h scram-0.16.2/gui/eventdialog.h --- scram-0.16.1/gui/eventdialog.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/eventdialog.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,7 @@ /// @file /// Dialog to edit and validate events. -#ifndef EVENTDIALOG_H -#define EVENTDIALOG_H +#pragma once #include #include @@ -38,8 +37,7 @@ #include "model.h" -namespace scram { -namespace gui { +namespace scram::gui { /// The Dialog to create, present, and manipulate event data. /// @@ -195,7 +193,4 @@ bool m_fixContainerName = false; ///< @todo Implement fault tree change. }; -} // namespace gui -} // namespace scram - -#endif // EVENTDIALOG_H +} // namespace scram::gui diff -Nru scram-0.16.1/gui/guiassert.h scram-0.16.2/gui/guiassert.h --- scram-0.16.1/gui/guiassert.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/guiassert.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,7 @@ /// @file /// GUI assertions that should not crash the program by default. -#ifndef GUIASSERT_H -#define GUIASSERT_H +#pragma once #include #include @@ -45,5 +44,3 @@ QString::number(__LINE__))); \ return ret; \ } while (false) - -#endif // GUIASSERT_H diff -Nru scram-0.16.1/gui/importancetablemodel.cpp scram-0.16.2/gui/importancetablemodel.cpp --- scram-0.16.1/gui/importancetablemodel.cpp 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/importancetablemodel.cpp 2018-01-12 11:42:47.000000000 +0000 @@ -24,9 +24,7 @@ #include "align.h" #include "guiassert.h" -namespace scram { -namespace gui { -namespace model { +namespace scram::gui::model { ImportanceTableModel::ImportanceTableModel( const std::vector *data, QObject *parent) @@ -108,6 +106,4 @@ GUI_ASSERT(false && "unexpected column", {}); } -} // namespace model -} // namespace gui -} // namespace scram +} // namespace scram::gui::model diff -Nru scram-0.16.1/gui/importancetablemodel.h scram-0.16.2/gui/importancetablemodel.h --- scram-0.16.1/gui/importancetablemodel.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/importancetablemodel.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,7 @@ /// @file /// Table model for reporting importance factors. -#ifndef IMPORTANCETABLEMODEL_H -#define IMPORTANCETABLEMODEL_H +#pragma once #include @@ -27,9 +26,7 @@ #include "src/importance_analysis.h" -namespace scram { -namespace gui { -namespace model { +namespace scram::gui::model { /// Table model wrapping the importance analysis result data. /// @@ -60,8 +57,4 @@ const std::vector &m_data; ///< The analysis result. }; -} // namespace model -} // namespace gui -} // namespace scram - -#endif // IMPORTANCETABLEMODEL_H +} // namespace scram::gui::model diff -Nru scram-0.16.1/gui/language.cpp scram-0.16.2/gui/language.cpp --- scram-0.16.1/gui/language.cpp 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/language.cpp 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -31,12 +31,11 @@ #include "guiassert.h" -namespace scram { -namespace gui { +namespace scram::gui { const std::string &translationsPath() { - static const std::string tsPath(scram::Env::install_dir() + static const std::string tsPath(scram::env::install_dir() + "/share/scram/translations"); return tsPath; } @@ -78,5 +77,4 @@ return language; } -} // namespace gui -} // namespace scram +} // namespace scram::gui diff -Nru scram-0.16.1/gui/language.h scram-0.16.2/gui/language.h --- scram-0.16.1/gui/language.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/language.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,16 +18,14 @@ /// @file /// Localization and translation facilities. -#ifndef LANGUAGE_H -#define LANGUAGE_H +#pragma once #include #include #include -namespace scram { -namespace gui { +namespace scram::gui { /// @returns The path to SCRAM GUI translations directory. const std::string &translationsPath(); @@ -45,7 +43,4 @@ /// @pre The locale language is a valid human language (not "C"). QString nativeLanguageName(const std::string &locale); -} // namespace gui -} // namespace scram - -#endif // LANGUAGE_H +} // namespace scram::gui diff -Nru scram-0.16.1/gui/main.cpp scram-0.16.2/gui/main.cpp --- scram-0.16.1/gui/main.cpp 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/main.cpp 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2017 Olzhas Rakhimov + * Copyright (C) 2015-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,6 @@ /// @file /// The main entrance to the SCRAM GUI. -#include - #include #include #include diff -Nru scram-0.16.1/gui/mainwindow.cpp scram-0.16.2/gui/mainwindow.cpp --- scram-0.16.1/gui/mainwindow.cpp 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/mainwindow.cpp 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2017 Olzhas Rakhimov + * Copyright (C) 2015-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -66,8 +66,7 @@ #include "settingsdialog.h" #include "validator.h" -namespace scram { -namespace gui { +namespace scram::gui { /// The dialog to set the model name. class NameDialog : public QDialog, public Ui::NameDialog @@ -100,9 +99,8 @@ explicit WaitDialog(QWidget *parent) : QProgressDialog(parent) { setFixedSize(size()); - setWindowFlags(static_cast( - windowFlags() | Qt::MSWindowsFixedSizeDialogHint - | Qt::FramelessWindowHint)); + setWindowFlags(windowFlags() | Qt::MSWindowsFixedSizeDialogHint + | Qt::FramelessWindowHint); setCancelButton(nullptr); setRange(0, 0); setMinimumDuration(0); @@ -288,7 +286,7 @@ bool MainWindow::addInputFiles(const std::vector &inputFiles) { - static xml::Validator validator(Env::install_dir() + static xml::Validator validator(env::install_dir() + "/share/scram/gui.rng"); if (inputFiles.empty()) @@ -583,7 +581,7 @@ { auto *startPage = new StartPage(this); QString examplesDir = - QString::fromStdString(Env::install_dir() + "/share/scram/input"); + QString::fromStdString(env::install_dir() + "/share/scram/input"); startPage->exampleModelsButton->setEnabled(QDir(examplesDir).exists()); connect(startPage->newModelButton, &QAbstractButton::clicked, ui->actionNewModel, &QAction::trigger); @@ -890,7 +888,7 @@ template void MainWindow::setupPrintableView(T *view) { - static_assert(std::is_base_of::value, "Missing QObject"); + static_assert(std::is_base_of_v, "Missing QObject"); struct PrintFilter : public QObject { PrintFilter(T *printable, MainWindow *window) @@ -1656,5 +1654,4 @@ m_analysis = std::move(analysis); } -} // namespace gui -} // namespace scram +} // namespace scram::gui diff -Nru scram-0.16.1/gui/mainwindow.h scram-0.16.2/gui/mainwindow.h --- scram-0.16.1/gui/mainwindow.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/mainwindow.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2017 Olzhas Rakhimov + * Copyright (C) 2015-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,7 @@ /// @file /// The main application window. -#ifndef MAINWINDOW_H -#define MAINWINDOW_H +#pragma once #include #include @@ -49,8 +48,7 @@ class MainWindow; } -namespace scram { -namespace gui { +namespace scram::gui { class EventDialog; ///< @todo Static build issues if the header is included. @@ -306,7 +304,4 @@ std::unique_ptr m_analysis; ///< Report container. }; -} // namespace gui -} // namespace scram - -#endif // MAINWINDOW_H +} // namespace scram::gui diff -Nru scram-0.16.1/gui/model.cpp scram-0.16.2/gui/model.cpp --- scram-0.16.1/gui/model.cpp 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/model.cpp 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,9 +25,7 @@ #include "guiassert.h" -namespace scram { -namespace gui { -namespace model { +namespace scram::gui::model { Element::SetLabel::SetLabel(Element *element, QString label) : Involution(QObject::tr("Set element '%1' label to '%2'") @@ -224,6 +222,4 @@ { } -} // namespace model -} // namespace gui -} // namespace scram +} // namespace scram::gui::model diff -Nru scram-0.16.1/gui/model.h scram-0.16.2/gui/model.h --- scram-0.16.1/gui/model.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/model.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,7 @@ /// @file /// Wrapper Model classes for the MEF data. -#ifndef MODEL_H -#define MODEL_H +#pragma once #include #include @@ -41,9 +40,7 @@ #include "command.h" -namespace scram { -namespace gui { -namespace model { +namespace scram::gui::model { /// Fault tree container element management assuming normalized model. /// @{ @@ -218,11 +215,16 @@ /// @returns The probability value of the event. /// - /// @pre The basic event has expression. + /// @pre The basic event has expression or the type has null state. template T probability() const { - return data()->p(); + if constexpr (std::is_same_v) { + return data()->HasExpression() ? QVariant(data()->p()) : QVariant(); + + } else { + return data()->p(); + } } /// Sets the basic event expression. @@ -272,11 +274,10 @@ Flavor m_flavor; ///< The current flavor of the basic event. }; -/// @returns The optional probability value of the basic event. -template <> -inline QVariant BasicEvent::probability() const +/// Converts Boolean value to a UI string. +inline QString boolToString(bool value) { - return data()->HasExpression() ? QVariant(probability()) : QVariant(); + return value ? QObject::tr("True") : QObject::tr("False"); } /// The proxy to manage mef::HouseEvent. @@ -292,7 +293,12 @@ template T state() const { - return data()->state(); + if constexpr (std::is_same_v) { + return boolToString(state()); + + } else { + return data()->state(); + } } /// Flips the house event state. @@ -314,19 +320,6 @@ void stateChanged(bool value); }; -/// Converts Boolean value to a UI string. -inline QString boolToString(bool value) -{ - return value ? QObject::tr("True") : QObject::tr("False"); -} - -/// @returns The string representation of the house event state. -template <> -inline QString HouseEvent::state() const -{ - return boolToString(state()); -} - /// The proxy to manage mef::Gate. /// /// @pre The gate formula is flat. @@ -342,7 +335,34 @@ template T type() const { - return data()->formula().type(); + if constexpr (std::is_same_v) { + switch (type()) { + case mef::kAnd: + return tr("and"); + case mef::kOr: + return tr("or"); + case mef::kVote: + //: Also named as 'vote', 'voting or', 'combination', 'combo'. + return tr("at-least %1").arg(voteNumber()); + case mef::kXor: + return tr("xor"); + case mef::kNot: + return tr("not"); + case mef::kNull: + //: This is 'pass-through' or 'no-action' gate type. + return tr("null"); + case mef::kNand: + //: not and. + return tr("nand"); + case mef::kNor: + //: not or. + return tr("nor"); + } + assert(false); + + } else { + return data()->formula().type(); + } } /// @returns The number of gate arguments. @@ -380,35 +400,6 @@ void formulaChanged(); }; -/// @returns The UI string representation for gate connective types. -template <> -inline QString Gate::type() const -{ - switch (type()) { - case mef::kAnd: - return tr("and"); - case mef::kOr: - return tr("or"); - case mef::kVote: - //: Also named as 'vote', 'voting or', 'combination', 'combo'. - return tr("at-least %1").arg(voteNumber()); - case mef::kXor: - return tr("xor"); - case mef::kNot: - return tr("not"); - case mef::kNull: - //: This is 'pass-through' or 'no-action' gate type. - return tr("null"); - case mef::kNand: - //: not and. - return tr("nand"); - case mef::kNor: - //: not or. - return tr("nor"); - } - assert(false); -} - /// Table of proxy elements uniquely wrapping the core model element. /// /// @tparam T The proxy type. @@ -440,7 +431,19 @@ /// Generic access to event tables. template - ProxyTable &table(); + ProxyTable &table() + { + if constexpr (std::is_same_v) { + return m_gates; + + } else if constexpr (std::is_same_v) { + return m_basicEvents; + + } else { + static_assert(std::is_same_v, "Unknown type."); + return m_houseEvents; + } + } /// @param[in] event The event defined/registered in the model. /// @@ -570,7 +573,7 @@ template class RemoveEvent : public Inverse> { - static_assert(std::is_base_of::value, ""); + static_assert(std::is_base_of_v); public: /// Stores model containers and the existing event for removal. @@ -589,9 +592,9 @@ template class ChangeEventType : public QUndoCommand { - static_assert(!std::is_same::value, ""); - static_assert(std::is_base_of::value, ""); - static_assert(std::is_base_of::value, ""); + static_assert(!std::is_same_v); + static_assert(std::is_base_of_v); + static_assert(std::is_base_of_v); public: /// Assumes that events have the same ID. @@ -701,27 +704,4 @@ /// @} }; -/// Specializations for the typed access to the proxy model container. -/// @{ -template <> -inline ProxyTable &Model::table() -{ - return m_gates; -} -template <> -inline ProxyTable &Model::table() -{ - return m_basicEvents; -} -template <> -inline ProxyTable &Model::table() -{ - return m_houseEvents; -} -/// @} - -} // namespace model -} // namespace gui -} // namespace scram - -#endif // MODEL_H +} // namespace scram::gui::model diff -Nru scram-0.16.1/gui/modeltree.cpp scram-0.16.2/gui/modeltree.cpp --- scram-0.16.1/gui/modeltree.cpp 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/modeltree.cpp 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,8 +22,7 @@ #include "guiassert.h" #include "overload.h" -namespace scram { -namespace gui { +namespace scram::gui { ModelTree::ModelTree(model::Model *model, QObject *parent) : QAbstractItemModel(parent), m_model(model) @@ -139,5 +138,4 @@ GUI_ASSERT(false, {}); } -} // namespace gui -} // namespace scram +} // namespace scram::gui diff -Nru scram-0.16.1/gui/modeltree.h scram-0.16.2/gui/modeltree.h --- scram-0.16.1/gui/modeltree.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/modeltree.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,7 @@ /// @file /// The main tree representation of the Model. -#ifndef MODELTREE_H -#define MODELTREE_H +#pragma once #include @@ -30,8 +29,7 @@ #include "model.h" -namespace scram { -namespace gui { +namespace scram::gui { /// The tree representation for the Model constructs. class ModelTree : public QAbstractItemModel @@ -89,7 +87,4 @@ boost::container::flat_set m_faultTrees; }; -} // namespace gui -} // namespace scram - -#endif // MODELTREE_H +} // namespace scram::gui diff -Nru scram-0.16.1/gui/preferencesdialog.cpp scram-0.16.2/gui/preferencesdialog.cpp --- scram-0.16.1/gui/preferencesdialog.cpp 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/preferencesdialog.cpp 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,8 +33,7 @@ #include "language.h" #include "overload.h" -namespace scram { -namespace gui { +namespace scram::gui { PreferencesDialog::PreferencesDialog(QSettings *preferences, QUndoStack *undoStack, @@ -137,5 +136,4 @@ }); } -} // namespace gui -} // namespace scram +} // namespace scram::gui diff -Nru scram-0.16.1/gui/preferencesdialog.h scram-0.16.2/gui/preferencesdialog.h --- scram-0.16.1/gui/preferencesdialog.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/preferencesdialog.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,7 @@ /// @file /// Dialog to manage the application's persistent preferences. -#ifndef PREFERENCESDIALOG_H -#define PREFERENCESDIALOG_H +#pragma once #include @@ -32,8 +31,7 @@ class PreferencesDialog; } -namespace scram { -namespace gui { +namespace scram::gui { /// The dialog to present and manage GUI application preferences. /// @@ -70,7 +68,4 @@ QSettings *m_preferences; ///< The persistent preferences to be saved. }; -} // namespace gui -} // namespace scram - -#endif // PREFERENCESDIALOG_H +} // namespace scram::gui diff -Nru scram-0.16.1/gui/printable.cpp scram-0.16.2/gui/printable.cpp --- scram-0.16.1/gui/printable.cpp 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/printable.cpp 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,8 +24,7 @@ #include #include -namespace scram { -namespace gui { +namespace scram::gui { void Printable::print() { @@ -44,5 +43,4 @@ preview.exec(); } -} // namespace gui -} // namespace scram +} // namespace scram::gui diff -Nru scram-0.16.1/gui/printable.h scram-0.16.2/gui/printable.h --- scram-0.16.1/gui/printable.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/printable.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,13 +18,11 @@ /// @file /// Interface for printable objects. -#ifndef PRINTABLE_H -#define PRINTABLE_H +#pragma once #include -namespace scram { -namespace gui { +namespace scram::gui { /// An abstract mixin class for printable objects. class Printable @@ -43,7 +41,4 @@ virtual void doPrint(QPrinter *printer) = 0; }; -} // namespace gui -} // namespace scram - -#endif // PRINTABLE_H +} // namespace scram::gui diff -Nru scram-0.16.1/gui/producttablemodel.cpp scram-0.16.2/gui/producttablemodel.cpp --- scram-0.16.1/gui/producttablemodel.cpp 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/producttablemodel.cpp 2018-01-12 11:42:47.000000000 +0000 @@ -24,9 +24,7 @@ #include "align.h" #include "guiassert.h" -namespace scram { -namespace gui { -namespace model { +namespace scram::gui::model { ProductTableModel::ProductTableModel(const core::ProductContainer &products, bool withProbability, QObject *parent) @@ -112,6 +110,4 @@ GUI_ASSERT(false && "unexpected column", {}); } -} // namespace model -} // namespace gui -} // namespace scram +} // namespace scram::gui::model diff -Nru scram-0.16.1/gui/producttablemodel.h scram-0.16.2/gui/producttablemodel.h --- scram-0.16.1/gui/producttablemodel.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/producttablemodel.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,7 @@ /// @file /// Table model for reporting products. -#ifndef PRODUCTTABLEMODEL_H -#define PRODUCTTABLEMODEL_H +#pragma once #include @@ -27,9 +26,7 @@ #include "src/fault_tree_analysis.h" -namespace scram { -namespace gui { -namespace model { +namespace scram::gui::model { /// The table model for immutable analysis products. class ProductTableModel : public QAbstractTableModel @@ -71,8 +68,4 @@ bool m_withProbability; ///< The flag for probability data inclusion. }; -} // namespace model -} // namespace gui -} // namespace scram - -#endif // PRODUCTTABLEMODEL_H +} // namespace scram::gui::model diff -Nru scram-0.16.1/gui/reporttree.cpp scram-0.16.2/gui/reporttree.cpp --- scram-0.16.1/gui/reporttree.cpp 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/reporttree.cpp 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,8 +23,7 @@ #include "guiassert.h" -namespace scram { -namespace gui { +namespace scram::gui { ReportTree::ReportTree(const std::vector *results, QObject *parent) @@ -100,8 +99,7 @@ if (!index.parent().isValid()) { GUI_ASSERT(index.row() < m_results.size(), {}); - return boost::apply_visitor(nameExtractor, - m_results[index.row()].id.target); + return std::visit(nameExtractor, m_results[index.row()].id.target); } GUI_ASSERT(index.parent().row() < m_results.size(), {}); const core::RiskAnalysis::Result &result = m_results[index.parent().row()]; @@ -121,5 +119,4 @@ GUI_ASSERT(false && "Unexpected analysis report data", {}); } -} // namespace gui -} // namespace scram +} // namespace scram::gui diff -Nru scram-0.16.1/gui/reporttree.h scram-0.16.2/gui/reporttree.h --- scram-0.16.1/gui/reporttree.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/reporttree.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,7 @@ /// @file /// Report tree model to represent the analysis results. -#ifndef REPORTTREE_H -#define REPORTTREE_H +#pragma once #include @@ -27,8 +26,7 @@ #include "src/risk_analysis.h" -namespace scram { -namespace gui { +namespace scram::gui { /// The report is organized by its top items as analysis identifiers /// and its descendant items as analysis result types. @@ -67,7 +65,4 @@ const std::vector &m_results; ///< The data. }; -} // namespace gui -} // namespace scram - -#endif // REPORTTREE_H +} // namespace scram::gui diff -Nru scram-0.16.1/gui/settingsdialog.cpp scram-0.16.2/gui/settingsdialog.cpp --- scram-0.16.1/gui/settingsdialog.cpp 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/settingsdialog.cpp 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,8 +24,7 @@ #include "guiassert.h" -namespace scram { -namespace gui { +namespace scram::gui { SettingsDialog::SettingsDialog(const core::Settings &initSettings, QWidget *parent) @@ -138,5 +137,4 @@ }); } -} // namespace gui -} // namespace scram +} // namespace scram::gui diff -Nru scram-0.16.1/gui/settingsdialog.h scram-0.16.2/gui/settingsdialog.h --- scram-0.16.1/gui/settingsdialog.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/settingsdialog.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,7 @@ /// @file /// Dialog to manage analysis settings. -#ifndef SETTINGSDIALOG_H -#define SETTINGSDIALOG_H +#pragma once #include @@ -31,8 +30,7 @@ class SettingsDialog; } -namespace scram { -namespace gui { +namespace scram::gui { /// The dialog to present and set analysis settings. class SettingsDialog : public QDialog @@ -59,7 +57,4 @@ std::unique_ptr ui; ///< The dialog UI. }; -} // namespace gui -} // namespace scram - -#endif // SETTINGSDIALOG_H +} // namespace scram::gui diff -Nru scram-0.16.1/gui/tests/CMakeLists.txt scram-0.16.2/gui/tests/CMakeLists.txt --- scram-0.16.1/gui/tests/CMakeLists.txt 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/tests/CMakeLists.txt 2018-01-12 11:42:47.000000000 +0000 @@ -1,8 +1,5 @@ find_package(Qt5Test REQUIRED) -# There are no tr() strings in test, so no need to be strict with string construction. -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -UQT_NO_CAST_FROM_ASCII") - macro(TEST NAME FILE) add_executable(scramgui_${NAME} ${FILE}) target_link_libraries(scramgui_${NAME} scram-gui Qt5::Test) diff -Nru scram-0.16.1/gui/tests/data.h scram-0.16.2/gui/tests/data.h --- scram-0.16.1/gui/tests/data.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/tests/data.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,27 +15,15 @@ * along with this program. If not, see . */ -#ifndef SCRAM_GUI_TEST_DATA_H -#define SCRAM_GUI_TEST_DATA_H +#pragma once #include +#include #include namespace detail { -/// Tuple with implicit constructor for convenience sake. -/// -/// @todo Not necessary in C++17. -template -struct tuple : public std::tuple -{ - template - constexpr tuple(Us &&... us) : std::tuple(std::forward(us)...) - { - } -}; - /// Initializes columns in the test data table. /// /// @tparam Ts void terminated type list. @@ -43,36 +31,24 @@ void initializeColumns(const char *const *it) { QTest::addColumn(*it); - initializeColumns(++it); -} -/// Terminal case for test column initialization. -template <> -inline void initializeColumns(const char *const *) -{ + if constexpr (sizeof...(Ts)) + initializeColumns(++it); } +/// Initializes rows in the test data table. +/// /// @tparam N The number of columns to initialize in the row. -template -struct RowInitializer +template +void initializeRows(QTestData &data, const std::tuple &row) { - template - void operator()(QTestData &data, const std::tuple &row) - { - RowInitializer{}(data, row); - data << std::get(row); - } -}; + static_assert(N >= 0); -/// Terminal case for row initialization. -template <> -struct RowInitializer<0> -{ - template - void operator()(QTestData &, const std::tuple &) - { + if constexpr (N != 0) { + initializeRows(data, row); + data << std::get(row); } -}; +} } // namespace detail @@ -83,15 +59,12 @@ /// @param[in] columns The column names. /// @param[in] rows The row name and data. template -void populateData( - const char *const (&columns)[sizeof...(Ts)], - std::initializer_list> rows) +void populateData(const char *const (&columns)[sizeof...(Ts)], + std::initializer_list> rows) { - detail::initializeColumns(columns); + detail::initializeColumns(columns); for (const auto &row : rows) - detail::RowInitializer{}(QTest::newRow(std::get<0>(row)), - row); + detail::initializeRows(QTest::newRow(std::get<0>(row)), + row); } - -#endif // SCRAM_GUI_TEST_DATA_H diff -Nru scram-0.16.1/gui/tests/help.h scram-0.16.2/gui/tests/help.h --- scram-0.16.1/gui/tests/help.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/tests/help.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,7 @@ /// @file /// Helper workarounds or additions to Qt Test. -#ifndef SCRAM_GUI_TEST_HELP_H -#define SCRAM_GUI_TEST_HELP_H +#pragma once #include #include @@ -87,20 +86,9 @@ connect(sender, sig, this, &SignalSpy::accept, Qt::DirectConnection); } - SignalSpy(SignalSpy &&); ///< Only to enable RVO. Undefined. - private: /// Stores the signal arguments. void accept(Ts... args) { this->emplace_back(args...); } }; -/// Convenience function to construct a SignalSpy with deduced types. -template -auto make_spy(const T *sender, void (U::*sig)(Ts...)) -{ - return SignalSpy(sender, sig); -} - } // namespace ext - -#endif // SCRAM_GUI_TEST_HELP_H diff -Nru scram-0.16.1/gui/tests/testmodel.cpp scram-0.16.2/gui/tests/testmodel.cpp --- scram-0.16.1/gui/tests/testmodel.cpp 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/tests/testmodel.cpp 2018-01-12 11:42:47.000000000 +0000 @@ -78,7 +78,7 @@ const char *name = "pump"; mef::BasicEvent event(name); gui::model::BasicEvent proxy(&event); - auto spy = ext::make_spy(&proxy, &gui::model::Element::labelChanged); + auto spy = ext::SignalSpy(&proxy, &gui::model::Element::labelChanged); TEST_EQ(event.name(), name); TEST_EQ(event.id(), name); @@ -118,7 +118,7 @@ QVERIFY(!model.name().empty()); const char *name = "model"; - auto spy = ext::make_spy(&proxy, &gui::model::Model::modelNameChanged); + auto spy = ext::SignalSpy(&proxy, &gui::model::Model::modelNameChanged); gui::model::Model::SetName setter(name, &proxy); setter.redo(); @@ -151,9 +151,9 @@ QVERIFY(model.fault_trees().empty()); QVERIFY(proxyModel.faultTrees().empty()); - auto spyAdd = ext::make_spy( + auto spyAdd = ext::SignalSpy( &proxyModel, OVERLOAD(gui::model::Model, added, mef::FaultTree *)); - auto spyRemove = ext::make_spy( + auto spyRemove = ext::SignalSpy( &proxyModel, OVERLOAD(gui::model::Model, removed, mef::FaultTree *)); auto *address = faultTree.get(); @@ -188,9 +188,9 @@ gui::model::Model proxyModel(&model); TEST_EQ(proxyModel.faultTrees().size(), 1); - auto spyAdd = ext::make_spy( + auto spyAdd = ext::SignalSpy( &proxyModel, OVERLOAD(gui::model::Model, added, mef::FaultTree *)); - auto spyRemove = ext::make_spy( + auto spyRemove = ext::SignalSpy( &proxyModel, OVERLOAD(gui::model::Model, removed, mef::FaultTree *)); gui::model::Model::RemoveFaultTree remover(address, &proxyModel); @@ -310,9 +310,9 @@ QVERIFY(proxyModel.table().empty()); auto spyAdd = - ext::make_spy(&proxyModel, OVERLOAD(gui::model::Model, added, T *)); + ext::SignalSpy(&proxyModel, OVERLOAD(gui::model::Model, added, T *)); auto spyRemove = - ext::make_spy(&proxyModel, OVERLOAD(gui::model::Model, removed, T *)); + ext::SignalSpy(&proxyModel, OVERLOAD(gui::model::Model, removed, T *)); auto event = std::make_unique("pump"); auto *address = event.get(); @@ -362,9 +362,9 @@ QCOMPARE(proxyEvent->data(), address); auto spyAdd = - ext::make_spy(&proxyModel, OVERLOAD(gui::model::Model, added, T *)); + ext::SignalSpy(&proxyModel, OVERLOAD(gui::model::Model, added, T *)); auto spyRemove = - ext::make_spy(&proxyModel, OVERLOAD(gui::model::Model, removed, T *)); + ext::SignalSpy(&proxyModel, OVERLOAD(gui::model::Model, removed, T *)); gui::model::Model::RemoveEvent remover(proxyEvent, &proxyModel, faultTree); @@ -396,7 +396,7 @@ QCOMPARE(proxy.state(), false); TEST_EQ(proxy.state(), "False"); - auto spy = ext::make_spy(&proxy, &gui::model::HouseEvent::stateChanged); + auto spy = ext::SignalSpy(&proxy, &gui::model::HouseEvent::stateChanged); gui::model::HouseEvent::SetState setter(&proxy, true); setter.redo(); TEST_EQ(spy.size(), 1); @@ -429,7 +429,7 @@ QVERIFY(event.attributes().empty()); QCOMPARE(proxy.flavor(), gui::model::BasicEvent::Basic); - auto spy = ext::make_spy(&proxy, &gui::model::BasicEvent::flavorChanged); + auto spy = ext::SignalSpy(&proxy, &gui::model::BasicEvent::flavorChanged); auto value = gui::model::BasicEvent::Undeveloped; gui::model::BasicEvent::SetFlavor setter(&proxy, value); setter.redo(); @@ -477,7 +477,7 @@ double value = 0.1; mef::ConstantExpression prob(value); auto spy = - ext::make_spy(&proxy, &gui::model::BasicEvent::expressionChanged); + ext::SignalSpy(&proxy, &gui::model::BasicEvent::expressionChanged); gui::model::BasicEvent::SetExpression setter(&proxy, &prob); setter.redo(); QCOMPARE(prob.value(), value); @@ -535,7 +535,7 @@ auto formula = std::make_unique(mef::kNull); auto *address = formula.get(); - auto spy = ext::make_spy(&proxy, &gui::model::Gate::formulaChanged); + auto spy = ext::SignalSpy(&proxy, &gui::model::Gate::formulaChanged); gui::model::Gate::SetFormula setter(&proxy, std::move(formula)); setter.redo(); TEST_EQ(spy.size(), 1); @@ -597,7 +597,7 @@ TEST_EQ(proxyEvent->id(), oldName); const char newName[] = "valve"; - auto spy = ext::make_spy(proxyEvent, &gui::model::Element::idChanged); + auto spy = ext::SignalSpy(proxyEvent, &gui::model::Element::idChanged); gui::model::Element::SetId setter(proxyEvent, newName, &model, faultTree); setter.redo(); diff -Nru scram-0.16.1/gui/validator.cpp scram-0.16.2/gui/validator.cpp --- scram-0.16.1/gui/validator.cpp 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/validator.cpp 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,8 +26,7 @@ #include #include -namespace scram { -namespace gui { +namespace scram::gui { const QValidator *Validator::name() { @@ -57,5 +56,4 @@ return &nonNegativeValidator; } -} // namespace gui -} // namespace scram +} // namespace scram::gui diff -Nru scram-0.16.1/gui/validator.h scram-0.16.2/gui/validator.h --- scram-0.16.1/gui/validator.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/validator.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,13 +18,11 @@ /// @file /// Collection of validators. -#ifndef VALIDATOR_H -#define VALIDATOR_H +#pragma once #include -namespace scram { -namespace gui { +namespace scram::gui { /// Provider of common validators. class Validator @@ -43,7 +41,4 @@ static const QValidator *nonNegative(); }; -} // namespace gui -} // namespace scram - -#endif // VALIDATOR_H +} // namespace scram::gui diff -Nru scram-0.16.1/gui/zoomableview.cpp scram-0.16.2/gui/zoomableview.cpp --- scram-0.16.1/gui/zoomableview.cpp 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/zoomableview.cpp 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,8 +21,7 @@ #include -namespace scram { -namespace gui { +namespace scram::gui { void ZoomableView::setZoom(int level) { @@ -64,5 +63,4 @@ } } -} // namespace gui -} // namespace scram +} // namespace scram::gui diff -Nru scram-0.16.1/gui/zoomableview.h scram-0.16.2/gui/zoomableview.h --- scram-0.16.1/gui/zoomableview.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/gui/zoomableview.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,14 +18,12 @@ /// @file /// Provides a GraphicsView with zoom in/out and other convenience features. -#ifndef ZOOMABLEVIEW_H -#define ZOOMABLEVIEW_H +#pragma once #include #include -namespace scram { -namespace gui { +namespace scram::gui { /// The base class for graphics views with default zoom logic. /// The zoom level is given as percents. @@ -66,7 +64,4 @@ int m_zoom = 100; ///< The zoom level value in percents. }; -} // namespace gui -} // namespace scram - -#endif // ZOOMABLEVIEW_H +} // namespace scram::gui diff -Nru scram-0.16.1/README.rst scram-0.16.2/README.rst --- scram-0.16.1/README.rst 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/README.rst 2018-01-12 11:42:47.000000000 +0000 @@ -60,7 +60,7 @@ Git Submodules ============== -Some dependencies are provided with git submodules (e.g., Google Test). +Some dependencies are provided with git submodules (e.g., Catch2). In order to initialize all the submodules, this repository must be cloned recursively with ``git clone --recursive``, or the following commands must be executed after a normal clone. @@ -73,38 +73,38 @@ Dependencies ============ -==================== ==================== +==================== =============== Package Minimum Version -==================== ==================== -CMake 3.5 -boost 1.61 (1.58 on Linux) +==================== =============== +CMake 3.8 +boost 1.61 libxml2 2.9.1 Python 2.7.3 or 3.3 -Qt 5.2.1 -==================== ==================== +Qt 5.9.1 +==================== =============== Optional Dependencies --------------------- -==================== ================== +==================== =============== Package Minimum Version -==================== ================== +==================== =============== TCMalloc 1.7 JEMalloc 3.6 -==================== ================== +==================== =============== Compilers --------- -==================== ================== +==================== =============== Package Minimum Version -==================== ================== -GCC/G++ 4.9 -Clang/LLVM 3.6 -Intel 17.0.2 -==================== ================== +==================== =============== +GCC/G++ 7.1 +Clang/LLVM 5.0 +Intel 18.0.1 +==================== =============== Installing Dependencies @@ -114,7 +114,7 @@ ------ Python and GCC/G++ compiler are assumed to be available on the system. -The process is tested on Ubuntu 16.04 LTS using ``apt-get`` as the package manager: +The process is tested on Ubuntu 17.10 using ``apt-get`` as the package manager: .. code-block:: bash @@ -126,8 +126,7 @@ If on a Mac system, homebrew_ is a good package manager to use. It is assumed that some dependencies are provided by Xcode (e.g., Python, llvm/clang, make). -The following instructions are tested on OS X 10.9, -but it should work for later versions as well: +The following instructions are tested on OS X 10.12: .. code-block:: bash @@ -263,13 +262,13 @@ .. code-block:: bash - nosetests -w scripts/ test/ + .../scram/scripts$ pythom -m pytest test/ To test the command-line call of SCRAM: .. code-block:: bash - nosetests -w tests/ + .../scram/tests$ python -m pytest test_scram_call.py To run performance tests @@ -284,7 +283,7 @@ .. code-block:: bash - scram_tests --gtest_also_run_disabled_tests --gtest_filter=*Performance* + scram_tests [.perf] To run GUI tests diff -Nru scram-0.16.1/requirements-tests.txt scram-0.16.2/requirements-tests.txt --- scram-0.16.1/requirements-tests.txt 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/requirements-tests.txt 2018-01-12 11:42:47.000000000 +0000 @@ -1,2 +1,4 @@ -nose +coverage +pytest +pytest-cov lxml diff -Nru scram-0.16.1/scripts/test/test_fault_tree_generator.py scram-0.16.2/scripts/test/test_fault_tree_generator.py --- scram-0.16.1/scripts/test/test_fault_tree_generator.py 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/scripts/test/test_fault_tree_generator.py 2018-01-12 11:42:47.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2014-2017 Olzhas Rakhimov +# Copyright (C) 2014-2018 Olzhas Rakhimov # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -22,97 +22,120 @@ from unittest import TestCase from lxml import etree -from nose.tools import assert_equal, assert_true, assert_is_not_none, \ - assert_less, assert_raises +import pytest from fault_tree_generator import FactorError, Factors, generate_fault_tree, \ write_info, write_summary, main +# pylint: disable=redefined-outer-name -class FactorsTestCase(TestCase): - """Tests for correct setting and calculation of factors.""" - def setUp(self): - """Creates partially constructed factors collection.""" - self.factors = Factors() - - def test_min_max_prob(self): - """Tests setting of probability factors.""" - assert_raises(FactorError, self.factors.set_min_max_prob, -0.1, 0.5) - assert_raises(FactorError, self.factors.set_min_max_prob, 1.1, 0.5) - assert_raises(FactorError, self.factors.set_min_max_prob, 0.1, -0.5) - assert_raises(FactorError, self.factors.set_min_max_prob, 0.1, 1.5) - assert_raises(FactorError, self.factors.set_min_max_prob, 0.5, 0.1) - self.factors.set_min_max_prob(0.1, 0.5) - assert_equal(0.1, self.factors.min_prob) - assert_equal(0.5, self.factors.max_prob) - - def test_set_common_event_factors(self): - """Tests setting of probability factors.""" - self.factors.set_common_event_factors(0.1, 0.1, 2, 2) # no fail - assert_raises(FactorError, self.factors.set_common_event_factors, -0.1, - 0.5, 2, 2) - assert_raises(FactorError, self.factors.set_common_event_factors, 1.0, - 0.5, 2, 2) - assert_raises(FactorError, self.factors.set_common_event_factors, 0.1, - -0.5, 2, 2) - assert_raises(FactorError, self.factors.set_common_event_factors, 0.1, - 1.0, 2, 2) - assert_raises(FactorError, self.factors.set_common_event_factors, 0, 0, - 2, 2) - assert_raises(FactorError, self.factors.set_common_event_factors, 0.1, - 0.1, 1, 2) - assert_raises(FactorError, self.factors.set_common_event_factors, 0.1, - 0.1, 101, 2) - assert_raises(FactorError, self.factors.set_common_event_factors, 0.1, - 0.1, 2, 1) - assert_raises(FactorError, self.factors.set_common_event_factors, 0.1, - 0.1, 2, 101) - self.factors.set_common_event_factors(0.4, 0.2, 3, 4) - assert_equal(0.4, self.factors.common_b) - assert_equal(0.2, self.factors.common_g) - assert_equal(3, self.factors.parents_b) - assert_equal(4, self.factors.parents_g) - - def test_set_num_factors(self): - """Tests setting of size factors.""" - self.factors.set_num_factors(3, 100, 5, 4) - assert_equal(3, self.factors.num_args) - assert_equal(100, self.factors.num_basic) - assert_equal(5, self.factors.num_house) - assert_equal(4, self.factors.num_ccf) - # Invalid values. - assert_raises(FactorError, self.factors.set_num_factors, 1.5, 100) - assert_raises(FactorError, self.factors.set_num_factors, 3, 0) - assert_raises(FactorError, self.factors.set_num_factors, 3, 100, -5) - assert_raises(FactorError, self.factors.set_num_factors, 3, 100, 0, -4) +@pytest.fixture() +def factors(): + """Creates partially constructed factors collection.""" + return Factors() + + +def test_min_max_prob_valid(factors): + """Tests setting of valid probability min-max factors.""" + factors.set_min_max_prob(0.1, 0.5) + assert factors.min_prob == 0.1 + assert factors.max_prob == 0.5 + + +@pytest.mark.parametrize("min_value,max_value", + [(-0.1, 0.5), (1.1, 0.5), (0.1, -0.5), (0.1, 1.5), + (0.5, 0.1)]) +def test_min_max_prob_fail(factors, min_value, max_value): + """Tests setting of invalid probability min-max factors.""" + with pytest.raises(FactorError): + factors.set_min_max_prob(min_value, max_value) + + +def test_set_common_event_valid(factors): + """Tests valid common event factors.""" + factors.set_common_event_factors(0.4, 0.2, 3, 4) + assert factors.common_b == 0.4 + assert factors.common_g == 0.2 + assert factors.parents_b == 3 + assert factors.parents_g == 4 + + +@pytest.mark.parametrize( + "args", [(-0.1, 0.5, 2, 2), (1.0, 0.5, 2, 2), (0.1, -0.5, 2, 2), + (0.1, 1.0, 2, 2), (0, 0, 2, 2), (0.1, 0.1, 1, 2), + (0.1, 0.1, 101, 2), (0.1, 0.1, 2, 1), (0.1, 0.1, 2, 101)]) +def test_set_common_event_fail(factors, args): + """Tests setting of invalid common event factors.""" + factors.set_common_event_factors(0.1, 0.1, 2, 2) # no fail + with pytest.raises(FactorError): + factors.set_common_event_factors(*args) + + +def test_set_num_factors_valid(factors): + """Tests setting of valid size factors.""" + factors.set_num_factors(3, 100, 5, 4) + assert factors.num_args == 3 + assert factors.num_basic == 100 + assert factors.num_house == 5 + assert factors.num_ccf == 4 + + +@pytest.mark.parametrize( + "args", + [ + (1.5, 100), + (3, 0), + (3, 100, -5), + (3, 100, 0, -4), # Too many house events. - assert_raises(FactorError, self.factors.set_num_factors, 3, 5, 5) + (3, 5, 5), # Too many CCF groups. - assert_raises(FactorError, self.factors.set_num_factors, 5, 50, 0, 11) - - def test_set_gate_weights(self): - """Tests the setting of gate weights.""" - assert_raises(FactorError, self.factors.set_gate_weights, []) - assert_raises(FactorError, self.factors.set_gate_weights, [-1, 2, 3]) - assert_raises(FactorError, self.factors.set_gate_weights, [0, 0, 0]) + (5, 50, 0, 11) + ]) +def test_set_num_factors_fail(factors, args): + """Tests setting of invalid size factors.""" + with pytest.raises(FactorError): + factors.set_num_factors(*args) + + +@pytest.mark.parametrize( + "args,expected", + [ + ([5, 8, 4, 2, 1], [5, 8, 4, 2, 1]), + ([5, 8, 4], [5, 8, 4, 0, 0]) # for padding with 0s + ]) +def test_set_gate_weights_valid(factors, args, expected): + """Tests the setting of valid gate weights.""" + factors.set_gate_weights(args) + assert factors.get_gate_weights() == expected + + +@pytest.mark.parametrize( + "args", + [ + [], + [-1, 2, 3], + [0, 0, 0], # Too many weights. - assert_raises(FactorError, self.factors.set_gate_weights, - [1, 2, 3, 4, 5, 6]) + [1, 2, 3, 4, 5, 6], # XOR or NOT only. - assert_raises(FactorError, self.factors.set_gate_weights, - [0, 0, 0, 1, 2]) - self.factors.set_gate_weights([5, 8, 4, 2, 1]) - assert_equal([5, 8, 4, 2, 1], self.factors.get_gate_weights()) - self.factors.set_gate_weights([5, 8, 4]) # for padding with 0s - assert_equal([5, 8, 4, 0, 0], self.factors.get_gate_weights()) - - def test_constrain_num_gates(self): - """Checks invalid setup for constraining gate numbers.""" - assert_raises(FactorError, self.factors.constrain_num_gate, 0) - self.factors.num_args = 4 - self.factors.num_basic = 400 - assert_raises(FactorError, self.factors.constrain_num_gate, 50) + [0, 0, 0, 1, 2], + ]) +def test_set_gate_weights_fail(factors, args): + """Tests the setting of invalid gate weights.""" + with pytest.raises(FactorError): + factors.set_gate_weights(args) + + +def test_constrain_num_gates(factors): + """Checks invalid setup for constraining gate numbers.""" + with pytest.raises(FactorError): + factors.constrain_num_gate(0) + factors.num_args = 4 + factors.num_basic = 400 + with pytest.raises(FactorError): + factors.constrain_num_gate(50) # unsatisfiable class FaultTreeGeneratorTestCase(TestCase): @@ -136,7 +159,7 @@ self.factors.num_ccf = 10 self.factors.calculate() fault_tree = generate_fault_tree("TestingTree", "root", self.factors) - assert_is_not_none(fault_tree) + assert fault_tree is not None write_info(fault_tree, self.output, 123) write_summary(fault_tree, self.output) self.output.write(fault_tree.to_xml(1)) @@ -145,7 +168,7 @@ relaxng = etree.RelaxNG(relaxng_doc) with open(self.output.name, "r") as test_file: doc = etree.parse(test_file) - assert_true(relaxng.validate(doc)) + assert relaxng.validate(doc) def test_aralia_output(self): """Checks if the Aralia format output passes validation.""" @@ -154,12 +177,12 @@ self.factors.num_ccf = 10 self.factors.calculate() fault_tree = generate_fault_tree("TestingTree", "root", self.factors) - assert_is_not_none(fault_tree) + assert fault_tree is not None self.output.write(fault_tree.to_aralia()) self.output.file.flush() tmp = NamedTemporaryFile(mode="w+") cmd = ["./translators/aralia.py", self.output.name, "-o", tmp.name] - assert_equal(0, call(cmd)) + assert call(cmd) == 0 def test_constrain_num_gates(self): """Checks the case of the constrained number of gates.""" @@ -168,8 +191,8 @@ self.factors.constrain_num_gate(200) self.factors.calculate() fault_tree = generate_fault_tree("TestingTree", "root", self.factors) - assert_is_not_none(fault_tree) - assert_less(abs(1 - len(fault_tree.gates) / 200), 0.1) + assert fault_tree is not None + assert abs(1 - len(fault_tree.gates) / 200) < 0.1 def test_main(): @@ -180,11 +203,11 @@ relaxng = etree.RelaxNG(relaxng_doc) with open(tmp.name, "r") as test_file: doc = etree.parse(test_file) - assert_true(relaxng.validate(doc)) + assert relaxng.validate(doc) main(["-b", "200", "-g", "200", "-o", tmp.name, "--aralia"]) cmd = [ "./translators/aralia.py", tmp.name, "-o", NamedTemporaryFile(mode="w+").name ] - assert_equal(0, call(cmd)) + assert call(cmd) == 0 diff -Nru scram-0.16.1/src/alignment.cc scram-0.16.2/src/alignment.cc --- scram-0.16.1/src/alignment.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/alignment.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,8 +23,7 @@ #include "error.h" #include "ext/float_compare.h" -namespace scram { -namespace mef { +namespace scram::mef { Phase::Phase(std::string name, double time_fraction) : Element(std::move(name)), time_fraction_(time_fraction) { @@ -46,5 +45,4 @@ "' do not sum to 1.")); } -} // namespace mef -} // namespace scram +} // namespace scram::mef diff -Nru scram-0.16.1/src/alignment.h scram-0.16.2/src/alignment.h --- scram-0.16.1/src/alignment.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/alignment.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,23 +18,19 @@ /// @file /// Mission and phase constructs. -#ifndef SCRAM_SRC_ALIGNMENT_H_ -#define SCRAM_SRC_ALIGNMENT_H_ +#pragma once #include #include #include -#include - #include "element.h" #include "instruction.h" -namespace scram { -namespace mef { +namespace scram::mef { /// Phases of alignments the models spends its time fraction. -class Phase : public Element, private boost::noncopyable { +class Phase : public Element { public: /// @copydoc Element::Element /// @@ -64,7 +60,7 @@ using PhasePtr = std::unique_ptr; ///< Phases are unique to alignments. /// Alignment configuration for the whole model per analysis. -class Alignment : public Element, private boost::noncopyable { +class Alignment : public Element { public: using Element::Element; @@ -89,7 +85,4 @@ using AlignmentPtr = std::unique_ptr; ///< Unique model alignments. -} // namespace mef -} // namespace scram - -#endif // SCRAM_SRC_ALIGNMENT_H_ +} // namespace scram::mef diff -Nru scram-0.16.1/src/analysis.cc scram-0.16.2/src/analysis.cc --- scram-0.16.1/src/analysis.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/analysis.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2017 Olzhas Rakhimov + * Copyright (C) 2015-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,13 +20,11 @@ #include "analysis.h" -namespace scram { -namespace core { +namespace scram::core { Analysis::Analysis(Settings settings) : settings_(std::move(settings)), analysis_time_(0) {} Analysis::~Analysis() = default; ///< Pure virtual destructor. -} // namespace core -} // namespace scram +} // namespace scram::core diff -Nru scram-0.16.1/src/analysis.h scram-0.16.2/src/analysis.h --- scram-0.16.1/src/analysis.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/analysis.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2017 Olzhas Rakhimov + * Copyright (C) 2015-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,7 @@ /// @file /// Common facilities for all analysis classes. -#ifndef SCRAM_SRC_ANALYSIS_H_ -#define SCRAM_SRC_ANALYSIS_H_ +#pragma once #include @@ -29,8 +28,7 @@ #include "settings.h" -namespace scram { -namespace core { +namespace scram::core { /// Base abstract class for all analysis with settings. class Analysis : private boost::noncopyable { @@ -76,7 +74,4 @@ std::string warnings_; ///< Generated warnings in analysis. }; -} // namespace core -} // namespace scram - -#endif // SCRAM_SRC_ANALYSIS_H_ +} // namespace scram::core diff -Nru scram-0.16.1/src/bdd.cc scram-0.16.2/src/bdd.cc --- scram-0.16.1/src/bdd.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/bdd.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2017 Olzhas Rakhimov + * Copyright (C) 2015-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,8 +27,7 @@ #include "logger.h" #include "zbdd.h" -namespace scram { -namespace core { +namespace scram::core { int GetPrimeNumber(int n) { assert(n > 0 && "Only natural numbers."); @@ -371,5 +370,4 @@ TestStructure(ite.low()); } -} // namespace core -} // namespace scram +} // namespace scram::core diff -Nru scram-0.16.1/src/bdd.h scram-0.16.2/src/bdd.h --- scram-0.16.1/src/bdd.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/bdd.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2017 Olzhas Rakhimov + * Copyright (C) 2015-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,7 @@ /// @file /// Fault tree analysis with the Binary Decision Diagram algorithms. -#ifndef SCRAM_SRC_BDD_H_ -#define SCRAM_SRC_BDD_H_ +#pragma once #include @@ -37,8 +36,7 @@ #include "pdag.h" #include "settings.h" -namespace scram { -namespace core { +namespace scram::core { /// The default management of BDD vertices. /// @@ -989,7 +987,4 @@ std::unique_ptr zbdd_; ///< ZBDD as a result of analysis. }; -} // namespace core -} // namespace scram - -#endif // SCRAM_SRC_BDD_H_ +} // namespace scram::core diff -Nru scram-0.16.1/src/ccf_group.cc scram-0.16.2/src/ccf_group.cc --- scram-0.16.1/src/ccf_group.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/ccf_group.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -29,8 +29,7 @@ #include "ext/combination_iterator.h" #include "ext/float_compare.h" -namespace scram { -namespace mef { +namespace scram::mef { CcfEvent::CcfEvent(std::string name, const CcfGroup* ccf_group) : BasicEvent(std::move(name), ccf_group->base_path(), ccf_group->role()), @@ -65,7 +64,7 @@ member->expression(distribution_); } -void CcfGroup::AddFactor(Expression* factor, boost::optional level) { +void CcfGroup::AddFactor(Expression* factor, std::optional level) { int min_level = this->min_level(); if (!level) level = prev_level_ ? (prev_level_ + 1) : min_level; @@ -290,5 +289,4 @@ return probabilities; } -} // namespace mef -} // namespace scram +} // namespace scram::mef diff -Nru scram-0.16.1/src/ccf_group.h scram-0.16.2/src/ccf_group.h --- scram-0.16.1/src/ccf_group.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/ccf_group.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,24 +22,20 @@ /// with alpha, beta, MGL, /// or direct parameter assignment in phi model. -#ifndef SCRAM_SRC_CCF_GROUP_H_ -#define SCRAM_SRC_CCF_GROUP_H_ +#pragma once #include +#include #include #include #include #include -#include -#include - #include "element.h" #include "event.h" #include "expression.h" -namespace scram { -namespace mef { +namespace scram::mef { class CcfGroup; // CCF Events know their own groups. @@ -87,7 +83,7 @@ }; /// Abstract base class for all common cause failure models. -class CcfGroup : public Id, private boost::noncopyable { +class CcfGroup : public Id { public: using Id::Id; @@ -131,7 +127,7 @@ /// @throws RedefinitionError The factor for the level already exists. /// @throws LogicError The level is not positive, /// or the CCF group members are undefined. - void AddFactor(Expression* factor, boost::optional level = {}); + void AddFactor(Expression* factor, std::optional level = {}); /// Validates the setup for the CCF model and group. /// Checks if the provided distribution is between 0 and 1. @@ -266,7 +262,4 @@ ExpressionMap CalculateProbabilities() override; }; -} // namespace mef -} // namespace scram - -#endif // SCRAM_SRC_CCF_GROUP_H_ +} // namespace scram::mef diff -Nru scram-0.16.1/src/CMakeLists.txt scram-0.16.2/src/CMakeLists.txt --- scram-0.16.1/src/CMakeLists.txt 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/CMakeLists.txt 2018-01-12 11:42:47.000000000 +0000 @@ -2,16 +2,14 @@ execute_process(COMMAND git describe --tags OUTPUT_VARIABLE core_version OUTPUT_STRIP_TRAILING_WHITESPACE) configure_file(version.cc.in version.cc @ONLY) -configure_file(env.cc.in env.cc @ONLY) ################### End File Configurations #################### set(CMAKE_INCLUDE_CURRENT_DIR ON) set(SCRAM_CORE_SRC - ${CMAKE_CURRENT_BINARY_DIR}/env.cc + env.cc ${CMAKE_CURRENT_BINARY_DIR}/version.cc logger.cc - random.cc settings.cc xml.cc config.cc @@ -50,6 +48,7 @@ ) add_library(scram SHARED ${SCRAM_CORE_SRC}) target_link_libraries(scram ${LIBS}) +target_compile_options(scram PRIVATE $<$:${SCRAM_CXX_FLAGS_DEBUG}>) install( TARGETS scram @@ -62,6 +61,7 @@ add_executable(scram-cli scram.cc) set_target_properties(scram-cli PROPERTIES OUTPUT_NAME scram) target_link_libraries(scram-cli scram ${Boost_LIBRARIES}) +target_compile_options(scram-cli PRIVATE $<$:${SCRAM_CXX_FLAGS_DEBUG}>) install( TARGETS scram-cli diff -Nru scram-0.16.1/src/config.cc scram-0.16.2/src/config.cc --- scram-0.16.1/src/config.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/config.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,6 +23,7 @@ #include #include +#include #include @@ -54,7 +55,7 @@ } // namespace Config::Config(const std::string& config_file) { - static xml::Validator validator(Env::config_schema()); + static xml::Validator validator(env::config_schema()); if (fs::exists(config_file) == false) { SCRAM_THROW(IOError("The configuration file does not exist.")) @@ -67,8 +68,8 @@ fs::path base_path = fs::path(config_file).parent_path(); GatherInputFiles(root, base_path); - if (boost::optional out = root.child("output-path")) { - output_path_ = normalize(out->text().to_string(), base_path); + if (std::optional out = root.child("output-path")) { + output_path_ = normalize(std::string(out->text()), base_path); } try { @@ -81,17 +82,18 @@ void Config::GatherInputFiles(const xml::Element& root, const fs::path& base_path) { - boost::optional input_files = root.child("input-files"); + std::optional input_files = root.child("input-files"); if (!input_files) return; for (xml::Element input_file : input_files->children()) { assert(input_file.name() == "file"); - input_files_.push_back(normalize(input_file.text().to_string(), base_path)); + input_files_.push_back( + normalize(std::string(input_file.text()), base_path)); } } void Config::GatherOptions(const xml::Element& root) { - boost::optional options_element = root.child("options"); + std::optional options_element = root.child("options"); if (!options_element) return; // The loop is used instead of query @@ -99,7 +101,7 @@ // yet this function should not know what the order is. for (xml::Element option_group : options_element->children()) { try { - xml::string_view name = option_group.name(); + std::string_view name = option_group.name(); if (name == "algorithm") { settings_.algorithm(option_group.attribute("name")); @@ -117,7 +119,7 @@ throw; } } - if (boost::optional analysis_group = + if (std::optional analysis_group = options_element->child("analysis")) { try { SetAnalysis(*analysis_group); @@ -130,7 +132,7 @@ void Config::SetAnalysis(const xml::Element& analysis) { auto set_flag = [&analysis](const char* tag, auto setter) { - if (boost::optional flag = analysis.attribute(tag)) + if (std::optional flag = analysis.attribute(tag)) setter(*flag); }; set_flag("probability", @@ -146,7 +148,7 @@ void Config::SetLimits(const xml::Element& limits) { for (xml::Element limit : limits.children()) { - xml::string_view name = limit.name(); + std::string_view name = limit.name(); if (name == "product-order") { settings_.limit_order(limit.text()); diff -Nru scram-0.16.1/src/config.h scram-0.16.2/src/config.h --- scram-0.16.1/src/config.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/config.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,8 +19,7 @@ /// Configuration management facilities /// to make various setups for analysis possible. -#ifndef SCRAM_SRC_CONFIG_H_ -#define SCRAM_SRC_CONFIG_H_ +#pragma once #include #include @@ -91,5 +90,3 @@ }; } // namespace scram - -#endif // SCRAM_SRC_CONFIG_H_ diff -Nru scram-0.16.1/src/cycle.h scram-0.16.2/src/cycle.h --- scram-0.16.1/src/cycle.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/cycle.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,7 @@ /// @file /// Validation facilities to detect and print cycles in graphs. -#ifndef SCRAM_SRC_CYCLE_H_ -#define SCRAM_SRC_CYCLE_H_ +#pragma once #include #include @@ -36,9 +35,7 @@ #include "instruction.h" #include "parameter.h" -namespace scram { -namespace mef { -namespace cycle { +namespace scram::mef::cycle { /// Determines the connectors between nodes. /// @@ -65,7 +62,7 @@ return connector->event_args() | boost::adaptors::transformed( [](const Formula::EventArg& event_args) -> Gate* { - if (auto* arg = boost::get(&event_args)) + if (auto* arg = std::get_if(&event_args)) return *arg; return nullptr; }) | @@ -183,7 +180,7 @@ decltype(cycle) cycle_; } continue_connector{cycle}; - return boost::apply_visitor(continue_connector, connector->target()); + return std::visit(continue_connector, connector->target()); } /// Cycle detection specialization for visitor-based traversal of instructions. @@ -248,7 +245,7 @@ std::vector* cycle) { struct { void operator()(const Branch* branch) { - boost::apply_visitor(*this, branch->target()); + std::visit(*this, branch->target()); } void operator()(Fork* fork) { for (Branch& branch : fork->paths()) @@ -334,8 +331,4 @@ } } -} // namespace cycle -} // namespace mef -} // namespace scram - -#endif // SCRAM_SRC_CYCLE_H_ +} // namespace scram::mef::cycle diff -Nru scram-0.16.1/src/element.cc scram-0.16.2/src/element.cc --- scram-0.16.1/src/element.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/element.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,8 +25,7 @@ #include "error.h" #include "ext/algorithm.h" -namespace scram { -namespace mef { +namespace scram::mef { Element::Element(std::string name) { Element::name(std::move(name)); } @@ -105,5 +104,4 @@ id_ = MakeId(*this); } -} // namespace mef -} // namespace scram +} // namespace scram::mef diff -Nru scram-0.16.1/src/element.h scram-0.16.2/src/element.h --- scram-0.16.1/src/element.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/element.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,8 +19,7 @@ /// Helper classes, structs, and properties /// common to all other classes. -#ifndef SCRAM_SRC_ELEMENT_H_ -#define SCRAM_SRC_ELEMENT_H_ +#pragma once #include @@ -30,9 +29,9 @@ #include #include #include +#include -namespace scram { -namespace mef { +namespace scram::mef { /// This struct allows any attribute. struct Attribute { @@ -45,7 +44,7 @@ /// any element of analysis /// that can have extra descriptions, /// such as attributes and a label. -class Element { +class Element : private boost::noncopyable { public: /// Constructs an element with an original name. /// The name is expected to conform to identifier requirements @@ -318,7 +317,4 @@ bool usage_ = false; ///< Elements are assumed to be unused at construction. }; -} // namespace mef -} // namespace scram - -#endif // SCRAM_SRC_ELEMENT_H_ +} // namespace scram::mef diff -Nru scram-0.16.1/src/env.cc scram-0.16.2/src/env.cc --- scram-0.16.1/src/env.cc 1970-01-01 00:00:00.000000000 +0000 +++ scram-0.16.2/src/env.cc 2018-01-12 11:42:47.000000000 +0000 @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2014-2018 Olzhas Rakhimov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/// @file +/// The environment variables discovered at run-time. + +#include "env.h" + +#include + +namespace scram::env { + +const std::string& config_schema() { + static const std::string schema_path = + install_dir() + "/share/scram/config.rng"; + return schema_path; +} + +const std::string& input_schema() { + static const std::string schema_path = + install_dir() + "/share/scram/input.rng"; + return schema_path; +} + +const std::string& report_schema() { + static const std::string schema_path = + install_dir() + "/share/scram/report.rng"; + return schema_path; +} + +const std::string& install_dir() { + static const std::string install_path = + boost::dll::program_location() // executable + .parent_path() // bin + .parent_path() // install + .generic_string(); // POSIX format. + return install_path; +} + +} // namespace scram::env diff -Nru scram-0.16.1/src/env.cc.in scram-0.16.2/src/env.cc.in --- scram-0.16.1/src/env.cc.in 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/env.cc.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2014-2017 Olzhas Rakhimov - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/// @file -/// Implementation of Env class. -/// The variables are filled by CMake or discovered at run-time. - -#include "env.h" - -#include - -#if BOOST_OS_WINDOWS - -#include - -/// Finds the installation directory on Windows. -/// -/// @returns POSIX path to the installation directory. -/// -/// @pre The main executable is located at "install_dir/bin/prog.exe". -/// -/// @note This function will terminate the program if any system calls fail. -static std::string GetInstallPath() noexcept { - return boost::dll::program_location() // executable - .parent_path() // bin - .parent_path() // install - .generic_string(); // POSIX format. -} -#else -// clang-format off -/// @returns Path to the installation directory known at compile-time. -static std::string GetInstallPath() { return "@CMAKE_INSTALL_PREFIX@"; } // NOLINT -// clang-format on -#endif - -namespace scram { - -const std::string Env::kInstallDir_ = GetInstallPath(); // NOLINT - -std::string Env::config_schema() { - return kInstallDir_ + "/share/scram/config.rng"; -} - -std::string Env::input_schema() { - return kInstallDir_ + "/share/scram/input.rng"; -} - -std::string Env::report_schema() { - return kInstallDir_ + "/share/scram/report.rng"; -} - -} // namespace scram diff -Nru scram-0.16.1/src/env.h scram-0.16.2/src/env.h --- scram-0.16.1/src/env.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/env.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,34 +16,28 @@ */ /// @file -/// Environmental Variables +/// SCRAM-specific environment variables. +/// +/// All paths are absolute, canonical, and POSIX (with '/' separator). +/// +/// @pre The system follows the Filesystem Hierarchy Standard. -#ifndef SCRAM_SRC_ENV_H_ -#define SCRAM_SRC_ENV_H_ +#pragma once #include -namespace scram { +namespace scram::env { -/// Provides environmental variables. -class Env { - public: - /// @returns The location of the RELAX NG schema for configuration files. - static std::string config_schema(); +/// @returns The location of the RELAX NG schema for configuration files. +const std::string& config_schema(); - /// @returns The location of the RELAX NG schema for input files. - static std::string input_schema(); +/// @returns The location of the RELAX NG schema for input files. +const std::string& input_schema(); - /// @returns The location of the RELAX NG schema for output report files. - static std::string report_schema(); +/// @returns The location of the RELAX NG schema for output report files. +const std::string& report_schema(); - /// @returns The path to the installation directory. - static const std::string& install_dir() { return kInstallDir_; } +/// @returns The path to the installation directory. +const std::string& install_dir(); - private: - static const std::string kInstallDir_; ///< Installation directory. -}; - -} // namespace scram - -#endif // SCRAM_SRC_ENV_H_ +} // namespace scram::env diff -Nru scram-0.16.1/src/error.h scram-0.16.2/src/error.h --- scram-0.16.1/src/error.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/error.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,7 @@ /// @file /// Exceptions for SCRAM. -#ifndef SCRAM_SRC_ERROR_H_ -#define SCRAM_SRC_ERROR_H_ +#pragma once #include #include @@ -160,5 +159,3 @@ } // namespace xml } // namespace scram - -#endif // SCRAM_SRC_ERROR_H_ diff -Nru scram-0.16.1/src/event.cc scram-0.16.2/src/event.cc --- scram-0.16.1/src/event.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/event.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,8 +26,7 @@ #include "ext/algorithm.h" #include "ext/variant.h" -namespace scram { -namespace mef { +namespace scram::mef { Event::~Event() = default; @@ -56,11 +55,12 @@ } int num_conditional = boost::count_if( formula_->event_args(), [](const Formula::EventArg& event) { - if (!boost::get(&event)) - return false; - auto& basic_event = boost::get(event); - return basic_event->HasAttribute("flavor") && - basic_event->GetAttribute("flavor").value == "conditional"; + if (BasicEvent* const* basic_event = std::get_if(&event)) { + return (*basic_event)->HasAttribute("flavor") && + (*basic_event)->GetAttribute("flavor").value == "conditional"; + } + + return false; }); if (num_conditional != 1) SCRAM_THROW(ValidityError(Element::name() + " : INHIBIT gate must have" + @@ -139,5 +139,4 @@ } } -} // namespace mef -} // namespace scram +} // namespace scram::mef diff -Nru scram-0.16.1/src/event.h scram-0.16.2/src/event.h --- scram-0.16.1/src/event.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/event.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,26 +18,25 @@ /// @file /// Contains event classes for fault trees. -#ifndef SCRAM_SRC_EVENT_H_ -#define SCRAM_SRC_EVENT_H_ +#pragma once #include #include #include +#include +#include #include #include -#include #include "element.h" #include "expression.h" -namespace scram { -namespace mef { +namespace scram::mef { /// Abstract base class for general fault tree events. -class Event : public Id, public Usage, private boost::noncopyable { +class Event : public Id, public Usage { public: using Id::Id; @@ -176,7 +175,7 @@ return *formula_; } Formula& formula() { - return const_cast(static_cast(this)->formula()); + return const_cast(std::as_const(*this).formula()); } /// @} @@ -228,7 +227,7 @@ class Formula : private boost::noncopyable { public: /// Event arguments of a formula. - using EventArg = boost::variant; + using EventArg = std::variant; /// Constructs a formula. /// @@ -297,7 +296,4 @@ std::vector formula_args_; ///< Nested formula arguments. }; -} // namespace mef -} // namespace scram - -#endif // SCRAM_SRC_EVENT_H_ +} // namespace scram::mef diff -Nru scram-0.16.1/src/event_tree_analysis.cc scram-0.16.2/src/event_tree_analysis.cc --- scram-0.16.1/src/event_tree_analysis.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/event_tree_analysis.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,8 +23,7 @@ #include "ext/find_iterator.h" #include "instruction.h" -namespace scram { -namespace core { +namespace scram::core { EventTreeAnalysis::EventTreeAnalysis( const mef::InitiatingEvent& initiating_event, const Settings& settings, @@ -89,7 +88,7 @@ } cloner{set_instructions, clones}; for (const mef::Formula::EventArg& arg : formula.event_args()) - new_formula->AddArgument(boost::apply_visitor(cloner, arg)); + new_formula->AddArgument(std::visit(cloner, arg)); for (const mef::FormulaPtr& arg : formula.formula_args()) new_formula->AddArgument(Clone(*arg, set_instructions, clones)); return new_formula; @@ -227,7 +226,7 @@ for (const mef::Instruction* instruction : branch->instructions()) instruction->Accept(&visitor); - boost::apply_visitor(*this, branch->target()); + std::visit(*this, branch->target()); } SequenceCollector* result_; @@ -239,5 +238,4 @@ Collector{result, &events_}(&initial_state); // NOLINT(whitespace/braces) } -} // namespace core -} // namespace scram +} // namespace scram::core diff -Nru scram-0.16.1/src/event_tree_analysis.h scram-0.16.2/src/event_tree_analysis.h --- scram-0.16.1/src/event_tree_analysis.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/event_tree_analysis.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,8 +17,7 @@ /// @file /// Event tree analysis facilities. -#ifndef SCRAM_SRC_EVENT_TREE_ANALYSIS_H_ -#define SCRAM_SRC_EVENT_TREE_ANALYSIS_H_ +#pragma once #include #include @@ -32,8 +31,7 @@ #include "expression/test_event.h" #include "settings.h" -namespace scram { -namespace core { +namespace scram::core { /// Event tree analysis functionality. class EventTreeAnalysis : public Analysis { @@ -104,7 +102,4 @@ mef::Context* context_; ///< The communication channel with test-events. }; -} // namespace core -} // namespace scram - -#endif // SCRAM_SRC_EVENT_TREE_ANALYSIS_H_ +} // namespace scram::core diff -Nru scram-0.16.1/src/event_tree.cc scram-0.16.2/src/event_tree.cc --- scram-0.16.1/src/event_tree.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/event_tree.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,8 +24,7 @@ #include "error.h" -namespace scram { -namespace mef { +namespace scram::mef { Path::Path(std::string state) : state_(std::move(state)) { if (state_.empty()) @@ -66,5 +65,4 @@ "Duplicate named branch: "); } -} // namespace mef -} // namespace scram +} // namespace scram::mef diff -Nru scram-0.16.1/src/event_tree.h scram-0.16.2/src/event_tree.h --- scram-0.16.1/src/event_tree.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/event_tree.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,22 +18,18 @@ /// @file /// Event Tree facilities. -#ifndef SCRAM_SRC_EVENT_TREE_H_ -#define SCRAM_SRC_EVENT_TREE_H_ +#pragma once #include #include +#include #include -#include -#include - #include "element.h" #include "ext/variant.h" #include "instruction.h" -namespace scram { -namespace mef { +namespace scram::mef { /// Representation of sequences in event trees. class Sequence : public Element, public Usage { @@ -88,7 +84,7 @@ class Branch { public: /// The types of possible branch end-points. - using Target = boost::variant; + using Target = std::variant; /// Sets the instructions to execute at the branch. void instructions(std::vector instructions) { @@ -166,7 +162,7 @@ }; /// Event Tree representation with MEF constructs. -class EventTree : public Element, public Usage, private boost::noncopyable { +class EventTree : public Element, public Usage { public: using Element::Element; @@ -241,7 +237,4 @@ /// Unique initiating events in a model. using InitiatingEventPtr = std::unique_ptr; -} // namespace mef -} // namespace scram - -#endif // SCRAM_SRC_EVENT_TREE_H_ +} // namespace scram::mef diff -Nru scram-0.16.1/src/expression/boolean.h scram-0.16.2/src/expression/boolean.h --- scram-0.16.1/src/expression/boolean.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/expression/boolean.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,15 +18,13 @@ /// @file /// Boolean expressions. -#ifndef SCRAM_SRC_EXPRESSION_BOOLEAN_H_ -#define SCRAM_SRC_EXPRESSION_BOOLEAN_H_ +#pragma once #include #include "src/expression.h" -namespace scram { -namespace mef { +namespace scram::mef { using Not = NaryExpression, 1>; ///< Logical negation. using And = NaryExpression, -1>; ///< Logical conjunction. @@ -38,7 +36,4 @@ using Leq = NaryExpression, 2>; ///< (<=) test. using Geq = NaryExpression, 2>; ///< (>=) test. -} // namespace mef -} // namespace scram - -#endif // SCRAM_SRC_EXPRESSION_BOOLEAN_H_ +} // namespace scram::mef diff -Nru scram-0.16.1/src/expression/conditional.cc scram-0.16.2/src/expression/conditional.cc --- scram-0.16.1/src/expression/conditional.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/expression/conditional.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,8 +22,7 @@ #include -namespace scram { -namespace mef { +namespace scram::mef { Interval Ite::interval() noexcept { assert(args().size() == 3); @@ -56,5 +55,4 @@ return Interval::closed(min_value, max_value); } -} // namespace mef -} // namespace scram +} // namespace scram::mef diff -Nru scram-0.16.1/src/expression/conditional.h scram-0.16.2/src/expression/conditional.h --- scram-0.16.1/src/expression/conditional.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/expression/conditional.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,15 +18,13 @@ /// @file /// Conditional (if-then-else, switch-case) expressions. -#ifndef SCRAM_SRC_EXPRESSION_CONDITIONAL_H_ -#define SCRAM_SRC_EXPRESSION_CONDITIONAL_H_ +#pragma once #include #include "src/expression.h" -namespace scram { -namespace mef { +namespace scram::mef { /// If-Then-Else ternary expression. class Ite : public ExpressionFormula { @@ -77,7 +75,4 @@ Expression& default_value_; ///< The default case value. }; -} // namespace mef -} // namespace scram - -#endif // SCRAM_SRC_EXPRESSION_CONDITIONAL_H_ +} // namespace scram::mef diff -Nru scram-0.16.1/src/expression/constant.cc scram-0.16.2/src/expression/constant.cc --- scram-0.16.1/src/expression/constant.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/expression/constant.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,13 +22,11 @@ #include -namespace scram { -namespace mef { +namespace scram::mef { ConstantExpression ConstantExpression::kOne(1); ConstantExpression ConstantExpression::kZero(0); ConstantExpression ConstantExpression::kPi( // This line confuses some linters! boost::math::constants::pi()); -} // namespace mef -} // namespace scram +} // namespace scram::mef diff -Nru scram-0.16.1/src/expression/constant.h scram-0.16.2/src/expression/constant.h --- scram-0.16.1/src/expression/constant.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/expression/constant.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,13 +18,11 @@ /// @file /// Constant expressions that cannot have uncertainties. -#ifndef SCRAM_SRC_EXPRESSION_CONSTANT_H_ -#define SCRAM_SRC_EXPRESSION_CONSTANT_H_ +#pragma once #include "src/expression.h" -namespace scram { -namespace mef { +namespace scram::mef { /// Indicates a constant value. class ConstantExpression : public Expression { @@ -48,7 +46,4 @@ const double value_; ///< The universal value to represent int, bool, double. }; -} // namespace mef -} // namespace scram - -#endif // SCRAM_SRC_EXPRESSION_CONSTANT_H_ +} // namespace scram::mef diff -Nru scram-0.16.1/src/expression/exponential.cc scram-0.16.2/src/expression/exponential.cc --- scram-0.16.1/src/expression/exponential.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/expression/exponential.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,8 +24,7 @@ #include "src/error.h" -namespace scram { -namespace mef { +namespace scram::mef { namespace { // Poisson process probability evaluators. @@ -304,5 +303,4 @@ sigma_.Sample(), omega_.Sample(), time_.Sample()); } -} // namespace mef -} // namespace scram +} // namespace scram::mef diff -Nru scram-0.16.1/src/expression/exponential.h scram-0.16.2/src/expression/exponential.h --- scram-0.16.1/src/expression/exponential.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/expression/exponential.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,15 +19,13 @@ /// Expressions and distributions /// that are described with exponential formulas. -#ifndef SCRAM_SRC_EXPRESSION_EXPONENTIAL_H_ -#define SCRAM_SRC_EXPRESSION_EXPONENTIAL_H_ +#pragma once #include #include "src/expression.h" -namespace scram { -namespace mef { +namespace scram::mef { /// Negative exponential distribution /// with hourly failure rate and time. @@ -256,7 +254,4 @@ std::unique_ptr flavor_; ///< Specialized flavor of calculations. }; -} // namespace mef -} // namespace scram - -#endif // SCRAM_SRC_EXPRESSION_EXPONENTIAL_H_ +} // namespace scram::mef diff -Nru scram-0.16.1/src/expression/extern.cc scram-0.16.2/src/expression/extern.cc --- scram-0.16.1/src/expression/extern.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/expression/extern.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,121 +20,11 @@ #include "extern.h" -#include - #include -#include - -#if BOOST_VERSION < 106100 - -#if !BOOST_OS_LINUX -#error "Dynamic library loading w/o Boost 1.61 is supported only on Linux." -#endif - -#include - -/// Use POSIX directly on Linux only. -#define DSO_LINUX 1 - -#else - -#include -#include -#include -#include - -#endif - -#include "src/error.h" namespace fs = boost::filesystem; -namespace scram { -namespace mef { - -#if DSO_LINUX -/// Implementation of external library load facilities. -class ExternLibrary::Pimpl { - public: - /// Loads the library for ExternLibrary. - Pimpl(std::string lib_path, const fs::path& reference_dir, bool system, - bool decorate) - : lib_handle_(nullptr) { - if (decorate) { - lib_path += ".so"; - auto pos = lib_path.rfind('/'); - lib_path.insert(pos == std::string::npos ? 0 : (pos + 1), "lib"); - } - if (!system || lib_path.find('/') != std::string::npos) { - fs::path abs_path = fs::absolute(lib_path, reference_dir); - lib_handle_ = dlopen(abs_path.c_str(), RTLD_LAZY); - } else { - lib_handle_ = dlopen(lib_path.c_str(), RTLD_LAZY); - } - - if (!lib_handle_) - SCRAM_THROW(DLError(dlerror())); - } - - /// @copydoc ExternLibrary::~ExternLibrary - ~Pimpl() { - int err = dlclose(lib_handle_); - assert(!err && "Failed to close dynamic library."); - } - - /// Retrieves the symbol from the loaded library. - void* get(const char* symbol) const { - dlerror(); // Clear the error message. - void* fptr = dlsym(lib_handle_, symbol); - const char* err = dlerror(); - if (!fptr && err) - SCRAM_THROW(UndefinedElement(err)); - - return fptr; - } - - private: - void* lib_handle_; ///< Handle to the library for reference. -}; -#else -/// Implementation of external library load facilities. -class ExternLibrary::Pimpl { - public: - /// Loads the library for ExternLibrary. - Pimpl(std::string lib_path, const fs::path& reference_dir, bool system, - bool decorate) { - boost::dll::load_mode::type load_type = boost::dll::load_mode::default_mode; - if (decorate) - load_type |= boost::dll::load_mode::append_decorations; - if (system) - load_type |= boost::dll::load_mode::search_system_folders; - - fs::path ref_path = lib_path; - if (!system || ref_path.has_parent_path()) - ref_path = fs::absolute(ref_path, reference_dir); - - try { - lib_handle_.load(ref_path, load_type); - } catch (const boost::system::system_error& err) { - SCRAM_THROW(DLError(err.what())) - << boost::errinfo_nested_exception(boost::current_exception()); - } - } - - /// Retrieves the symbol from the loaded library. - void* get(const char* symbol) const { - try { - return reinterpret_cast(lib_handle_.get(symbol)); - } catch (const boost::system::system_error& err) { - SCRAM_THROW(UndefinedElement(err.what())) - << boost::errinfo_nested_exception(boost::current_exception()); - } - } - - private: - boost::dll::shared_library lib_handle_; ///< Shared Library abstraction. -}; -#endif +namespace scram::mef { ExternLibrary::ExternLibrary(std::string name, std::string lib_path, const fs::path& reference_dir, bool system, @@ -153,14 +43,22 @@ } // clang-format on - pimpl_ = new Pimpl(std::move(lib_path), reference_dir, system, decorate); -} - -ExternLibrary::~ExternLibrary() { delete pimpl_; } - -void* ExternLibrary::get(const char* symbol) const { - return pimpl_->get(symbol); + boost::dll::load_mode::type load_type = boost::dll::load_mode::default_mode; + if (decorate) + load_type |= boost::dll::load_mode::append_decorations; + if (system) + load_type |= boost::dll::load_mode::search_system_folders; + + fs::path ref_path = lib_path; + if (!system || ref_path.has_parent_path()) + ref_path = fs::absolute(ref_path, reference_dir); + + try { + lib_handle_.load(ref_path, load_type); + } catch (const boost::system::system_error& err) { + SCRAM_THROW(DLError(err.what())) + << boost::errinfo_nested_exception(boost::current_exception()); + } } -} // namespace mef -} // namespace scram +} // namespace scram::mef diff -Nru scram-0.16.1/src/expression/extern.h scram-0.16.2/src/expression/extern.h --- scram-0.16.1/src/expression/extern.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/expression/extern.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,28 +18,29 @@ /// @file /// The MEF facilities to call external functions in expressions. -#ifndef SCRAM_SRC_EXPRESSION_EXTERN_H_ -#define SCRAM_SRC_EXPRESSION_EXTERN_H_ +#pragma once #include #include #include #include +#include +#include +#include #include -#include +#include #include "src/element.h" #include "src/error.h" #include "src/expression.h" -namespace scram { -namespace mef { +namespace scram::mef { /// The MEF construct to extend expressions with external libraries. /// This class dynamically loads and manages libraries. /// It supports only very basic interface for C function lookup with its symbol. -class ExternLibrary : public Element, public Usage, private boost::noncopyable { +class ExternLibrary : public Element, public Usage { public: /// @copydoc Element::Element /// @@ -54,40 +55,26 @@ const boost::filesystem::path& reference_dir, bool system, bool decorate); - ~ExternLibrary(); ///< Closes the loaded library. - - /// @tparam F The C free function pointer type. + /// @tparam F The C free function type. /// /// @param[in] symbol The function symbol in the library. /// /// @returns The function pointer resolved from the symbol. /// /// @throws UndefinedElement The symbol is not in the library. - /// - /// @note The functionality should fail at compile time (UB in C) - /// if the platform doesn't support - /// object pointer to function pointer casts. template - std::enable_if_t::value && - std::is_function>::value, - F> + std::enable_if_t, std::add_pointer_t> get(const std::string& symbol) const { - return reinterpret_cast(get(symbol.c_str())); + try { + return lib_handle_.get(symbol); + } catch (const boost::system::system_error& err) { + SCRAM_THROW(UndefinedElement(err.what())) + << boost::errinfo_nested_exception(boost::current_exception()); + } } private: - /// Hides all the cross-platform shared library faculties. - /// @todo Remove/refactor after switching to Boost 1.61 on Linux. - class Pimpl; - - /// @param[in] symbol The function symbol in the library. - /// - /// @returns The function loaded from the library symbol. - /// - /// @throws UndefinedElement The symbol is not in the library. - void* get(const char* symbol) const; - - Pimpl* pimpl_; ///< Provides basic implementation for function discovery. + boost::dll::shared_library lib_handle_; ///< Shared Library abstraction. }; template @@ -99,8 +86,7 @@ /// /// The base acts as a factory for generating expressions with given arguments. template <> -class ExternFunction - : public Element, public Usage, private boost::noncopyable { +class ExternFunction : public Element, public Usage { public: using Element::Element; @@ -131,7 +117,7 @@ /// @pre The source dynamic library is loaded as long as this function lives. template class ExternFunction : public ExternFunctionBase { - static_assert(std::is_arithmetic::value, "Numeric type functions only."); + static_assert(std::is_arithmetic_v, "Numeric type functions only."); using Pointer = R (*)(Args...); ///< The function pointer type. @@ -147,7 +133,7 @@ ExternFunction(std::string name, const std::string& symbol, const ExternLibrary& library) : ExternFunctionBase(std::move(name)), - fptr_(library.get(symbol)) {} + fptr_(library.get(symbol)) {} /// Calls the library function with the given numeric arguments. R operator()(Args... args) const noexcept { return fptr_(args...); } @@ -162,35 +148,36 @@ namespace detail { // Helpers for extern function call with Expression values. +/// Evaluates the argument expressions and marshals the result to function. /// Marshaller of expressions to extern function calls. /// /// @tparam N The number of arguments. /// +/// @param[in] self The extern function to be called with the argument values. +/// @param[in] args The argument expressions. +/// @param[in] eval The evaluator of the expressions. +/// @param[in] values The results of expression evaluation. +/// +/// @returns The result of the function call. +/// /// @pre The number of arguments is exactly the same at runtime. -template -struct Marshaller { - /// Evaluates the argument expressions and marshals the result to function. - template - R operator()(const ExternFunction& self, - const std::vector& args, F&& eval, - Ts&&... values) const noexcept { - double value = eval(args[N - 1]); - return Marshaller()(self, args, std::forward(eval), value, - std::forward(values)...); - } -}; +template +R Marshal(const ExternFunction& self, + const std::vector& args, F&& eval, + Ts&&... values) noexcept { + static_assert(N >= 0); + assert(args.size() >= N); -/// Specialization to call the extern function with argument values. -template <> -struct Marshaller<0> { - /// Calls the extern function with the argument values. - template - R operator()(const ExternFunction& self, - const std::vector&, F&&, Ts&&... values) const - noexcept { + if constexpr (N == 0) { + assert(args.size() == sizeof...(values) && "Incorrect number of args."); return self(std::forward(values)...); + + } else { + double value = eval(args[N - 1]); + return Marshal(self, args, std::forward(eval), value, + std::forward(values)...); } -}; +} } // namespace detail @@ -218,7 +205,7 @@ /// Computes the extern function with the given evaluator for arguments. template double Compute(F&& eval) noexcept { - return detail::Marshaller()( + return detail::Marshal( extern_function_, Expression::args(), std::forward(eval)); } @@ -232,7 +219,4 @@ return std::make_unique>(this, std::move(args)); } -} // namespace mef -} // namespace scram - -#endif // SCRAM_SRC_EXPRESSION_EXTERN_H_ +} // namespace scram::mef diff -Nru scram-0.16.1/src/expression/numerical.cc scram-0.16.2/src/expression/numerical.cc --- scram-0.16.1/src/expression/numerical.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/expression/numerical.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,8 +22,7 @@ #include "src/error.h" -namespace scram { -namespace mef { +namespace scram::mef { /// @cond Doxygen_With_Smart_Using_Declaration template <> @@ -73,5 +72,4 @@ SCRAM_THROW(ValidityError("Expression requires 2 or more arguments.")); } -} // namespace mef -} // namespace scram +} // namespace scram::mef diff -Nru scram-0.16.1/src/expression/numerical.h scram-0.16.2/src/expression/numerical.h --- scram-0.16.1/src/expression/numerical.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/expression/numerical.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,8 +19,7 @@ /// A collection of numerical expressions. /// @note The PI value is located in constant expressions. -#ifndef SCRAM_SRC_EXPRESSION_NUMERICAL_H_ -#define SCRAM_SRC_EXPRESSION_NUMERICAL_H_ +#pragma once #include @@ -30,8 +29,7 @@ #include "constant.h" #include "src/expression.h" -namespace scram { -namespace mef { +namespace scram::mef { /// Creates a functor out of function pointer to common cmath functions. template @@ -190,7 +188,4 @@ /// @} /// @endcond -} // namespace mef -} // namespace scram - -#endif // SCRAM_SRC_EXPRESSION_NUMERICAL_H_ +} // namespace scram::mef diff -Nru scram-0.16.1/src/expression/random_deviate.cc scram-0.16.2/src/expression/random_deviate.cc --- scram-0.16.1/src/expression/random_deviate.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/expression/random_deviate.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,14 +28,15 @@ #include #include #include +#include #include #include "src/error.h" #include "src/ext/algorithm.h" -#include "src/random.h" -namespace scram { -namespace mef { +namespace scram::mef { + +std::mt19937 RandomDeviate::rng_; UniformDeviate::UniformDeviate(Expression* min, Expression* max) : RandomDeviate({min, max}), min_(*min), max_(*max) {} @@ -48,7 +49,8 @@ } double UniformDeviate::DoSample() noexcept { - return Random::UniformRealGenerator(min_.value(), max_.value()); + return std::uniform_real_distribution(min_.value(), + max_.value())(RandomDeviate::rng()); } NormalDeviate::NormalDeviate(Expression* mean, Expression* sigma) @@ -61,7 +63,8 @@ } double NormalDeviate::DoSample() noexcept { - return Random::NormalGenerator(mean_.value(), sigma_.value()); + return std::normal_distribution(mean_.value(), + sigma_.value())(RandomDeviate::rng()); } LognormalDeviate::LognormalDeviate(Expression* mean, Expression* ef, @@ -86,7 +89,8 @@ } double LognormalDeviate::DoSample() noexcept { - return Random::LognormalGenerator(flavor_->location(), flavor_->scale()); + return std::lognormal_distribution(flavor_->location(), + flavor_->scale())(RandomDeviate::rng()); } Interval LognormalDeviate::interval() noexcept { @@ -136,7 +140,8 @@ } double GammaDeviate::DoSample() noexcept { - return Random::GammaGenerator(k_.value(), theta_.value()); + return std::gamma_distribution(k_.value())(RandomDeviate::rng()) * + theta_.value(); } BetaDeviate::BetaDeviate(Expression* alpha, Expression* beta) @@ -161,7 +166,8 @@ } double BetaDeviate::DoSample() noexcept { - return Random::BetaGenerator(alpha_.value(), beta_.value()); + return boost::random::beta_distribution(alpha_.value(), + beta_.value())(RandomDeviate::rng()); } Histogram::Histogram(std::vector boundaries, @@ -220,10 +226,12 @@ } // namespace double Histogram::DoSample() noexcept { - return Random::HistogramGenerator(make_sampler(boundaries_.begin()), - make_sampler(boundaries_.end()), - make_sampler(weights_.begin())); + // clang-format off + return std::piecewise_constant_distribution( + make_sampler(boundaries_.begin()), + make_sampler(boundaries_.end()), + make_sampler(weights_.begin()))(RandomDeviate::rng()); + // clang-format on } -} // namespace mef -} // namespace scram +} // namespace scram::mef diff -Nru scram-0.16.1/src/expression/random_deviate.h scram-0.16.2/src/expression/random_deviate.h --- scram-0.16.1/src/expression/random_deviate.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/expression/random_deviate.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,26 +19,45 @@ /// A collection of deviate expressions with random distributions /// sampled at run-time. -#ifndef SCRAM_SRC_EXPRESSION_RANDOM_DEVIATE_H_ -#define SCRAM_SRC_EXPRESSION_RANDOM_DEVIATE_H_ +#pragma once #include +#include #include #include #include "src/expression.h" -namespace scram { -namespace mef { +namespace scram::mef { /// Abstract base class for all deviate expressions. /// These expressions provide quantification for uncertainty and sensitivity. +/// +/// @note Only single RNG is embedded for convenience. +/// All the distributions share this RNG. +/// This is not suitable for parallelized simulations!!! +/// +/// @todo Parametrize with RNG (requires mef::Expression interface change). class RandomDeviate : public Expression { public: using Expression::Expression; bool IsDeviate() noexcept override { return true; } + + /// Sets the seed of the underlying random number generator. + /// + /// @param[in] seed The seed for RNGs. + /// + /// @note This is static! Used by all the deriving deviates. + static void seed(unsigned seed) noexcept { rng_.seed(seed); } + + protected: + /// @returns RNG to be used by derived classes. + std::mt19937& rng() { return rng_; } + + private: + static std::mt19937 rng_; ///< The random number generator. }; /// Uniform distribution. @@ -261,7 +280,4 @@ IteratorRange weights_; ///< Weights of the intervals. }; -} // namespace mef -} // namespace scram - -#endif // SCRAM_SRC_EXPRESSION_RANDOM_DEVIATE_H_ +} // namespace scram::mef diff -Nru scram-0.16.1/src/expression/test_event.cc scram-0.16.2/src/expression/test_event.cc --- scram-0.16.1/src/expression/test_event.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/expression/test_event.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,8 +22,7 @@ #include "src/ext/find_iterator.h" -namespace scram { -namespace mef { +namespace scram::mef { double TestInitiatingEvent::value() noexcept { return context_.initiating_event == name_; @@ -35,5 +34,4 @@ return false; } -} // namespace mef -} // namespace scram +} // namespace scram::mef diff -Nru scram-0.16.1/src/expression/test_event.h scram-0.16.2/src/expression/test_event.h --- scram-0.16.1/src/expression/test_event.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/expression/test_event.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,16 +18,14 @@ /// @file /// Event tree analysis expressions to test functional and initiating events. -#ifndef SCRAM_SRC_EXPRESSION_TEST_EVENT_H_ -#define SCRAM_SRC_EXPRESSION_TEST_EVENT_H_ +#pragma once #include #include #include "src/expression.h" -namespace scram { -namespace mef { +namespace scram::mef { /// The context for test-event expressions. struct Context { @@ -85,7 +83,4 @@ std::string state_; ///< The state of the functional event. }; -} // namespace mef -} // namespace scram - -#endif // SCRAM_SRC_EXPRESSION_TEST_EVENT_H_ +} // namespace scram::mef diff -Nru scram-0.16.1/src/expression.cc scram-0.16.2/src/expression.cc --- scram-0.16.1/src/expression.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/expression.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,10 +20,12 @@ #include "expression.h" +#include + +#include "error.h" #include "ext/algorithm.h" -namespace scram { -namespace mef { +namespace scram::mef { Expression::Expression(std::vector args) : args_(std::move(args)), sampled_value_(0), sampled_(false) {} @@ -48,5 +50,60 @@ return ext::any_of(args_, [](Expression* arg) { return arg->IsDeviate(); }); } -} // namespace mef -} // namespace scram +namespace detail { + +void EnsureMultivariateArgs(std::vector args) { + if (args.size() < 2) + SCRAM_THROW(ValidityError("Expression requires 2 or more arguments.")); +} + +} // namespace detail + +void EnsureProbability(Expression* expression, const std::string& description, + const char* type) { + double value = expression->value(); + if (value < 0 || value > 1) + SCRAM_THROW(DomainError("Invalid " + std::string(type) + " value for " + + description)); + + if (IsProbability(expression->interval()) == false) + SCRAM_THROW(DomainError("Invalid " + std::string(type) + + " sample domain for " + description)); +} + +void EnsurePositive(Expression* expression, const std::string& description) { + if (expression->value() <= 0) + SCRAM_THROW(DomainError(description + " argument value must be positive.")); + if (IsPositive(expression->interval()) == false) + SCRAM_THROW( + DomainError(description + " argument sample domain must be positive.")); +} + +void EnsureNonNegative(Expression* expression, const std::string& description) { + if (expression->value() < 0) + SCRAM_THROW( + DomainError(description + " argument value cannot be negative.")); + if (IsNonNegative(expression->interval()) == false) + SCRAM_THROW(DomainError(description + + " argument sample cannot have negative values.")); +} + +void EnsureWithin(Expression* expression, const Interval& interval, + const char* type) { + double arg_value = expression->value(); + if (!Contains(interval, arg_value)) { + std::stringstream ss; + ss << type << " argument value [" << arg_value << "] must be in " + << interval << "."; + SCRAM_THROW(DomainError(ss.str())); + } + Interval arg_interval = expression->interval(); + if (!boost::icl::within(arg_interval, interval)) { + std::stringstream ss; + ss << type << " argument sample domain " << arg_interval << " must be in " + << interval << "."; + SCRAM_THROW(DomainError(ss.str())); + } +} + +} // namespace scram::mef diff -Nru scram-0.16.1/src/expression.h scram-0.16.2/src/expression.h --- scram-0.16.1/src/expression.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/expression.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,11 +19,9 @@ /// Provides the base class for all expressions /// and units for expression values. -#ifndef SCRAM_SRC_EXPRESSION_H_ -#define SCRAM_SRC_EXPRESSION_H_ +#pragma once #include -#include #include #include #include @@ -31,11 +29,7 @@ #include #include -#include "element.h" -#include "error.h" - -namespace scram { -namespace mef { +namespace scram::mef { /// Validation domain interval for expression values. using Interval = boost::icl::continuous_interval; @@ -226,6 +220,17 @@ } }; +namespace detail { + +/// Ensures the number of args for multivariate expressions. +/// +/// @param[in] args Argument expressions. +/// +/// @throws ValidityError The number of arguments is fewer than 2. +void EnsureMultivariateArgs(std::vector args); + +} // namespace detail + /// Multivariate expression. template class NaryExpression : public ExpressionFormula> { @@ -237,8 +242,7 @@ /// @throws ValidityError The number of arguments is fewer than 2. explicit NaryExpression(std::vector args) : ExpressionFormula>(std::move(args)) { - if (Expression::args().size() < 2) - SCRAM_THROW(ValidityError("Expression requires 2 or more arguments.")); + detail::EnsureMultivariateArgs(Expression::args()); } void Validate() const override {} @@ -282,18 +286,8 @@ /// @param[in] type The type of probability or fraction for error messages. /// /// @throws DomainError The expression is not suited for probability. -inline void EnsureProbability(Expression* expression, - const std::string& description, - const char* type = "probability") { - double value = expression->value(); - if (value < 0 || value > 1) - SCRAM_THROW(DomainError("Invalid " + std::string(type) + " value for " + - description)); - - if (IsProbability(expression->interval()) == false) - SCRAM_THROW(DomainError("Invalid " + std::string(type) + - " sample domain for " + description)); -} +void EnsureProbability(Expression* expression, const std::string& description, + const char* type = "probability"); /// Ensures that expression yields positive (> 0) values. /// @@ -301,14 +295,7 @@ /// @param[in] description The addition information for error messages. /// /// @throws DomainError The expression is not suited for positive values. -inline void EnsurePositive(Expression* expression, - const std::string& description) { - if (expression->value() <= 0) - SCRAM_THROW(DomainError(description + " argument value must be positive.")); - if (IsPositive(expression->interval()) == false) - SCRAM_THROW( - DomainError(description + " argument sample domain must be positive.")); -} +void EnsurePositive(Expression* expression, const std::string& description); /// Ensures that expression yields non-negative (>= 0) values. /// @@ -316,15 +303,7 @@ /// @param[in] description The addition information for error messages. /// /// @throws DomainError The expression is not suited for non-negative values. -inline void EnsureNonNegative(Expression* expression, - const std::string& description) { - if (expression->value() < 0) - SCRAM_THROW( - DomainError(description + " argument value cannot be negative.")); - if (IsNonNegative(expression->interval()) == false) - SCRAM_THROW(DomainError(description + - " argument sample cannot have negative values.")); -} +void EnsureNonNegative(Expression* expression, const std::string& description); /// Ensures that expression values are within the interval. /// @@ -333,25 +312,7 @@ /// @param[in] type The type of expression for error messages. /// /// @throws DomainError The expression is not suited for non-negative values. -inline void EnsureWithin(Expression* expression, const Interval& interval, - const char* type) { - double arg_value = expression->value(); - if (!Contains(interval, arg_value)) { - std::stringstream ss; - ss << type << " argument value [" << arg_value << "] must be in " - << interval << "."; - SCRAM_THROW(DomainError(ss.str())); - } - Interval arg_interval = expression->interval(); - if (!boost::icl::within(arg_interval, interval)) { - std::stringstream ss; - ss << type << " argument sample domain " << arg_interval << " must be in " - << interval << "."; - SCRAM_THROW(DomainError(ss.str())); - } -} - -} // namespace mef -} // namespace scram +void EnsureWithin(Expression* expression, const Interval& interval, + const char* type); -#endif // SCRAM_SRC_EXPRESSION_H_ +} // namespace scram::mef diff -Nru scram-0.16.1/src/ext/algorithm.h scram-0.16.2/src/ext/algorithm.h --- scram-0.16.1/src/ext/algorithm.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/ext/algorithm.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2017 Olzhas Rakhimov + * Copyright (C) 2016-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,7 @@ /// @file /// Helpful algorithm facilities as an extension to the STL or Boost. -#ifndef SCRAM_SRC_EXT_ALGORITHM_H_ -#define SCRAM_SRC_EXT_ALGORITHM_H_ +#pragma once #include @@ -80,5 +79,3 @@ /// @} } // namespace ext - -#endif // SCRAM_SRC_EXT_ALGORITHM_H_ diff -Nru scram-0.16.1/src/ext/bits.h scram-0.16.2/src/ext/bits.h --- scram-0.16.1/src/ext/bits.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/ext/bits.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,7 @@ /// @file /// Helper constexpr functions to make bit operations explicit. -#ifndef SCRAM_SRC_EXT_BITS_H_ -#define SCRAM_SRC_EXT_BITS_H_ +#pragma once namespace ext { @@ -66,5 +65,3 @@ } } // namespace ext - -#endif // SCRAM_SRC_EXT_BITS_H_ diff -Nru scram-0.16.1/src/ext/combination_iterator.h scram-0.16.2/src/ext/combination_iterator.h --- scram-0.16.1/src/ext/combination_iterator.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/ext/combination_iterator.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2017 Olzhas Rakhimov + * Copyright (C) 2016-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,7 @@ /// @file /// n-choose-k combination generation facilities. -#ifndef SCRAM_SRC_EXT_COMBINATION_ITERATOR_H_ -#define SCRAM_SRC_EXT_COMBINATION_ITERATOR_H_ +#pragma once #include #include @@ -93,5 +92,3 @@ } } // namespace ext - -#endif // SCRAM_SRC_EXT_COMBINATION_ITERATOR_H_ diff -Nru scram-0.16.1/src/ext/find_iterator.h scram-0.16.2/src/ext/find_iterator.h --- scram-0.16.1/src/ext/find_iterator.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/ext/find_iterator.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2017 Olzhas Rakhimov + * Copyright (C) 2016-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,7 @@ /// @file /// Convenience iterator adaptor to wrap find calls and results. -#ifndef SCRAM_SRC_EXT_FIND_ITERATOR_H_ -#define SCRAM_SRC_EXT_FIND_ITERATOR_H_ +#pragma once #include @@ -63,5 +62,3 @@ } } // namespace ext - -#endif // SCRAM_SRC_EXT_FIND_ITERATOR_H_ diff -Nru scram-0.16.1/src/ext/float_compare.h scram-0.16.2/src/ext/float_compare.h --- scram-0.16.1/src/ext/float_compare.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/ext/float_compare.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,7 @@ /// @file /// Floating pointing comparison helper functions. -#ifndef SCRAM_SRC_EXT_FLOAT_COMPARE_H_ -#define SCRAM_SRC_EXT_FLOAT_COMPARE_H_ +#pragma once #include #include @@ -42,5 +41,3 @@ } } // namespace ext - -#endif // SCRAM_SRC_EXT_FLOAT_COMPARE_H_ diff -Nru scram-0.16.1/src/ext/index_map.h scram-0.16.2/src/ext/index_map.h --- scram-0.16.1/src/ext/index_map.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/ext/index_map.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,7 @@ /// @file /// Non-zero based Index->Value map adapter on sequential containers. -#ifndef SCRAM_SRC_EXT_INDEX_MAP_H_ -#define SCRAM_SRC_EXT_INDEX_MAP_H_ +#pragma once #include @@ -56,5 +55,3 @@ }; } // namespace ext - -#endif // SCRAM_SRC_EXT_INDEX_MAP_H_ diff -Nru scram-0.16.1/src/ext/linear_map.h scram-0.16.2/src/ext/linear_map.h --- scram-0.16.1/src/ext/linear_map.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/ext/linear_map.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2017 Olzhas Rakhimov + * Copyright (C) 2016-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,7 @@ /// @file /// Implementation of a vector-based map for a small number of entries. -#ifndef SCRAM_SRC_EXT_LINEAR_MAP_H_ -#define SCRAM_SRC_EXT_LINEAR_MAP_H_ +#pragma once #include @@ -278,8 +277,7 @@ } mapped_type& at(const key_type& key) { - return const_cast( - static_cast(this)->at(key)); + return const_cast(std::as_const(*this).at(key)); } /// @} @@ -429,5 +427,3 @@ }; } // namespace ext - -#endif // SCRAM_SRC_EXT_LINEAR_MAP_H_ diff -Nru scram-0.16.1/src/ext/multi_index.h scram-0.16.2/src/ext/multi_index.h --- scram-0.16.1/src/ext/multi_index.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/ext/multi_index.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,8 +20,7 @@ #include -#ifndef SCRAM_SRC_EXT_MULTI_INDEX_H_ -#define SCRAM_SRC_EXT_MULTI_INDEX_H_ +#pragma once namespace ext { @@ -56,5 +55,3 @@ } } // namespace ext - -#endif // SCRAM_SRC_EXT_MULTI_INDEX_H_ diff -Nru scram-0.16.1/src/ext/scope_guard.h scram-0.16.2/src/ext/scope_guard.h --- scram-0.16.1/src/ext/scope_guard.h 1970-01-01 00:00:00.000000000 +0000 +++ scram-0.16.2/src/ext/scope_guard.h 2018-01-12 11:42:47.000000000 +0000 @@ -0,0 +1,185 @@ +// Copyright Yuri Kilochek 2017. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/// @file +/// Scope guard functionality with C++17. +/// Adapted from Yuri Kilochek's Boost.scope_guard. + +#pragma once + +#include +#include +#include +#include +#include + +#include +#include + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +namespace ext { + +namespace detail::scope_guard { + +template +auto apply_impl(Fn&& fn, Args&& args, std::index_sequence) noexcept( + noexcept(std::invoke(std::forward(fn), + std::get(std::forward(args))...))) + -> decltype(std::invoke(std::forward(fn), + std::get(std::forward(args))...)) { + return std::invoke(std::forward(fn), + std::get(std::forward(args))...); +} + +// Like `std::apply` but SFINAE friendly and propagates `noexcept`ness. +template +auto apply(Fn&& fn, Args&& args) noexcept(noexcept(apply_impl( + std::forward(fn), std::forward(args), + std::make_index_sequence>>()))) + -> decltype(apply_impl( + std::forward(fn), std::forward(args), + std::make_index_sequence>>())) { + return apply_impl( + std::forward(fn), std::forward(args), + std::make_index_sequence>>()); +} + +template +class callback { + Fn m_fn; + std::tuple m_args; + + public: + template && ... && + std::is_constructible_v)>*...> + explicit callback(Fn_&& fn, Args_&&... args) noexcept( + (std::is_nothrow_constructible_v && ... && + std::is_nothrow_constructible_v)) + : m_fn(std::forward(fn)), m_args(std::forward(args)...) {} + + template + auto operator()() noexcept(noexcept( + (void)scope_guard::apply(std::forward(m_fn), std::move(m_args)))) + -> decltype((void)scope_guard::apply(std::forward(m_fn), + std::move(m_args))) { + return (void)scope_guard::apply(std::forward(m_fn), std::move(m_args)); + } +}; + +template +class base { + protected: + using callback_type = detail::scope_guard::callback; + + callback_type callback; + + public: + static_assert(std::is_invocable_v, "callback not invocable"); + + template < + typename... Params_, + std::enable_if_t>*...> + explicit base(Params_&&... params) noexcept( + std::is_nothrow_constructible_v) + : callback(std::forward(params)...) {} + + base(base const&) = delete; + auto operator=(base const&) -> base& = delete; + + base(base&&) = delete; + auto operator=(base &&) -> base& = delete; +}; + +template +struct unwrap { + using type = T; +}; + +template +struct unwrap> { + using type = T&; +}; + +template +using unwrap_decay_t = typename unwrap>::type; +} // namespace detail::scope_guard + +template +struct scope_guard : detail::scope_guard::base { + using base_type = detail::scope_guard::base; + using this_type = scope_guard; + + public: + using base_type::base_type; + + ~scope_guard() noexcept(noexcept(this_type::callback()) && + std::is_nothrow_destructible_v) { + this_type::callback(); + } +}; + +template +scope_guard(Params&&...) + ->scope_guard...>; + +template +struct scope_guard_failure : detail::scope_guard::base { + using base_type = detail::scope_guard::base; + using this_type = scope_guard_failure; + + int in = std::uncaught_exceptions(); + + public: + using detail::scope_guard::base::base; + + ~scope_guard_failure() noexcept(noexcept(this_type::callback()) && + std::is_nothrow_destructible_v) { + int out = std::uncaught_exceptions(); + if (BOOST_UNLIKELY(out > in)) { + this_type::callback(); + } + } +}; + +template +scope_guard_failure(Params&&...) + ->scope_guard_failure...>; + +template +struct scope_guard_success : detail::scope_guard::base { + using base_type = detail::scope_guard::base; + using this_type = scope_guard_success; + + int in = std::uncaught_exceptions(); + + public: + using detail::scope_guard::base::base; + + ~scope_guard_success() noexcept(noexcept(this_type::callback()) && + std::is_nothrow_destructible_v) { + int out = std::uncaught_exceptions(); + if (BOOST_LIKELY(out == in)) { + this_type::callback(); + } + } +}; + +template +scope_guard_success(Params&&...) + ->scope_guard_success...>; + +} // namespace ext + +#define SCOPE_EXIT(fn) ext::scope_guard BOOST_PP_CAT(scope_guard_, __LINE__)(fn) + +#define SCOPE_FAIL(fn) \ + ext::scope_guard_failure BOOST_PP_CAT(scope_fail_, __LINE__)(fn) + +#define SCOPE_SUCCESS(fn) \ + ext::scope_guard_success BOOST_PP_CAT(scope_success_, __LINE__)(fn) + +#endif // DOXYGEN_SHOULD_SKIP_THIS diff -Nru scram-0.16.1/src/ext/source_info.h scram-0.16.2/src/ext/source_info.h --- scram-0.16.1/src/ext/source_info.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/ext/source_info.h 2018-01-12 11:42:47.000000000 +0000 @@ -18,8 +18,7 @@ /// @file /// Helper facilities to get source file information. -#ifndef SCRAM_SRC_EXT_SOURCE_INFO_H_ -#define SCRAM_SRC_EXT_SOURCE_INFO_H_ +#pragma once /// Check if CMake provides required definitions. #ifndef PROJECT_SOURCE_DIR @@ -34,5 +33,3 @@ "The source file is not inside the project directory."); \ return __FILE__ + sizeof(PROJECT_SOURCE_DIR); \ }() - -#endif // SCRAM_SRC_EXT_SOURCE_INFO_H_ diff -Nru scram-0.16.1/src/ext/variant.h scram-0.16.2/src/ext/variant.h --- scram-0.16.1/src/ext/variant.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/ext/variant.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,12 +16,11 @@ */ /// @file -/// Extra helper functions for boost::variant. +/// Extra helper functions for std::variant. -#ifndef SCRAM_SRC_EXT_VARIANT_H_ -#define SCRAM_SRC_EXT_VARIANT_H_ +#pragma once -#include +#include namespace ext { @@ -34,11 +33,8 @@ /// /// @returns The stored value cast to the type T. template -T as(const boost::variant& var) { - return boost::apply_visitor([](auto& arg) { return static_cast(arg); }, - var); +T as(const std::variant& var) { + return std::visit([](auto& arg) { return static_cast(arg); }, var); } } // namespace ext - -#endif // SCRAM_SRC_EXT_VARIANT_H_ diff -Nru scram-0.16.1/src/fault_tree_analysis.cc scram-0.16.2/src/fault_tree_analysis.cc --- scram-0.16.1/src/fault_tree_analysis.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/fault_tree_analysis.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -29,8 +29,7 @@ #include "event.h" #include "logger.h" -namespace scram { -namespace core { +namespace scram::core { void Print(const ProductContainer& products) { if (products.empty()) { @@ -136,5 +135,4 @@ #endif } -} // namespace core -} // namespace scram +} // namespace scram::core diff -Nru scram-0.16.1/src/fault_tree_analysis.h scram-0.16.2/src/fault_tree_analysis.h --- scram-0.16.1/src/fault_tree_analysis.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/fault_tree_analysis.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,7 @@ /// @file /// Fault Tree Analysis. -#ifndef SCRAM_SRC_FAULT_TREE_ANALYSIS_H_ -#define SCRAM_SRC_FAULT_TREE_ANALYSIS_H_ +#pragma once #include @@ -36,15 +35,13 @@ #include "settings.h" #include "zbdd.h" -namespace scram { - -namespace mef { // Decouple from the analysis code. +namespace scram::mef { // Decouple from the analysis code. class Model; // Provider of substitutions. class Gate; class BasicEvent; -} // namespace mef +} // namespace scram::mef -namespace core { +namespace scram::core { /// Event or its complement /// that may appear in products. @@ -316,7 +313,4 @@ std::unique_ptr algorithm_; ///< Analysis algorithm. }; -} // namespace core -} // namespace scram - -#endif // SCRAM_SRC_FAULT_TREE_ANALYSIS_H_ +} // namespace scram::core diff -Nru scram-0.16.1/src/fault_tree.cc scram-0.16.2/src/fault_tree.cc --- scram-0.16.1/src/fault_tree.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/fault_tree.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,8 +22,7 @@ #include "error.h" -namespace scram { -namespace mef { +namespace scram::mef { Component::Component(std::string name, std::string base_path, RoleSpecifier role) @@ -140,7 +139,7 @@ void FaultTree::MarkNonTopGates(const Formula& formula, const std::unordered_set& gates) { for (const Formula::EventArg& event_arg : formula.event_args()) { - if (auto* gate = boost::get(&event_arg)) { + if (Gate* const* gate = std::get_if(&event_arg)) { if (gates.count(*gate)) { MarkNonTopGates(*gate, gates); (*gate)->mark(NodeMark::kPermanent); // Any non clear mark can be used. @@ -152,5 +151,4 @@ } } -} // namespace mef -} // namespace scram +} // namespace scram::mef diff -Nru scram-0.16.1/src/fault_tree.h scram-0.16.2/src/fault_tree.h --- scram-0.16.1/src/fault_tree.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/fault_tree.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,26 +18,22 @@ /// @file /// Fault Tree and Component containers. -#ifndef SCRAM_SRC_FAULT_TREE_H_ -#define SCRAM_SRC_FAULT_TREE_H_ +#pragma once #include #include #include #include -#include - #include "ccf_group.h" #include "element.h" #include "event.h" #include "parameter.h" -namespace scram { -namespace mef { +namespace scram::mef { /// Component is for logical grouping of events, gates, and other components. -class Component : public Element, public Role, private boost::noncopyable { +class Component : public Element, public Role { public: /// Constructs a component assuming /// that it exists within some fault tree. @@ -181,7 +177,4 @@ using FaultTreePtr = std::unique_ptr; ///< Unique trees in models. -} // namespace mef -} // namespace scram - -#endif // SCRAM_SRC_FAULT_TREE_H_ +} // namespace scram::mef diff -Nru scram-0.16.1/src/importance_analysis.cc scram-0.16.2/src/importance_analysis.cc --- scram-0.16.1/src/importance_analysis.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/importance_analysis.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,8 +27,7 @@ #include "logger.h" #include "zbdd.h" -namespace scram { -namespace core { +namespace scram::core { ImportanceAnalysis::ImportanceAnalysis(const ProbabilityAnalysis* prob_analysis) : Analysis(prob_analysis->settings()) {} @@ -145,5 +144,4 @@ return Ite::Ref(vertex).p(); } -} // namespace core -} // namespace scram +} // namespace scram::core diff -Nru scram-0.16.1/src/importance_analysis.h scram-0.16.2/src/importance_analysis.h --- scram-0.16.1/src/importance_analysis.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/importance_analysis.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,8 +19,7 @@ /// Contains functionality to do numerical analysis /// of importance factors. -#ifndef SCRAM_SRC_IMPORTANCE_ANALYSIS_H_ -#define SCRAM_SRC_IMPORTANCE_ANALYSIS_H_ +#pragma once #include @@ -28,13 +27,11 @@ #include "probability_analysis.h" #include "settings.h" -namespace scram { - -namespace mef { // Decouple from the analysis code header. +namespace scram::mef { // Decouple from the analysis code header. class BasicEvent; -} // namespace mef +} // namespace scram::mef -namespace core { +namespace scram::core { /// Collection of importance factors for variables. struct ImportanceFactors { @@ -199,7 +196,4 @@ Bdd* bdd_graph_; ///< Binary decision diagram for the analyzer. }; -} // namespace core -} // namespace scram - -#endif // SCRAM_SRC_IMPORTANCE_ANALYSIS_H_ +} // namespace scram::core diff -Nru scram-0.16.1/src/initializer.cc scram-0.16.2/src/initializer.cc --- scram-0.16.1/src/initializer.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/initializer.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -44,8 +44,7 @@ #include "ext/find_iterator.h" #include "logger.h" -namespace scram { -namespace mef { +namespace scram::mef { namespace { // Helper function and wrappers for MEF initializations. @@ -54,7 +53,7 @@ /// @param[in] s Non-empty, valid role specifier string. /// /// @returns Role specifier attribute for elements. -RoleSpecifier GetRole(const xml::string_view& s) { +RoleSpecifier GetRole(const std::string_view& s) { assert(!s.empty()); assert(s == "public" || s == "private"); return s == "public" ? RoleSpecifier::kPublic : RoleSpecifier::kPrivate; @@ -66,7 +65,7 @@ /// @param[in] parent_role The role to be inherited. /// /// @returns The role for the element under consideration. -RoleSpecifier GetRole(const xml::string_view& s, RoleSpecifier parent_role) { +RoleSpecifier GetRole(const std::string_view& s, RoleSpecifier parent_role) { return s.empty() ? parent_role : GetRole(s); } @@ -81,20 +80,20 @@ /// @throws ValidityError Invalid attribute setting. void AttachLabelAndAttributes(const xml::Element& xml_element, Element* element) { - if (boost::optional label = xml_element.child("label")) { + if (std::optional label = xml_element.child("label")) { assert(element->label().empty() && "Resetting element label."); - element->label(label->text().to_string()); + element->label(std::string(label->text())); } - boost::optional attributes = xml_element.child("attributes"); + std::optional attributes = xml_element.child("attributes"); if (!attributes) return; for (const xml::Element& attribute : attributes->children()) { assert(attribute.name() == "attribute"); try { - element->AddAttribute({attribute.attribute("name").to_string(), - attribute.attribute("value").to_string(), - attribute.attribute("type").to_string()}); + element->AddAttribute({std::string(attribute.attribute("name")), + std::string(attribute.attribute("value")), + std::string(attribute.attribute("type"))}); } catch (ValidityError& err) { err << boost::errinfo_at_line(attribute.line()); throw; @@ -104,20 +103,21 @@ /// Constructs Element of type T from an XML element. template -std::enable_if_t::value, std::unique_ptr> +std::enable_if_t, std::unique_ptr> ConstructElement(const xml::Element& xml_element) { - auto element = std::make_unique(xml_element.attribute("name").to_string()); + auto element = + std::make_unique(std::string(xml_element.attribute("name"))); AttachLabelAndAttributes(xml_element, element.get()); return element; } /// Constructs Element of type T with a role from an XML element. template -std::enable_if_t::value, std::unique_ptr> +std::enable_if_t, std::unique_ptr> ConstructElement(const xml::Element& xml_element, const std::string& base_path, RoleSpecifier base_role) { auto element = - std::make_unique(xml_element.attribute("name").to_string(), base_path, + std::make_unique(std::string(xml_element.attribute("name")), base_path, GetRole(xml_element.attribute("role"), base_role)); AttachLabelAndAttributes(xml_element, element.get()); return element; @@ -131,7 +131,7 @@ auto GetNonAttributeElements(const xml::Element& xml_element) { return xml_element.children() | boost::adaptors::filtered([](const xml::Element& child) { - xml::string_view name = child.name(); + std::string_view name = child.name(); return name != "label" && name != "attributes"; }); } @@ -141,7 +141,7 @@ PhasePtr element; try { element = std::make_unique( - xml_element.attribute("name").to_string(), + std::string(xml_element.attribute("name")), *xml_element.attribute("time-fraction")); } catch (ValidityError& err) { err << boost::errinfo_at_line(xml_element.line()); @@ -281,7 +281,7 @@ path_house_events_.insert(house_event); // Only Boolean xml. - if (boost::optional constant = event_node.child("constant")) { + if (std::optional constant = event_node.child("constant")) { house_event->state(*constant->attribute("value")); } return house_event; @@ -299,7 +299,7 @@ tbd_.emplace_back(parameter, param_node); // Attach units. - xml::string_view unit = param_node.attribute("unit"); + std::string_view unit = param_node.attribute("unit"); if (!unit.empty()) { int pos = boost::find(kUnitsToString, unit) - std::begin(kUnitsToString); assert(pos < kNumUnits && "Unexpected unit kind."); @@ -313,7 +313,7 @@ const std::string& base_path, RoleSpecifier container_role) { auto ptr = [&]() -> CcfGroupPtr { - xml::string_view model = ccf_node.attribute("model"); + std::string_view model = ccf_node.attribute("model"); if (model == "beta-factor") return ConstructElement(ccf_node, base_path, container_role); @@ -348,7 +348,7 @@ /// @} void Initializer::ProcessInputFile(const std::string& xml_file) { - static xml::Validator validator(Env::input_schema()); + static xml::Validator validator(env::input_schema()); CLOCK(parse_time); LOG(DEBUG3) << "Parsing " << xml_file << " ..."; @@ -459,7 +459,7 @@ template <> void Initializer::Define(const xml::Element& ccf_node, CcfGroup* ccf_group) { for (const xml::Element& element : ccf_node.children()) { - xml::string_view name = element.name(); + std::string_view name = element.name(); if (name == "distribution") { ccf_group->AddDistribution( GetExpression(*element.child(), ccf_group->base_path())); @@ -501,7 +501,7 @@ template <> void Initializer::Define(const xml::Element& xml_node, InitiatingEvent* initiating_event) { - std::string event_tree_name = xml_node.attribute("event-tree").to_string(); + std::string event_tree_name(xml_node.attribute("event-tree")); if (!event_tree_name.empty()) { if (auto it = ext::find(model_->event_trees(), event_tree_name)) { initiating_event->event_tree(it->get()); @@ -554,10 +554,10 @@ substitution->hypothesis( GetFormula(xml_node.child("hypothesis")->child().value(), "")); - if (boost::optional source = xml_node.child("source")) { + if (std::optional source = xml_node.child("source")) { for (const xml::Element& basic_event : source->children()) { assert(basic_event.name() == "basic-event"); - std::string name = basic_event.attribute("name").to_string(); + std::string name(basic_event.attribute("name")); try { BasicEvent* event = GetBasicEvent(name, ""); substitution->Add(event); @@ -575,7 +575,7 @@ xml::Element target = xml_node.child("target")->child().value(); if (target.name() == "basic-event") { - std::string name = target.attribute("name").to_string(); + std::string name(target.attribute("name")); try { BasicEvent* event = GetBasicEvent(name, ""); substitution->target(event); @@ -591,9 +591,9 @@ try { substitution->Validate(); - xml::string_view type = xml_node.attribute("type"); + std::string_view type = xml_node.attribute("type"); if (!type.empty()) { - boost::optional deduced_type = substitution->type(); + std::optional deduced_type = substitution->type(); int pos = std::distance(kSubstitutionTypeToString, boost::find(kSubstitutionTypeToString, type)); assert(pos < 3 && "Unexpected substitution type string."); @@ -616,22 +616,21 @@ try { DefineExternFunction(node); } catch (ValidityError& err) { - err << boost::errinfo_file_name(root.filename().to_string()); + err << boost::errinfo_file_name(root.filename()); throw; } } } - for (const auto& tbd_element : tbd_) { + for (const auto & [ tbd_element, xml_element ] : tbd_) { try { - boost::apply_visitor( - [this, &tbd_element](auto* tbd_construct) { - this->Define(tbd_element.second, tbd_construct); + std::visit( + [this, &xml_element](auto* tbd_construct) { + this->Define(xml_element, tbd_construct); }, - tbd_element.first); + tbd_element); } catch (ValidityError& err) { - err << boost::errinfo_file_name( - tbd_element.second.filename().to_string()); + err << boost::errinfo_file_name(xml_element.filename()); throw; } } @@ -750,15 +749,15 @@ return; } - std::string name = element.attribute("name").to_string(); + std::string name(element.attribute("name")); if (name.empty()) { formula->AddArgument(GetFormula(element, base_path)); return; } - xml::string_view element_type = [&element] { + std::string_view element_type = [&element] { // This is for the case "". - xml::string_view type = element.attribute("type"); + std::string_view type = element.attribute("type"); return type.empty() ? element.name() : type; }(); @@ -778,7 +777,7 @@ } } catch (std::out_of_range&) { SCRAM_THROW(ValidityError( - "Undefined " + element_type.to_string() + " " + name + + "Undefined " + std::string(element_type) + " " + name + (base_path.empty() ? "" : " with base path " + base_path))) << boost::errinfo_at_line(element.line()); } catch (DuplicateArgumentError& err) { @@ -810,11 +809,11 @@ void Initializer::DefineBranchTarget(const xml::Element& target_node, EventTree* event_tree, Branch* branch) { if (target_node.name() == "fork") { - std::string name = target_node.attribute("functional-event").to_string(); + std::string name(target_node.attribute("functional-event")); if (auto it = ext::find(event_tree->functional_events(), name)) { std::vector paths; for (const xml::Element& path_element : target_node.children("path")) { - paths.emplace_back(path_element.attribute("state").to_string()); + paths.emplace_back(std::string(path_element.attribute("state"))); DefineBranch(path_element.children(), event_tree, &paths.back()); } assert(!paths.empty()); @@ -833,7 +832,7 @@ << boost::errinfo_at_line(target_node.line()); } } else if (target_node.name() == "sequence") { - std::string name = target_node.attribute("name").to_string(); + std::string name(target_node.attribute("name")); if (auto it = ext::find(model_->sequences(), name)) { branch->target(it->get()); (*it)->usage(true); @@ -844,7 +843,7 @@ } } else { assert(target_node.name() == "branch"); - std::string name = target_node.attribute("name").to_string(); + std::string name(target_node.attribute("name")); if (auto it = ext::find(event_tree->branches(), name)) { branch->target(it->get()); (*it)->usage(true); @@ -874,9 +873,9 @@ } Instruction* Initializer::GetInstruction(const xml::Element& xml_element) { - xml::string_view node_name = xml_element.name(); + std::string_view node_name = xml_element.name(); if (node_name == "rule") { - std::string name = xml_element.attribute("name").to_string(); + std::string name(xml_element.attribute("name")); if (auto it = ext::find(model_->rules(), name)) { (*it)->usage(true); return it->get(); @@ -894,7 +893,7 @@ }; if (node_name == "event-tree") { - std::string name = xml_element.attribute("name").to_string(); + std::string name(xml_element.attribute("name")); if (auto it = ext::find(model_->event_trees(), name)) { (*it)->usage(true); links_.push_back(static_cast( @@ -938,7 +937,7 @@ } if (node_name == "set-house-event") { - std::string name = xml_element.attribute("name").to_string(); + std::string name(xml_element.attribute("name")); if (!model_->house_events().count(name)) { SCRAM_THROW(ValidityError("House event " + name + " is not defined in the model.")) @@ -989,36 +988,19 @@ xml::Element::Range::iterator it_end, const std::string& base_path, Initializer* init, Ts&&... expressions) { - assert(it != it_end && "Not enough arguments in the args container."); - return Extractor()(std::next(it), it_end, base_path, init, - std::forward(expressions)..., - init->GetExpression(*it, base_path)); - } -}; + static_assert(N >= 0); -/// Partial specialization for terminal Extractor. -template -struct Initializer::Extractor { - /// Constructs the requested expression T - /// with all accumulated argument expressions. - /// - /// @tparam Ts Expression types. - /// - /// @param[in] it The iterator in the argument container. - /// @param[in] it_end The end sentinel iterator of the argument container. - /// @param[in] expressions All argument expressions for constructing T. - /// - /// @returns The constructed expression. - /// - /// @pre All the elements in the argument container has been processed. - template - std::unique_ptr operator()(xml::Element::Range::iterator it, - xml::Element::Range::iterator it_end, - const std::string& /*base_path*/, - Initializer* /*init*/, Ts&&... expressions) { - static_assert(sizeof...(Ts), "Unintended use case."); - assert(it == it_end && "Too many arguments in the args container."); - return std::make_unique(std::forward(expressions)...); + if constexpr (N == 0) { + static_assert(sizeof...(Ts), "Unintended use case."); + assert(it == it_end && "Too many arguments in the args container."); + return std::make_unique(std::forward(expressions)...); + + } else { + assert(it != it_end && "Not enough arguments in the args container."); + return Extractor()(std::next(it), it_end, base_path, init, + std::forward(expressions)..., + init->GetExpression(*it, base_path)); + } } }; @@ -1047,39 +1029,23 @@ /// @returns The number of constructor arguments for Expression types. /// @{ -template -constexpr int count_args(std::true_type) { - return sizeof...(As); -} - -template -constexpr int count_args(); - template -constexpr int count_args(std::false_type) { - return count_args(); -} - -template constexpr int count_args() { - return count_args(std::is_constructible()); -} - -template -constexpr int num_args(std::false_type) { - return count_args(); -} - -template -constexpr int num_args(std::true_type) { - return -1; + if constexpr (std::is_constructible_v) { + return 1 + sizeof...(As); + } else { + return count_args(); + } } template -constexpr std::enable_if_t::value, int> -num_args() { - static_assert(!std::is_default_constructible::value, "No zero args."); - return num_args(std::is_constructible>()); +constexpr std::enable_if_t, int> num_args() { + static_assert(!std::is_default_constructible_v, "No zero args."); + if constexpr (std::is_constructible_v>) { + return -1; + } else { + return count_args(); + } } /// @} @@ -1217,7 +1183,7 @@ Expression* Initializer::GetExpression(const xml::Element& expr_element, const std::string& base_path) { - xml::string_view expr_type = expr_element.name(); + std::string_view expr_type = expr_element.name(); auto register_expression = [this](std::unique_ptr expression) { auto* ret_ptr = expression.get(); model_->Add(std::move(expression)); @@ -1240,17 +1206,17 @@ if (expr_type == "test-initiating-event") { return register_expression(std::make_unique( - expr_element.attribute("name").to_string(), model_->context())); + std::string(expr_element.attribute("name")), model_->context())); } if (expr_type == "test-functional-event") { return register_expression(std::make_unique( - expr_element.attribute("name").to_string(), - expr_element.attribute("state").to_string(), model_->context())); + std::string(expr_element.attribute("name")), + std::string(expr_element.attribute("state")), model_->context())); } if (expr_type == "extern-function") { const ExternFunction* extern_function = [this, &expr_element] { - std::string name = expr_element.attribute("name").to_string(); + std::string name(expr_element.attribute("name")); auto it = model_->extern_functions().find(name); if (it == model_->extern_functions().end()) { SCRAM_THROW(ValidityError("Undefined extern function: " + name)) @@ -1277,7 +1243,7 @@ try { Expression* expression = register_expression(kExpressionExtractors_.at( - expr_type.to_string())(expr_element.children(), base_path, this)); + expr_type)(expr_element.children(), base_path, this)); // Register for late validation after ensuring no cycles. expressions_.emplace_back(expression, expr_element); return expression; @@ -1287,11 +1253,11 @@ } } -Expression* Initializer::GetParameter(const xml::string_view& expr_type, +Expression* Initializer::GetParameter(const std::string_view& expr_type, const xml::Element& expr_element, const std::string& base_path) { auto check_units = [&expr_element](const auto& parameter) { - xml::string_view unit = expr_element.attribute("unit"); + std::string_view unit = expr_element.attribute("unit"); const char* param_unit = scram::mef::kUnitsToString[parameter.unit()]; if (!unit.empty() && unit != param_unit) { std::stringstream msg; @@ -1303,7 +1269,7 @@ }; if (expr_type == "parameter") { - std::string name = expr_element.attribute("name").to_string(); + std::string name(expr_element.attribute("name")); try { Parameter* param = GetParameter(name, base_path); param->usage(true); @@ -1327,7 +1293,7 @@ for (const xml::Element& event_node : members_node.children()) { assert("basic-event" == event_node.name()); auto basic_event = - std::make_unique(event_node.attribute("name").to_string(), + std::make_unique(std::string(event_node.attribute("name")), ccf_group->base_path(), ccf_group->role()); try { ccf_group->AddMember(basic_event.get()); @@ -1435,14 +1401,14 @@ void Initializer::DefineExternLibraries(const xml::Element& xml_node, const std::string& xml_file) { auto optional_bool = [&xml_node](const char* tag) { - boost::optional attribute = xml_node.attribute(tag); + std::optional attribute = xml_node.attribute(tag); return attribute ? *attribute : false; }; auto library = [&xml_file, &xml_node, &optional_bool] { try { return std::make_unique( - xml_node.attribute("name").to_string(), - xml_node.attribute("path").to_string(), + std::string(xml_node.attribute("name")), + std::string(xml_node.attribute("path")), boost::filesystem::path(xml_file).parent_path(), optional_bool("system"), optional_bool("decorate")); } catch (DLError& err) { @@ -1481,7 +1447,7 @@ int Encode(const SinglePassRange& args) noexcept { assert(!args.empty()); auto to_digit = [](const xml::Element& node) -> int { - xml::string_view name = node.name(); + std::string_view name = node.name(); return static_cast([&name] { if (name == "int") return ExternParamType::kInt; @@ -1501,22 +1467,19 @@ } /// Encodes function parameter types at compile-time. -/// @{ template constexpr int Encode(int base_power = 1) noexcept { - return Encode(base_power) + Encode(base_power * kExternTypeBase); -} + if constexpr (sizeof...(Ts)) { + return Encode(base_power) + Encode(base_power * kExternTypeBase); -template <> -constexpr int Encode(int base_power) noexcept { - return base_power * static_cast(ExternParamType::kInt); -} + } else if constexpr (std::is_same_v) { + return base_power * static_cast(ExternParamType::kInt); -template <> -constexpr int Encode(int base_power) noexcept { - return base_power * static_cast(ExternParamType::kDouble); + } else { + static_assert(std::is_same_v); + return base_power * static_cast(ExternParamType::kDouble); + } } -/// @} using ExternFunctionExtractor = ExternFunctionPtr (*)(std::string, const std::string&, @@ -1524,37 +1487,31 @@ using ExternFunctionExtractorMap = std::unordered_map; +/// Generates all extractors for extern functions. +/// /// @tparam N The number of parameters. -template -struct ExternFunctionGenerator; - -template <> -struct ExternFunctionGenerator<0> { - template - static void Generate(ExternFunctionExtractorMap* function_map) noexcept { - ///< @todo GCC 4.9, 5.4 segfaults on move for lambda arguments. - struct Extractor { // Use instead of lambda! - static ExternFunctionPtr Extract(std::string name, - const std::string& symbol, - const ExternLibrary& library) { - return std::make_unique>(std::move(name), symbol, - library); - } - }; - function_map->emplace(Encode(), &Extractor::Extract); - } -}; - -template -struct ExternFunctionGenerator { - template - static void Generate(ExternFunctionExtractorMap* function_map) noexcept { - ExternFunctionGenerator<0>::template Generate(function_map); - ExternFunctionGenerator::template Generate(function_map); - ExternFunctionGenerator::template Generate( - function_map); +/// @tparam Ts The return and parameter types of the extern function. +/// +/// @param[in,out] function_map The destination container for extractor. +template +void GenerateExternFunctionExtractor(ExternFunctionExtractorMap* function_map) { + static_assert(N >= 0); + static_assert(sizeof...(Ts)); + + if constexpr (N == 0) { + function_map->emplace( + Encode(), + [](std::string name, const std::string& symbol, + const ExternLibrary& library) -> ExternFunctionPtr { + return std::make_unique>(std::move(name), + symbol, library); + }); + } else { + GenerateExternFunctionExtractor<0, Ts...>(function_map); + GenerateExternFunctionExtractor(function_map); + GenerateExternFunctionExtractor(function_map); } -}; +} } // namespace @@ -1562,14 +1519,14 @@ static const ExternFunctionExtractorMap function_extractors = [] { ExternFunctionExtractorMap function_map; function_map.reserve(kNumInterfaces); - ExternFunctionGenerator::Generate(&function_map); - ExternFunctionGenerator::Generate(&function_map); + GenerateExternFunctionExtractor(&function_map); + GenerateExternFunctionExtractor(&function_map); assert(function_map.size() == kNumInterfaces); return function_map; }(); const ExternLibrary& library = [this, &xml_element]() -> decltype(auto) { - std::string lib_name = xml_element.attribute("library").to_string(); + std::string lib_name(xml_element.attribute("library")); auto it = model_->libraries().find(lib_name); if (it == model_->libraries().end()) SCRAM_THROW(ValidityError("Undefined extern library: " + lib_name)) @@ -1593,8 +1550,8 @@ int encoding = Encode(args); try { return function_extractors.at(encoding)( - xml_element.attribute("name").to_string(), - xml_element.attribute("symbol").to_string(), library); + std::string(xml_element.attribute("name")), + std::string(xml_element.attribute("symbol")), library); } catch (ValidityError& err) { err << boost::errinfo_at_line(xml_element.line()); throw; @@ -1675,7 +1632,7 @@ void operator()(Sequence*) const {} void operator()(NamedBranch* named_branch) const { - boost::apply_visitor(*this, named_branch->target()); + std::visit(*this, named_branch->target()); } void operator()(Fork* fork) const { @@ -1702,14 +1659,13 @@ void operator()(Fork* fork) const { for (const Path& fork_path : fork->paths()) { initializer->CheckFunctionalEventOrder(fork_path); - boost::apply_visitor(CheckOrder{fork->functional_event()}, - fork_path.target()); + std::visit(CheckOrder{fork->functional_event()}, fork_path.target()); } } Initializer* initializer; }; - boost::apply_visitor(OrderValidator{this}, branch.target()); + std::visit(OrderValidator{this}, branch.target()); } void Initializer::EnsureLinksOnlyInSequences(const Branch& branch) { @@ -1727,7 +1683,7 @@ void operator()(const Branch* arg_branch) { for (const Instruction* instruction : arg_branch->instructions()) instruction->Accept(&validator); - boost::apply_visitor(*this, arg_branch->target()); + std::visit(*this, arg_branch->target()); } void operator()(Fork* fork) { @@ -1782,7 +1738,7 @@ } void operator()(const Branch* arg_branch) { CheckInstructions(arg_branch->instructions()); - boost::apply_visitor(*this, arg_branch->target()); + std::visit(*this, arg_branch->target()); } void operator()(const Fork* fork) { for (const Path& fork_path : fork->paths()) @@ -1801,7 +1757,7 @@ return !substitution->declarative(); }); for (const SubstitutionPtr& origin : substitutions) { - const auto* target_ptr = boost::get(&origin->target()); + const auto* target_ptr = std::get_if(&origin->target()); for (const SubstitutionPtr& substitution : substitutions) { if (target_ptr && boost::count(substitution->source(), *target_ptr)) SCRAM_THROW(ValidityError( @@ -1812,7 +1768,7 @@ auto in_hypothesis = [&substitution](const BasicEvent* source) { return ext::any_of(substitution->hypothesis().event_args(), [source](const Formula::EventArg& arg) { - return boost::get(arg) == source; + return std::get(arg) == source; }); }; if (target_ptr && in_hypothesis(*target_ptr)) @@ -1837,11 +1793,11 @@ auto is_ccf = [](const Substitution& substitution) { if (ext::any_of(substitution.hypothesis().event_args(), [](const Formula::EventArg& arg) { - return boost::get(arg)->HasCcf(); + return std::get(arg)->HasCcf(); })) return true; - const auto* target_ptr = boost::get(&substitution.target()); + const auto* target_ptr = std::get_if(&substitution.target()); if (target_ptr && (*target_ptr)->HasCcf()) return true; @@ -1881,7 +1837,7 @@ try { expression.first->Validate(); } catch (ValidityError& err) { - err << boost::errinfo_file_name(expression.second.filename().to_string()) + err << boost::errinfo_file_name(expression.second.filename()) << boost::errinfo_at_line(expression.second.line()); throw; } @@ -1917,5 +1873,4 @@ } } -} // namespace mef -} // namespace scram +} // namespace scram::mef diff -Nru scram-0.16.1/src/initializer.h scram-0.16.2/src/initializer.h --- scram-0.16.1/src/initializer.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/initializer.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,20 +18,20 @@ /// @file /// A facility that processes input files into analysis constructs. -#ifndef SCRAM_SRC_INITIALIZER_H_ -#define SCRAM_SRC_INITIALIZER_H_ +#pragma once #include #include +#include #include #include +#include #include #include #include #include #include -#include #include "alignment.h" #include "ccf_group.h" @@ -48,8 +48,7 @@ #include "substitution.h" #include "xml.h" -namespace scram { -namespace mef { +namespace scram::mef { /// This class operates on input files /// to initialize analysis constructs @@ -89,11 +88,11 @@ using ExtractorFunction = std::unique_ptr (*)( const xml::Element::Range&, const std::string&, Initializer*); /// Map of expression names and their extractor functions. - using ExtractorMap = std::unordered_map; + using ExtractorMap = std::unordered_map; /// Container for late defined constructs. template using TbdContainer = - std::vector, xml::Element>>; + std::vector, xml::Element>>; /// Container with full paths to elements. /// /// @tparam T The element type. @@ -328,7 +327,7 @@ /// @returns nullptr if the expression type is not a parameter. /// /// @throws ValidityError The parameter variable is not reachable. - Expression* GetParameter(const xml::string_view& expr_type, + Expression* GetParameter(const std::string_view& expr_type, const xml::Element& expr_element, const std::string& base_path); @@ -527,7 +526,4 @@ /// @} }; -} // namespace mef -} // namespace scram - -#endif // SCRAM_SRC_INITIALIZER_H_ +} // namespace scram::mef diff -Nru scram-0.16.1/src/instruction.h scram-0.16.2/src/instruction.h --- scram-0.16.1/src/instruction.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/instruction.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,7 @@ /// @file /// Model and event tree modifier instructions. -#ifndef SCRAM_SRC_INSTRUCTION_H_ -#define SCRAM_SRC_INSTRUCTION_H_ +#pragma once #include #include @@ -31,8 +30,7 @@ #include "event.h" #include "expression.h" -namespace scram { -namespace mef { +namespace scram::mef { class InstructionVisitor; @@ -232,7 +230,4 @@ visitor->Visit(static_cast(this)); } -} // namespace mef -} // namespace scram - -#endif // SCRAM_SRC_INSTRUCTION_H_ +} // namespace scram::mef diff -Nru scram-0.16.1/src/logger.h scram-0.16.2/src/logger.h --- scram-0.16.1/src/logger.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/logger.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,8 +26,7 @@ /// The timing facilities are inspired by /// the talk of Bryce Adelstein "Benchmarking C++ Code" at CppCon 2015. -#ifndef SCRAM_SRC_LOGGER_H_ -#define SCRAM_SRC_LOGGER_H_ +#pragma once #include @@ -150,5 +149,3 @@ }; } // namespace scram - -#endif // SCRAM_SRC_LOGGER_H_ diff -Nru scram-0.16.1/src/mocus.cc scram-0.16.2/src/mocus.cc --- scram-0.16.1/src/mocus.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/mocus.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -29,8 +29,7 @@ #include "logger.h" -namespace scram { -namespace core { +namespace scram::core { Mocus::Mocus(const Pdag* graph, const Settings& settings) : graph_(graph), kSettings_(settings) { @@ -106,5 +105,4 @@ return container; } -} // namespace core -} // namespace scram +} // namespace scram::core diff -Nru scram-0.16.1/src/mocus.h scram-0.16.2/src/mocus.h --- scram-0.16.1/src/mocus.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/mocus.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,8 +23,7 @@ /// That is, negations must be pushed down to leaves, basic events. /// The fault tree should not contain constants or house events. -#ifndef SCRAM_SRC_MOCUS_H_ -#define SCRAM_SRC_MOCUS_H_ +#pragma once #include #include @@ -35,8 +34,7 @@ #include "settings.h" #include "zbdd.h" -namespace scram { -namespace core { +namespace scram::core { /// This class analyzes normalized, preprocessed, and indexed fault trees /// to generate minimal cut sets with the MOCUS algorithm. @@ -79,7 +77,4 @@ std::unique_ptr zbdd_; ///< ZBDD as a result of analysis. }; -} // namespace core -} // namespace scram - -#endif // SCRAM_SRC_MOCUS_H_ +} // namespace scram::core diff -Nru scram-0.16.1/src/model.cc scram-0.16.2/src/model.cc --- scram-0.16.1/src/model.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/model.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,8 +24,7 @@ #include "ext/find_iterator.h" #include "ext/multi_index.h" -namespace scram { -namespace mef { +namespace scram::mef { const char Model::kDefaultName[] = "__unnamed-model__"; @@ -160,5 +159,4 @@ return ext::extract(it, &fault_trees_); } -} // namespace mef -} // namespace scram +} // namespace scram::mef diff -Nru scram-0.16.1/src/model.h scram-0.16.2/src/model.h --- scram-0.16.1/src/model.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/model.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,15 +18,12 @@ /// @file /// Representation for a model container for risk analysis. -#ifndef SCRAM_SRC_MODEL_H_ -#define SCRAM_SRC_MODEL_H_ +#pragma once #include #include #include -#include - #include "alignment.h" #include "ccf_group.h" #include "element.h" @@ -40,11 +37,10 @@ #include "parameter.h" #include "substitution.h" -namespace scram { -namespace mef { +namespace scram::mef { /// This class represents a risk analysis model. -class Model : public Element, private boost::noncopyable { +class Model : public Element { public: /// Only Model is allowed to have an optional name, /// while all other Elements require names. @@ -191,7 +187,4 @@ Context context_; ///< The context to be used by test-event expressions. }; -} // namespace mef -} // namespace scram - -#endif // SCRAM_SRC_MODEL_H_ +} // namespace scram::mef diff -Nru scram-0.16.1/src/parameter.cc scram-0.16.2/src/parameter.cc --- scram-0.16.1/src/parameter.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/parameter.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,8 +22,7 @@ #include "error.h" -namespace scram { -namespace mef { +namespace scram::mef { MissionTime::MissionTime(double time, Units unit) : unit_(unit), value_(time) { value(time); @@ -42,5 +41,4 @@ Expression::AddArg(expression); } -} // namespace mef -} // namespace scram +} // namespace scram::mef diff -Nru scram-0.16.1/src/parameter.h scram-0.16.2/src/parameter.h --- scram-0.16.1/src/parameter.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/parameter.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,7 @@ /// @file /// Parameter expressions that act like a shareable variable. -#ifndef SCRAM_SRC_PARAMETER_H_ -#define SCRAM_SRC_PARAMETER_H_ +#pragma once #include @@ -29,8 +28,7 @@ #include "element.h" #include "expression.h" -namespace scram { -namespace mef { +namespace scram::mef { /// Provides units for parameters. enum Units : std::uint8_t { @@ -117,7 +115,4 @@ using ParameterPtr = std::unique_ptr; ///< Convenience alias. -} // namespace mef -} // namespace scram - -#endif // SCRAM_SRC_PARAMETER_H_ +} // namespace scram::mef diff -Nru scram-0.16.1/src/pdag.cc scram-0.16.2/src/pdag.cc --- scram-0.16.1/src/pdag.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/pdag.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -38,8 +38,7 @@ #include "model.h" #include "substitution.h" -namespace scram { -namespace core { +namespace scram::core { void NodeParentManager::AddParent(const GatePtr& gate) { assert(!parents_.count(gate->index()) && "Adding an existing parent."); @@ -521,7 +520,7 @@ } formula_visitor{this, ccf, nodes}; for (const mef::Formula::EventArg& event_arg : formula.event_args()) { - boost::apply_visitor(formula_visitor, event_arg); + std::visit(formula_visitor, event_arg); } for (const mef::FormulaPtr& sub_form : formula.formula_args()) { @@ -553,7 +552,7 @@ GatherVariables(*event, ccf, nodes); } - if (auto* target = boost::get(&substitution.target())) + if (auto* target = std::get_if(&substitution.target())) GatherVariables(**target, ccf, nodes); } @@ -621,7 +620,7 @@ assert((type == kOr || type == kAnd) && "Unexpected gate type."); } for (const mef::Formula::EventArg& event_arg : formula.event_args()) { - boost::apply_visitor( + std::visit( [&](const auto* event) { this->AddArg(parent, *event, ccf, nodes); }, event_arg); } @@ -639,10 +638,10 @@ auto implication = std::make_shared(kOr, this); implication->AddArg(ConstructGate(substitution.hypothesis(), ccf, nodes), /*complement=*/true); - if (auto* target = boost::get(&substitution.target())) { + if (auto* target = std::get_if(&substitution.target())) { AddArg(implication, **target, ccf, nodes); } else { - assert(!*boost::get(&substitution.target()) && "Invalid delete term"); + assert(!*std::get_if(&substitution.target()) && "Not a delete term"); implication->type(kNull); } return implication; @@ -652,10 +651,10 @@ ProcessedNodes* nodes) noexcept { assert(!substitution.declarative() && "Only non-declarative substitutions."); int target = [&substitution, &nodes] { - if (auto* event = boost::get(&substitution.target())) + if (auto* event = std::get_if(&substitution.target())) return nodes->variables.find(*event)->second->index(); - assert(*boost::get(&substitution.target()) && "Invalid delete term"); + assert(*std::get_if(&substitution.target()) && "Invalid delete term"); return 0; }(); @@ -669,7 +668,7 @@ std::vector args; for (const mef::Formula::EventArg& arg : substitution.hypothesis().event_args()) { - auto* event = boost::get(&arg); + auto* event = std::get_if(&arg); assert(event); args.push_back(nodes->variables.find(*event)->second->index()); } @@ -679,7 +678,7 @@ case mef::kOr: { for (const mef::Formula::EventArg& arg : substitution.hypothesis().event_args()) { - auto* event = boost::get(&arg); + auto* event = std::get_if(&arg); assert(event); substitutions_.push_back( {{nodes->variables.find(*event)->second->index()}, source, target}); @@ -693,8 +692,8 @@ bool Pdag::IsTrivial() noexcept { assert(root_.use_count() == 1 && "Graph gate pointers outside of the graph!"); - /// @todo Enable the code by decouple the order assignment! - /* if (static_cast(this)->IsTrivial()) */ + /// @todo Enable the code by decoupling the order assignment! + /* if (std::as_const(*this).IsTrivial()) */ /* return true; */ if (root_->type() != kNull) return false; @@ -723,7 +722,7 @@ /// @todo Decouple the order assignment! root_->args().begin()->second->order(1); } - assert(static_cast(this)->IsTrivial()); + assert(std::as_const(*this).IsTrivial()); return true; } @@ -988,5 +987,4 @@ return os; } -} // namespace core -} // namespace scram +} // namespace scram::core diff -Nru scram-0.16.1/src/pdag.h scram-0.16.2/src/pdag.h --- scram-0.16.1/src/pdag.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/pdag.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,8 +27,7 @@ /// the Boolean terminology is preferred. /// For example, instead of "children", "arguments" are preferred. -#ifndef SCRAM_SRC_PDAG_H_ -#define SCRAM_SRC_PDAG_H_ +#pragma once #include #include @@ -36,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -48,18 +48,16 @@ #include "ext/index_map.h" #include "ext/linear_map.h" -namespace scram { - -namespace mef { // Declarations to decouple from the initialization code. +namespace scram::mef { // Declarations to decouple from the MEF initialization. class Model; // Provider of substitutions. class Substitution; class Gate; class BasicEvent; class HouseEvent; class Formula; -} // namespace mef +} // namespace scram::mef -namespace core { +namespace scram::core { class Gate; // An indexed gate parent of nodes. using GatePtr = std::shared_ptr; ///< Shared gates in the graph. @@ -373,7 +371,15 @@ /// /// @returns The map container of the gate arguments with the given type. template - const ArgMap& args(); + const ArgMap& args() { + if constexpr (std::is_same_v) { + return gate_args_; + + } else { + static_assert(std::is_same_v, "No container for const args"); + return variable_args_; + } + } /// Provides const access to gate arguments /// w/o exposing the shared pointers. @@ -748,18 +754,6 @@ ConstantPtr constant_; }; -/// @returns The Gate type arguments of a gate. -template <> -inline const Gate::ArgMap& Gate::args() { - return gate_args_; -} - -/// @returns The Variable type arguments of a gate. -template <> -inline const Gate::ArgMap& Gate::args() { - return variable_args_; -} - /// Specialization to handle Boolean constants in arguments. /// @copydoc Gate::AddArg template <> @@ -989,9 +983,14 @@ /// @tparam Mark The kind of the mark. template void Clear() noexcept { - Clear(); - Clear(root_); - Clear(); + if constexpr (Mark == kGateMark) { + Clear(root_); + + } else { + Clear(); + Clear(root_); + Clear(); + } } /// Determines the proper "clear" state for the graph node mark, @@ -1151,50 +1150,36 @@ } /// @} -/// Specializations for various node mark clearance operations. -/// -/// @param[in,out] gate The starting gate. -/// @{ -template <> -inline void Pdag::Clear(const GatePtr& gate) noexcept { - TraverseGates(gate, [](auto&&) {}); -} -template <> -inline void Pdag::Clear(const GatePtr& gate) noexcept { - TraverseNodes(gate, [](auto&& node) { - if (node->Visited()) - node->ClearVisits(); - }); -} -template <> -inline void Pdag::Clear(const GatePtr& gate) noexcept { - TraverseNodes(gate, [](auto&& node) { node->opti_value(0); }); -} -template <> -inline void Pdag::Clear(const GatePtr& gate) noexcept { - TraverseNodes(gate, [](auto&& node) { node->ResetCount(); }); -} -template <> -inline void Pdag::Clear(const GatePtr& gate) noexcept { - TraverseGates(gate, [](const GatePtr& arg) { arg->descendant(0); }); -} -template <> -inline void Pdag::Clear(const GatePtr& gate) noexcept { - TraverseGates(gate, [](const GatePtr& arg) { arg->ancestor(0); }); -} -template <> -inline void Pdag::Clear(const GatePtr& gate) noexcept { - TraverseNodes(gate, [](auto&& node) { - if (node->order()) - node->order(0); - }); -} -/// @} - -/// Specialization to clear the generic mark for the whole graph. -template <> -inline void Pdag::Clear() noexcept { - Clear(root_); +template +void Pdag::Clear(const GatePtr& gate) noexcept { + if constexpr (Mark == kGateMark) { + TraverseGates(gate, [](auto&&) {}); + + } else if constexpr (Mark == kDescendant) { + TraverseGates(gate, [](const GatePtr& arg) { arg->descendant(0); }); + + } else if constexpr (Mark == kAncestor) { + TraverseGates(gate, [](const GatePtr& arg) { arg->ancestor(0); }); + + } else { + TraverseNodes(gate, [](auto&& node) { + if constexpr (Mark == kVisit) { + if (node->Visited()) + node->ClearVisits(); + + } else if constexpr (Mark == kOrder) { + if (node->order()) + node->order(0); + + } else if constexpr (Mark == kOptiValue) { + node->opti_value(0); + + } else { + static_assert(Mark == kCount, "The node mark is not covered."); + node->ResetCount(); + } + }); + } } /// Prints PDAG nodes in the Aralia format. @@ -1216,7 +1201,4 @@ /// Visit information may get changed. std::ostream& operator<<(std::ostream& os, Pdag* graph); -} // namespace core -} // namespace scram - -#endif // SCRAM_SRC_PDAG_H_ +} // namespace scram::core diff -Nru scram-0.16.1/src/preprocessor.cc scram-0.16.2/src/preprocessor.cc --- scram-0.16.1/src/preprocessor.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/preprocessor.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -89,8 +89,7 @@ #include "ext/find_iterator.h" #include "logger.h" -namespace scram { -namespace core { +namespace scram::core { namespace pdag { @@ -2409,5 +2408,4 @@ var->order(shift + var->order()); } -} // namespace core -} // namespace scram +} // namespace scram::core diff -Nru scram-0.16.1/src/preprocessor.h scram-0.16.2/src/preprocessor.h --- scram-0.16.1/src/preprocessor.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/preprocessor.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,8 +19,7 @@ /// A collection of PDAG transformation/preprocessing algorithms /// that simplify fault trees for analysis. -#ifndef SCRAM_SRC_PREPROCESSOR_H_ -#define SCRAM_SRC_PREPROCESSOR_H_ +#pragma once #include #include @@ -33,14 +32,10 @@ #include "pdag.h" -namespace scram { -namespace core { +namespace scram::core { namespace pdag { -/// The terminal case for graph transformations. -inline void Transform(Pdag* /*graph*/) {} - /// Applies graph transformations consecutively. /// /// @param[in,out] graph The graph to be transformed. @@ -50,8 +45,11 @@ void Transform(Pdag* graph, T&& unary_op, Ts&&... unary_ops) noexcept { if (graph->IsTrivial()) return; + unary_op(graph); - Transform(graph, std::forward(unary_ops)...); + + if constexpr (sizeof...(unary_ops)) + Transform(graph, std::forward(unary_ops)...); } /// Determines the order of traversal for gate arguments. @@ -1065,7 +1063,4 @@ void InvertOrder() noexcept; }; -} // namespace core -} // namespace scram - -#endif // SCRAM_SRC_PREPROCESSOR_H_ +} // namespace scram::core diff -Nru scram-0.16.1/src/probability_analysis.cc scram-0.16.2/src/probability_analysis.cc --- scram-0.16.1/src/probability_analysis.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/probability_analysis.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -29,8 +29,7 @@ #include "settings.h" #include "zbdd.h" -namespace scram { -namespace core { +namespace scram::core { ProbabilityAnalysis::ProbabilityAnalysis(const FaultTreeAnalysis* fta, mef::MissionTime* mission_time) @@ -291,5 +290,4 @@ return ite.p(); } -} // namespace core -} // namespace scram +} // namespace scram::core diff -Nru scram-0.16.1/src/probability_analysis.h scram-0.16.2/src/probability_analysis.h --- scram-0.16.1/src/probability_analysis.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/probability_analysis.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,7 @@ /// @file /// Contains functionality to do numerical analysis of probabilities. -#ifndef SCRAM_SRC_PROBABILITY_ANALYSIS_H_ -#define SCRAM_SRC_PROBABILITY_ANALYSIS_H_ +#pragma once #include #include @@ -29,13 +28,11 @@ #include "fault_tree_analysis.h" #include "pdag.h" -namespace scram { - -namespace mef { +namespace scram::mef { class MissionTime; -} +} // namespace scram::mef -namespace core { +namespace scram::core { /// Safety Integrity Level metrics. /// @@ -333,7 +330,4 @@ bool owner_; ///< Indication that pointers are handles. }; -} // namespace core -} // namespace scram - -#endif // SCRAM_SRC_PROBABILITY_ANALYSIS_H_ +} // namespace scram::core diff -Nru scram-0.16.1/src/random.cc scram-0.16.2/src/random.cc --- scram-0.16.1/src/random.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/random.cc 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2014-2015, 2017 Olzhas Rakhimov - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/// @file -/// Implementation file of various RNGs. - -#include "random.h" - -namespace scram { - -std::mt19937 Random::rng_; - -} // namespace scram diff -Nru scram-0.16.1/src/random.h scram-0.16.2/src/random.h --- scram-0.16.1/src/random.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/random.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,255 +0,0 @@ -/* - * Copyright (C) 2014-2017 Olzhas Rakhimov - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/// @file -/// Contains helpers for randomness simulations. - -#ifndef SCRAM_SRC_RANDOM_H_ -#define SCRAM_SRC_RANDOM_H_ - -#include -#include - -#include - -#include -#include - -namespace scram { - -/// This class contains generators for various random distributions. -/// The values passed to the member functions are asserted -/// to be in the correct form. -/// In other words, the user should make sure -/// that the passed parameters are valid. -/// For example, standard deviation cannot be negative. -/// -/// This facility wraps the engine and distributions. -/// It provides convenience and reproducibility for the whole analysis. -class Random { - public: - /// Sets the seed of the underlying random number generator. - /// - /// @param[in] seed The seed for RNGs. - static void seed(int seed) noexcept { - Random::rng_.seed(static_cast(seed)); - } - - /// RNG from a uniform distribution. - /// - /// @param[in] lower Lower bound. - /// @param[in] upper Upper bound. - /// - /// @returns A sampled value. - static double UniformRealGenerator(double lower, double upper) noexcept { - assert(lower < upper); - return std::uniform_real_distribution<>(lower, upper)(rng_); - } - - /// RNG from a triangular distribution. - /// - /// @param[in] lower Lower bound. - /// @param[in] mode The peak of the distribution. - /// @param[in] upper Upper bound. - /// - /// @returns A sampled value. - static double TriangularGenerator(double lower, double mode, - double upper) noexcept { - assert(lower < mode); - assert(mode < upper); - return boost::random::triangle_distribution<>(lower, mode, upper)(rng_); - } - - /// RNG from a piecewise linear distribution. - /// - /// @tparam IteratorB Input iterator of interval boundaries returning double. - /// @tparam IteratorW Input iterator of weights returning double. - /// - /// @param[in] first_b The begin of the interval boundaries. - /// @param[in] last_b The sentinel end of the interval boundaries. - /// @param[in] first_w The begin of the interval weights. - /// - /// @returns A sampled value. - /// - /// @pre Interval points for the distribution must be strictly increasing. - /// - /// @pre The number of weights must be equal to - /// the number of boundaries. - /// Extra weights are ignored. - template - static double PiecewiseLinearGenerator(IteratorB first_b, IteratorB last_b, - IteratorW first_w) noexcept { - return std::piecewise_linear_distribution<>(first_b, last_b, first_w)(rng_); - } - - /// RNG from a histogram distribution. - /// - /// @tparam IteratorB Input iterator of interval boundaries returning double. - /// @tparam IteratorW Input iterator of weights returning double. - /// - /// @param[in] first_b The begin of the interval boundaries. - /// @param[in] last_b The sentinel end of the interval boundaries. - /// @param[in] first_w The begin of the interval weights. - /// - /// @returns A sampled value from the interval. - /// - /// @pre Interval points for the distribution must be strictly increasing. - /// - /// @pre The number of weights must be equal to - /// the number of intervals (boundaries - 1). - /// Extra weights are ignored. - template - static double HistogramGenerator(IteratorB first_b, IteratorB last_b, - IteratorW first_w) noexcept { - std::piecewise_constant_distribution<> dist(first_b, last_b, first_w); - return dist(rng_); - } - - /// RNG from a discrete distribution. - /// - /// @tparam Iterator Input iterator of weights returning double. - /// - /// @param[in] first1 The begin of the interval weights. - /// @param[in] last1 The sentinel end of the interval weights. - /// - /// @returns Integer in the range [0, n). - template - static int DiscreteGenerator(Iterator first1, Iterator last1) noexcept { - return std::discrete_distribution<>(first1, last1)(rng_); - } - - /// RNG from a Binomial distribution. - /// - /// @param[in] n Number of trials. - /// @param[in] p Probability of success. - /// - /// @returns The number of successes. - static int BinomialGenerator(int n, double p) noexcept { - return std::binomial_distribution<>(n, p)(rng_); - } - - /// RNG from a normal distribution. - /// - /// @param[in] mean The mean of the distribution. - /// @param[in] sigma The standard deviation of the distribution. - /// - /// @returns A sampled value. - static double NormalGenerator(double mean, double sigma) noexcept { - assert(sigma >= 0); - return std::normal_distribution<>(mean, sigma)(rng_); - } - - /// RNG from a lognormal distribution. - /// - /// @param[in] m The m location parameter of the distribution. - /// @param[in] s The s scale factor of the distribution. - /// - /// @returns A sampled value. - static double LognormalGenerator(double m, double s) noexcept { - assert(s >= 0); - return std::lognormal_distribution<>(m, s)(rng_); - } - - /// RNG from a Gamma distribution. - /// - /// @param[in] k Shape parameter of Gamma distribution. - /// @param[in] theta Scale parameter of Gamma distribution. - /// - /// @returns A sampled value. - /// - /// @note The rate parameter is 1/theta, - /// so for alpha/beta system, - /// pass 1/beta as a second parameter for this generator. - static double GammaGenerator(double k, double theta) noexcept { - assert(k > 0); - assert(theta > 0); - return std::gamma_distribution<>(k)(rng_) * theta; - } - - /// RNG from a Beta distribution. - /// - /// @param[in] alpha Alpha shape parameter of Beta distribution. - /// @param[in] beta Beta shape parameter of Beta distribution. - /// - /// @returns A sampled value. - static double BetaGenerator(double alpha, double beta) noexcept { - assert(alpha > 0); - assert(beta > 0); - return boost::random::beta_distribution<>(alpha, beta)(rng_); - } - - /// RNG from a Weibull distribution. - /// - /// @param[in] k Shape parameter of Weibull distribution. - /// @param[in] lambda Scale parameter of Weibull distribution. - /// - /// @returns A sampled value. - static double WeibullGenerator(double k, double lambda) noexcept { - assert(k > 0); - assert(lambda > 0); - return std::weibull_distribution<>(k, lambda)(rng_); - } - - /// RNG from an Exponential distribution. - /// - /// @param[in] lambda Rate parameter of Exponential distribution. - /// - /// @returns A sampled value. - static double ExponentialGenerator(double lambda) noexcept { - assert(lambda > 0); - return std::exponential_distribution<>(lambda)(rng_); - } - - /// RNG from a Poisson distribution. - /// - /// @param[in] mean The mean value for Poisson distribution. - /// - /// @returns A sampled value. - static int PoissonGenerator(int mean) noexcept { - assert(mean > 0); - return std::poisson_distribution<>(mean)(rng_); - } - - /// RNG from a log-uniform distribution. - /// - /// @param[in] lower Lower bound. - /// @param[in] upper Upper bound. - /// - /// @returns A sampled value. - static double LogUniformGenerator(double lower, double upper) noexcept { - return std::exp(UniformRealGenerator(lower, upper)); - } - - /// RNG from a log-triangular distribution. - /// - /// @param[in] lower Lower bound. - /// @param[in] mode The peak of the distribution. - /// @param[in] upper Upper bound. - /// - /// @returns A sampled value. - static double LogTriangularGenerator(double lower, double mode, - double upper) noexcept { - return std::exp(TriangularGenerator(lower, mode, upper)); - } - - private: - static std::mt19937 rng_; ///< The random number generator. -}; - -} // namespace scram - -#endif // SCRAM_SRC_RANDOM_H_ diff -Nru scram-0.16.1/src/reporter.cc scram-0.16.2/src/reporter.cc --- scram-0.16.1/src/reporter.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/reporter.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,12 +20,13 @@ #include "reporter.h" +#include + #include #include #include #include -#include #include #include #include @@ -57,7 +58,7 @@ } xml::StreamElement* report_; } extractor{report}; - boost::apply_visitor(extractor, id.target); + std::visit(extractor, id.target); if (id.context) { report->SetAttribute("alignment", id.context->alignment.name()); @@ -271,9 +272,14 @@ ? version::describe() : version::core()) .SetAttribute("contacts", "https://scram-pra.org"); - namespace pt = boost::posix_time; - information->AddChild("time").AddText( - pt::to_iso_extended_string(pt::second_clock::universal_time())); + + std::time_t current_time = std::time(nullptr); + char iso_extended[20] = {}; + auto ret = std::strftime(iso_extended, sizeof(iso_extended), + "%Y-%m-%dT%H:%M:%S", std::gmtime(¤t_time)); + assert(ret && "Time formatting failure. Who is running this in year 10000?"); + if (ret) // The user can set the wall-clock year beyond 10k. + information->AddChild("time").AddText(iso_extended); } void Reporter::ReportModelFeatures(const mef::Model& model, diff -Nru scram-0.16.1/src/reporter.h scram-0.16.2/src/reporter.h --- scram-0.16.1/src/reporter.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/reporter.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,7 @@ /// @file /// Reporter of results. -#ifndef SCRAM_SRC_REPORTER_H_ -#define SCRAM_SRC_REPORTER_H_ +#pragma once #include @@ -194,5 +193,3 @@ }; } // namespace scram - -#endif // SCRAM_SRC_REPORTER_H_ diff -Nru scram-0.16.1/src/risk_analysis.cc scram-0.16.2/src/risk_analysis.cc --- scram-0.16.1/src/risk_analysis.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/risk_analysis.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,14 +21,14 @@ #include "risk_analysis.h" #include "bdd.h" +#include "expression/random_deviate.h" +#include "ext/scope_guard.h" #include "fault_tree.h" #include "logger.h" #include "mocus.h" -#include "random.h" #include "zbdd.h" -namespace scram { -namespace core { +namespace scram::core { RiskAnalysis::RiskAnalysis(mef::Model* model, const Settings& settings) : Analysis(settings), model_(model) {} @@ -38,7 +38,7 @@ // Set the seed for the pseudo-random number generator if given explicitly. // Otherwise it defaults to the implementation dependent value. if (Analysis::settings().seed() >= 0) - Random::seed(Analysis::settings().seed()); + mef::RandomDeviate::seed(Analysis::settings().seed()); if (model_->alignments().empty()) { RunAnalysis(); @@ -50,22 +50,17 @@ } } -void RiskAnalysis::RunAnalysis(boost::optional context) noexcept { +void RiskAnalysis::RunAnalysis(std::optional context) noexcept { + std::vector> house_events; /// Restores the model after application of the context. - struct Restorator { - ~Restorator() { - mission_time.first->value(mission_time.second); - settings.mission_time(mission_time.second); - - for (const std::pair& entry : house_events) - entry.first->state(entry.second); - } - - Settings& settings; - std::pair mission_time; - std::vector> house_events; - } restorator{Analysis::settings(), - {&model_->mission_time(), model_->mission_time().value()}}; + ext::scope_guard restorator( + [&house_events, this, init_time = model_->mission_time().value() ] { + model_->mission_time().value(init_time); + Analysis::settings().mission_time(init_time); + + for (const std::pair& entry : house_events) + entry.first->state(entry.second); + }); if (context) { double mission_time = @@ -79,7 +74,7 @@ assert(it != model_->house_events().end() && "Invalid instruction."); mef::HouseEvent* house_event = it->get(); if (house_event->state() != instruction->state()) { - restorator.house_events.emplace_back(house_event, house_event->state()); + house_events.emplace_back(house_event, house_event->state()); house_event->state(instruction->state()); } } @@ -176,5 +171,4 @@ result->probability_analysis = std::move(pa); } -} // namespace core -} // namespace scram +} // namespace scram::core diff -Nru scram-0.16.1/src/risk_analysis.h scram-0.16.2/src/risk_analysis.h --- scram-0.16.1/src/risk_analysis.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/risk_analysis.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,16 +18,14 @@ /// @file /// Contains the main system for performing analysis. -#ifndef SCRAM_SRC_RISK_ANALYSIS_H_ -#define SCRAM_SRC_RISK_ANALYSIS_H_ +#pragma once #include +#include #include +#include #include -#include -#include - #include "alignment.h" #include "analysis.h" #include "event.h" @@ -39,8 +37,7 @@ #include "settings.h" #include "uncertainty_analysis.h" -namespace scram { -namespace core { +namespace scram::core { /// Main system that performs analyses. class RiskAnalysis : public Analysis { @@ -55,10 +52,10 @@ struct Result { /// The analysis target type as a unique identifier. struct Id { - boost::variant> + std::variant> target; ///< The main input to the analysis. - boost::optional context; ///< Optional analysis context. + std::optional context; ///< Optional analysis context. }; const Id id; ///< The main analysis input or target. @@ -77,7 +74,7 @@ /// @todo Replace with query (group_by). struct EtaResult { const mef::InitiatingEvent& initiating_event; ///< Unique event per tree. - boost::optional context; ///< The alignment context. + std::optional context; ///< The alignment context. /// The holder of the analysis. std::unique_ptr event_tree_analysis; }; @@ -121,7 +118,7 @@ /// @pre The model is in pristine. /// /// @post The model is restored to the original state. - void RunAnalysis(boost::optional context = {}) noexcept; + void RunAnalysis(std::optional context = {}) noexcept; /// Runs all possible analysis on a given target. /// Analysis types are deduced from the settings. @@ -158,7 +155,4 @@ std::vector event_tree_results_; ///< Grouping of sequences. }; -} // namespace core -} // namespace scram - -#endif // SCRAM_SRC_RISK_ANALYSIS_H_ +} // namespace scram::core diff -Nru scram-0.16.1/src/scram.cc scram-0.16.2/src/scram.cc --- scram-0.16.1/src/scram.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/scram.cc 2018-01-12 11:42:47.000000000 +0000 @@ -37,6 +37,7 @@ #include "config.h" #include "error.h" +#include "ext/scope_guard.h" #include "initializer.h" #include "logger.h" #include "reporter.h" @@ -305,11 +306,7 @@ void LogXmlError(void* /*ctx*/, const char* msg, ...) noexcept { std::va_list args; va_start(args, msg); - - struct VAListCloser { - ~VAListCloser() { va_end(args_); } - std::va_list& args_; - } args_closer{args}; + SCOPE_EXIT([&args] { va_end(args); }); std::va_list args_for_nchar; // Only used to determine the string length. va_copy(args_for_nchar, args); @@ -336,11 +333,8 @@ /// @returns 1 for errored state. int main(int argc, char* argv[]) { LIBXML_TEST_VERSION - - struct XmlInit { - XmlInit() { xmlInitParser(); } - ~XmlInit() { xmlCleanupParser(); } - } xml_memory_guard; + xmlInitParser(); + SCOPE_EXIT(&xmlCleanupParser); xmlGenericErrorFunc xml_error_printer = LogXmlError; initGenericErrorDefaultFunc(&xml_error_printer); diff -Nru scram-0.16.1/src/serialization.cc scram-0.16.2/src/serialization.cc --- scram-0.16.1/src/serialization.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/serialization.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,8 +33,7 @@ #include "fault_tree.h" #include "xml_stream.h" -namespace scram { -namespace mef { +namespace scram::mef { void Serialize(const Model& model, const std::string& file) { std::unique_ptr fp( @@ -95,7 +94,7 @@ }; if (formula.type() == kNull) { assert(formula.event_args().size() == 1); - boost::apply_visitor(ArgStreamer{parent}, formula.event_args().front()); + std::visit(ArgStreamer{parent}, formula.event_args().front()); } else { xml::StreamElement type_element = [&formula, &parent] { switch (formula.type()) { @@ -122,7 +121,7 @@ } }(); for (const Formula::EventArg& arg : formula.event_args()) - boost::apply_visitor(ArgStreamer{&type_element}, arg); + std::visit(ArgStreamer{&type_element}, arg); } } @@ -203,5 +202,4 @@ Serialize(*house_event, &model_data); } -} // namespace mef -} // namespace scram +} // namespace scram::mef diff -Nru scram-0.16.1/src/serialization.h scram-0.16.2/src/serialization.h --- scram-0.16.1/src/serialization.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/serialization.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,8 +21,7 @@ /// @note This facility currently caters only models representable in the GUI. /// @todo Implement serialization for all MEF constructs. -#ifndef SCRAM_SRC_SERIALIZATION_H_ -#define SCRAM_SRC_SERIALIZATION_H_ +#pragma once #include @@ -30,8 +29,7 @@ #include "model.h" -namespace scram { -namespace mef { +namespace scram::mef { /// Serializes the model and its data into stream as XML. /// @@ -50,7 +48,4 @@ /// or the write operation has failed. void Serialize(const Model& model, const std::string& file); -} // namespace mef -} // namespace scram - -#endif // SCRAM_SRC_SERIALIZATION_H_ +} // namespace scram::mef diff -Nru scram-0.16.1/src/settings.cc scram-0.16.2/src/settings.cc --- scram-0.16.1/src/settings.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/settings.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,12 +20,13 @@ #include "settings.h" +#include + #include #include "error.h" -namespace scram { -namespace core { +namespace scram::core { Settings& Settings::algorithm(Algorithm value) noexcept { algorithm_ = value; @@ -42,11 +43,11 @@ return *this; } -Settings& Settings::algorithm(boost::string_ref value) { +Settings& Settings::algorithm(std::string_view value) { auto it = boost::find(kAlgorithmToString, value); if (it == std::end(kAlgorithmToString)) SCRAM_THROW(SettingsError("The qualitative analysis algorithm '" + - value.to_string() + "' is not recognized.")); + std::string(value) + "' is not recognized.")); return algorithm( static_cast(std::distance(kAlgorithmToString, it))); } @@ -59,11 +60,11 @@ return *this; } -Settings& Settings::approximation(boost::string_ref value) { +Settings& Settings::approximation(std::string_view value) { auto it = boost::find(kApproximationToString, value); if (it == std::end(kApproximationToString)) SCRAM_THROW(SettingsError("The probability approximation '" + - value.to_string() + "'is not recognized.")); + std::string(value) + "'is not recognized.")); return approximation( static_cast(std::distance(kApproximationToString, it))); } @@ -158,5 +159,4 @@ return *this; } -} // namespace core -} // namespace scram +} // namespace scram::core diff -Nru scram-0.16.1/src/settings.h scram-0.16.2/src/settings.h --- scram-0.16.1/src/settings.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/settings.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,15 +18,13 @@ /// @file /// Builder for settings. -#ifndef SCRAM_SRC_SETTINGS_H_ -#define SCRAM_SRC_SETTINGS_H_ +#pragma once #include -#include +#include -namespace scram { -namespace core { +namespace scram::core { /// Qualitative analysis algorithms. enum class Algorithm : std::uint8_t { kBdd = 0, kZbdd, kMocus }; @@ -73,7 +71,7 @@ /// @throws SettingsError The algorithm is not recognized. /// /// @returns Reference to this object. - Settings& algorithm(boost::string_ref value); + Settings& algorithm(std::string_view value); /// @returns The quantitative analysis approximation. Approximation approximation() const { return approximation_; } @@ -88,7 +86,7 @@ /// or inappropriate for analysis. /// @{ Settings& approximation(Approximation value); - Settings& approximation(boost::string_ref value); + Settings& approximation(std::string_view value); /// @} /// @returns true if prime implicants are to be calculated @@ -315,7 +313,4 @@ double cut_off_ = 1e-8; ///< The cut-off probability for products. }; -} // namespace core -} // namespace scram - -#endif // SCRAM_SRC_SETTINGS_H_ +} // namespace scram::core diff -Nru scram-0.16.1/src/substitution.cc scram-0.16.2/src/substitution.cc --- scram-0.16.1/src/substitution.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/substitution.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,8 +23,7 @@ #include "error.h" #include "ext/algorithm.h" -namespace scram { -namespace mef { +namespace scram::mef { void Substitution::Add(BasicEvent* source_event) { if (ext::any_of(source_, [source_event](BasicEvent* arg) { @@ -39,7 +38,7 @@ void Substitution::Validate() const { assert(hypothesis_ && "Missing substitution hypothesis."); if (ext::any_of(hypothesis_->event_args(), [](const Formula::EventArg& arg) { - return !boost::get(&arg); + return !std::holds_alternative(arg); })) { SCRAM_THROW(ValidityError( "Substitution hypothesis must be built over basic events only.")); @@ -58,7 +57,7 @@ default: SCRAM_THROW(ValidityError("Substitution hypotheses must be coherent.")); } - const bool* constant = boost::get(&target_); + const bool* constant = std::get_if(&target_); if (constant && *constant) SCRAM_THROW(ValidityError("Substitution has no effect.")); } else { // Non-declarative. @@ -72,17 +71,17 @@ ValidityError("Non-declarative substitution hypotheses only allow " "AND/OR/NULL connectives.")); } - const bool* constant = boost::get(&target_); + const bool* constant = std::get_if(&target_); if (constant && !*constant) SCRAM_THROW(ValidityError("Substitution source set is irrelevant.")); } } -boost::optional Substitution::type() const { +std::optional Substitution::type() const { auto in_hypothesis = [this](const BasicEvent* source_arg) { return ext::any_of(hypothesis_->event_args(), [source_arg](const Formula::EventArg& arg) { - return boost::get(arg) == source_arg; + return std::get(arg) == source_arg; }); }; @@ -98,17 +97,17 @@ }; if (source_.empty()) { - if (const bool* constant = boost::get(&target_)) { + if (const bool* constant = std::get_if(&target_)) { assert(!*constant && "Substitution has no effect."); if (is_mutually_exclusive(*hypothesis_)) return kDeleteTerms; - } else if (boost::get(&target_)) { + } else if (std::holds_alternative(target_)) { if (hypothesis_->type() == kAnd) return kRecoveryRule; } return {}; } - if (!boost::get(&target_)) + if (!std::holds_alternative(target_)) return {}; if (hypothesis_->type() != kAnd && hypothesis_->type() != kNull) return {}; @@ -123,5 +122,4 @@ return {}; } -} // namespace mef -} // namespace scram +} // namespace scram::mef diff -Nru scram-0.16.1/src/substitution.h scram-0.16.2/src/substitution.h --- scram-0.16.1/src/substitution.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/substitution.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,27 +18,23 @@ /// @file /// The MEF Substitution constructs. -#ifndef SCRAM_SRC_SUBSTITUTION_H_ -#define SCRAM_SRC_SUBSTITUTION_H_ +#pragma once #include +#include +#include #include -#include -#include -#include - #include "element.h" #include "event.h" -namespace scram { -namespace mef { +namespace scram::mef { /// The general representation for /// Delete Terms, Recovery Rules, and Exchange Events. -class Substitution : public Element, private boost::noncopyable { +class Substitution : public Element { public: - using Target = boost::variant; ///< The target type. + using Target = std::variant; ///< The target type. /// The "traditional" substitution types. enum Type { kDeleteTerms, kRecoveryRule, kExchangeEvent }; @@ -97,7 +93,7 @@ /// @returns The equivalent "traditional" substitution type if any. /// /// @pre The hypothesis, target, and source are all defined and valid. - boost::optional type() const; + std::optional type() const; private: FormulaPtr hypothesis_; ///< The formula to be satisfied. @@ -111,7 +107,4 @@ const char* const kSubstitutionTypeToString[] = { "delete-terms", "recovery-rule", "exchange-event"}; -} // namespace mef -} // namespace scram - -#endif // SCRAM_SRC_SUBSTITUTION_H_ +} // namespace scram::mef diff -Nru scram-0.16.1/src/uncertainty_analysis.cc scram-0.16.2/src/uncertainty_analysis.cc --- scram-0.16.1/src/uncertainty_analysis.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/uncertainty_analysis.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,8 +33,7 @@ #include "expression.h" #include "logger.h" -namespace scram { -namespace core { +namespace scram::core { UncertaintyAnalysis::UncertaintyAnalysis( const ProbabilityAnalysis* prob_analysis) @@ -121,5 +120,4 @@ } } -} // namespace core -} // namespace scram +} // namespace scram::core diff -Nru scram-0.16.1/src/uncertainty_analysis.h scram-0.16.2/src/uncertainty_analysis.h --- scram-0.16.1/src/uncertainty_analysis.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/uncertainty_analysis.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,8 +19,7 @@ /// Provides functionality for uncertainty analysis /// with Monte Carlo method. -#ifndef SCRAM_SRC_UNCERTAINTY_ANALYSIS_H_ -#define SCRAM_SRC_UNCERTAINTY_ANALYSIS_H_ +#pragma once #include #include @@ -29,13 +28,11 @@ #include "probability_analysis.h" #include "settings.h" -namespace scram { - -namespace mef { // Decouple from the implementation dependence. +namespace scram::mef { // Decouple from the implementation dependence. class Expression; -} // namespace mef +} // namespace scram::mef -namespace core { +namespace scram::core { /// Uncertainty analysis and statistics /// for top event or gate probabilities @@ -159,7 +156,4 @@ return samples; } -} // namespace core -} // namespace scram - -#endif // SCRAM_SRC_UNCERTAINTY_ANALYSIS_H_ +} // namespace scram::core diff -Nru scram-0.16.1/src/version.cc.in scram-0.16.2/src/version.cc.in --- scram-0.16.1/src/version.cc.in 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/version.cc.in 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,8 +27,7 @@ #include -namespace scram { -namespace version { +namespace scram::version { const char* describe() { return "@core_version@"; } @@ -44,5 +43,4 @@ const char* libxml() { return LIBXML_DOTTED_VERSION; } -} // namespace version -} // namespace scram +} // namespace scram::version diff -Nru scram-0.16.1/src/version.h scram-0.16.2/src/version.h --- scram-0.16.1/src/version.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/version.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,11 +19,9 @@ /// Set of functions with version information /// of the core and dependencies. -#ifndef SCRAM_SRC_VERSION_H_ -#define SCRAM_SRC_VERSION_H_ +#pragma once -namespace scram { -namespace version { +namespace scram::version { /// @returns Git generated tag recent version. const char* describe(); @@ -40,7 +38,4 @@ /// @returns The version of the XML C library. const char* libxml(); -} // namespace version -} // namespace scram - -#endif // SCRAM_SRC_VERSION_H_ +} // namespace scram::version diff -Nru scram-0.16.1/src/xml.cc scram-0.16.2/src/xml.cc --- scram-0.16.1/src/xml.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/xml.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,8 +22,7 @@ #include -namespace scram { -namespace xml { +namespace scram::xml { Document::Document(const std::string& file_path, Validator* validator) : doc_(nullptr, &xmlFreeDoc) { @@ -64,5 +63,4 @@ SCRAM_THROW(detail::GetError()); } -} // namespace xml -} // namespace scram +} // namespace scram::xml diff -Nru scram-0.16.1/src/xml.h scram-0.16.2/src/xml.h --- scram-0.16.1/src/xml.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/xml.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -29,8 +29,7 @@ /// @warning Complex XML features are not handled or expected, /// for example, DTD, namespaces, entries. -#ifndef SCRAM_SRC_XML_H_ -#define SCRAM_SRC_XML_H_ +#pragma once #include #include @@ -39,7 +38,9 @@ #include #include #include +#include #include +#include #include #include @@ -47,9 +48,7 @@ #include #include #include -#include #include -#include #include #include @@ -57,10 +56,7 @@ #include "error.h" -namespace scram { -namespace xml { - -using string_view = boost::string_ref; ///< Non-owning, immutable string view. +namespace scram::xml { namespace detail { // Internal XML helper functions. @@ -74,42 +70,42 @@ /// /// @throws ValidityError Casting is unsuccessful. template -std::enable_if_t::value, T> -CastValue(const xml::string_view& value); +std::enable_if_t, T> +CastValue(const std::string_view& value); /// Specialization for integer values. template <> -inline int CastValue(const xml::string_view& value) { +inline int CastValue(const std::string_view& value) { char* end_char = nullptr; std::int64_t ret = std::strtoll(value.data(), &end_char, 10); int len = end_char - value.data(); if (len != value.size() || ret > std::numeric_limits::max() || ret < std::numeric_limits::min()) - SCRAM_THROW(ValidityError("Failed to interpret '" + value.to_string() + + SCRAM_THROW(ValidityError("Failed to interpret '" + std::string(value) + "' to 'int'.")); return ret; } /// Specialization for floating point numbers. template <> -inline double CastValue(const xml::string_view& value) { +inline double CastValue(const std::string_view& value) { char* end_char = nullptr; double ret = std::strtod(value.data(), &end_char); int len = end_char - value.data(); if (len != value.size() || ret == HUGE_VAL || ret == -HUGE_VAL) - SCRAM_THROW(ValidityError("Failed to interpret '" + value.to_string() + + SCRAM_THROW(ValidityError("Failed to interpret '" + std::string(value) + "' to 'double'.")); return ret; } /// Specialization for Boolean values. template <> -inline bool CastValue(const xml::string_view& value) { +inline bool CastValue(const std::string_view& value) { if (value == "true" || value == "1") return true; if (value == "false" || value == "0") return false; - SCRAM_THROW(ValidityError("Failed to interpret '" + value.to_string() + + SCRAM_THROW(ValidityError("Failed to interpret '" + std::string(value) + "' to 'bool'.")); } @@ -142,15 +138,15 @@ /// @returns View to the trimmed substring. /// /// @pre The string is normalized by the XML parser. -inline xml::string_view trim(const xml::string_view& text) noexcept { +inline std::string_view trim(const std::string_view& text) noexcept { auto pos_first = text.find_first_not_of(' '); - if (pos_first == xml::string_view::npos) + if (pos_first == std::string_view::npos) return {}; auto pos_last = text.find_last_not_of(' '); auto len = pos_last - pos_first + 1; - return xml::string_view(text.data() + pos_first, len); + return std::string_view(text.data() + pos_first, len); } /// Gets the last XML error converted from the library error codes. @@ -263,9 +259,7 @@ /// @returns The URI of the file containing the element. /// /// @pre The document has been loaded from a file. - xml::string_view filename() const { - return detail::from_utf8(element_->doc->URL); - } + const char* filename() const { return detail::from_utf8(element_->doc->URL); } /// @returns The line number of the element. int line() const { return XML_GET_LINE(to_node()); } @@ -273,7 +267,7 @@ /// @returns The name of the XML element. /// /// @pre The element has a name. - xml::string_view name() const { return detail::from_utf8(element_->name); } + std::string_view name() const { return detail::from_utf8(element_->name); } /// Retrieves the XML element's attribute values. /// @@ -284,7 +278,7 @@ /// /// @pre XML attributes never contain empty strings. /// @pre XML attribute values are simple texts w/o DTD processing. - xml::string_view attribute(const char* name) const { + std::string_view attribute(const char* name) const { const xmlAttr* property = xmlHasProp(to_node(), detail::to_utf8(name)); if (!property) return {}; @@ -309,7 +303,7 @@ /// @returns The XML element's text. /// /// @pre The Element has text. - xml::string_view text() const { + std::string_view text() const { const xmlNode* text_node = element_->children; while (text_node && text_node->type != XML_TEXT_NODE) text_node = text_node->next; @@ -329,17 +323,17 @@ /// /// @throws ValidityError Casting is unsuccessful. template - std::enable_if_t::value, boost::optional> + std::enable_if_t, std::optional> attribute(const char* name) const { - xml::string_view value = attribute(name); + std::string_view value = attribute(name); if (value.empty()) return {}; try { return detail::CastValue(value); } catch (ValidityError& err) { - err << errinfo_element(Element::name().to_string()) + err << errinfo_element(std::string(Element::name())) << errinfo_attribute(name) << boost::errinfo_at_line(line()) - << boost::errinfo_file_name(filename().to_string()); + << boost::errinfo_file_name(filename()); throw; } } @@ -354,13 +348,13 @@ /// /// @throws ValidityError Casting is unsuccessful. template - std::enable_if_t::value, T> text() const { + std::enable_if_t, T> text() const { try { return detail::CastValue(text()); } catch (ValidityError& err) { - err << errinfo_element(name().to_string()) + err << errinfo_element(std::string(name())) << boost::errinfo_at_line(line()) - << boost::errinfo_file_name(filename().to_string()); + << boost::errinfo_file_name(filename()); throw; } } @@ -369,7 +363,7 @@ /// Empty string to request any first child element. /// /// @returns The first child element (with the given name). - boost::optional child(xml::string_view name = "") const { + std::optional child(std::string_view name = "") const { for (Element element : children()) { if (name.empty() || name == element.name()) return element; @@ -385,7 +379,7 @@ /// @returns The range of Element children with the given name. /// /// @pre The name must live at least as long as the returned range lives. - auto children(xml::string_view name) const { + auto children(std::string_view name) const { return children() | boost::adaptors::filtered([name](const Element& element) { return element.name() == name; @@ -474,7 +468,4 @@ valid_ctxt_; }; -} // namespace xml -} // namespace scram - -#endif // SCRAM_SRC_XML_H_ +} // namespace scram::xml diff -Nru scram-0.16.1/src/xml_stream.h scram-0.16.2/src/xml_stream.h --- scram-0.16.1/src/xml_stream.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/xml_stream.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2017 Olzhas Rakhimov + * Copyright (C) 2016-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,7 @@ /// @file /// Facilities to stream data in XML format. -#ifndef SCRAM_SRC_XML_STREAM_H_ -#define SCRAM_SRC_XML_STREAM_H_ +#pragma once #include #include @@ -32,8 +31,7 @@ #include "error.h" -namespace scram { -namespace xml { +namespace scram::xml { /// Errors in using XML streaming facilities. struct StreamError : public Error { @@ -199,15 +197,6 @@ detail::FileStream* out) : StreamElement(name, 0, nullptr, indenter, out) {} - /// Move constructor is only declared - /// to make the compiler happy. - /// The code must rely on the RVO, NRVO, and copy elision - /// instead of this constructor. - /// - /// The constructor is not defined, - /// so the use of this constructor will produce a linker error. - StreamElement(StreamElement&&); - /// Puts the closing tag. /// /// @pre No child element is alive. @@ -377,7 +366,10 @@ /// /// @note This output file has clean error state. explicit Stream(std::FILE* out, bool indent = true) - : indenter_(indent), has_root_(false), out_(out) { + : indenter_(indent), + has_root_(false), + uncaught_exceptions_(std::uncaught_exceptions()), + out_(out) { assert(!std::ferror(out) && "Unclean error state in output destination."); out_ << "\n"; } @@ -387,7 +379,7 @@ /// @post The exception is thrown only if no other exception is on flight. ~Stream() noexcept(false) { int err = std::ferror(out_.file()); - if (err && !std::uncaught_exception()) + if (err && (std::uncaught_exceptions() == uncaught_exceptions_)) SCRAM_THROW(IOError("FILE error on write")) << boost::errinfo_errno(err); } @@ -412,10 +404,8 @@ private: detail::Indenter indenter_; ///< The indentation manager for the document. bool has_root_; ///< The document has constructed its root. + int uncaught_exceptions_; ///< The balance of exceptions. detail::FileStream out_; ///< The output stream. }; -} // namespace xml -} // namespace scram - -#endif // SCRAM_SRC_XML_STREAM_H_ +} // namespace scram::xml diff -Nru scram-0.16.1/src/zbdd.cc scram-0.16.2/src/zbdd.cc --- scram-0.16.1/src/zbdd.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/zbdd.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2017 Olzhas Rakhimov + * Copyright (C) 2015-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,8 +30,7 @@ #include "ext/find_iterator.h" #include "logger.h" -namespace scram { -namespace core { +namespace scram::core { #ifndef NDEBUG /// Runs assertions on ZBDD structure. @@ -943,5 +942,4 @@ } // namespace zbdd -} // namespace core -} // namespace scram +} // namespace scram::core diff -Nru scram-0.16.1/src/zbdd.h scram-0.16.2/src/zbdd.h --- scram-0.16.1/src/zbdd.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/src/zbdd.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2017 Olzhas Rakhimov + * Copyright (C) 2015-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,7 @@ /// @file /// Zero-Suppressed Binary Decision Diagram facilities. -#ifndef SCRAM_SRC_ZBDD_H_ -#define SCRAM_SRC_ZBDD_H_ +#pragma once #include @@ -37,8 +36,7 @@ #include "bdd.h" #include "pdag.h" -namespace scram { -namespace core { +namespace scram::core { /// Representation of non-terminal nodes in ZBDD. /// Complement variables are represented with negative indices. @@ -1007,7 +1005,4 @@ } // namespace zbdd -} // namespace core -} // namespace scram - -#endif // SCRAM_SRC_ZBDD_H_ +} // namespace scram::core diff -Nru scram-0.16.1/tests/alignment_tests.cc scram-0.16.2/tests/alignment_tests.cc --- scram-0.16.1/tests/alignment_tests.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/alignment_tests.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,62 +17,58 @@ #include "alignment.h" -#include +#include #include "error.h" -namespace scram { -namespace mef { -namespace test { - -TEST(PhaseTest, TimeFraction) { - EXPECT_NO_THROW(Phase("phase", 0.5)); - EXPECT_NO_THROW(Phase("phase", 0.1)); - EXPECT_NO_THROW(Phase("phase", 1)); - - EXPECT_THROW(Phase("phase", 0), DomainError); - EXPECT_THROW(Phase("phase", 1.1), DomainError); - EXPECT_THROW(Phase("phase", -0.1), DomainError); +namespace scram::mef::test { + +TEST_CASE("PhaseTest.TimeFraction", "[mef::alignment]") { + CHECK_NOTHROW(Phase("phase", 0.5)); + CHECK_NOTHROW(Phase("phase", 0.1)); + CHECK_NOTHROW(Phase("phase", 1)); + + CHECK_THROWS_AS(Phase("phase", 0), DomainError); + CHECK_THROWS_AS(Phase("phase", 1.1), DomainError); + CHECK_THROWS_AS(Phase("phase", -0.1), DomainError); } -TEST(AlignmentTest, AddPhase) { +TEST_CASE("AlignmentTest.AddPhase", "[mef::alignment]") { Alignment alignment("mission"); auto phase_one = std::make_unique("one", 0.5); auto phase_two = std::make_unique("one", 0.1); // Duplicate name. auto phase_three = std::make_unique("three", 0.1); - EXPECT_TRUE(alignment.phases().empty()); + CHECK(alignment.phases().empty()); auto* phase_one_address = phase_one.get(); - ASSERT_NO_THROW(alignment.Add(std::move(phase_one))); - EXPECT_EQ(1, alignment.phases().size()); - EXPECT_EQ(phase_one_address, alignment.phases().begin()->get()); - - EXPECT_THROW(alignment.Add(std::move(phase_two)), DuplicateArgumentError); - EXPECT_EQ(1, alignment.phases().size()); - EXPECT_EQ(phase_one_address, alignment.phases().begin()->get()); + REQUIRE_NOTHROW(alignment.Add(std::move(phase_one))); + CHECK(alignment.phases().size() == 1); + CHECK(alignment.phases().begin()->get() == phase_one_address); + + CHECK_THROWS_AS(alignment.Add(std::move(phase_two)), DuplicateArgumentError); + CHECK(alignment.phases().size() == 1); + CHECK(alignment.phases().begin()->get() == phase_one_address); - ASSERT_NO_THROW(alignment.Add(std::move(phase_three))); - EXPECT_EQ(2, alignment.phases().size()); + REQUIRE_NOTHROW(alignment.Add(std::move(phase_three))); + CHECK(alignment.phases().size() == 2); } -TEST(AlignmentTest, Validation) { +TEST_CASE("AlignmentTest.Validation", "[mef::alignment]") { Alignment alignment("mission"); auto phase_one = std::make_unique("one", 0.5); auto phase_two = std::make_unique("two", 0.5); auto phase_three = std::make_unique("three", 0.1); - EXPECT_THROW(alignment.Validate(), ValidityError); + CHECK_THROWS_AS(alignment.Validate(), ValidityError); - ASSERT_NO_THROW(alignment.Add(std::move(phase_one))); - EXPECT_THROW(alignment.Validate(), ValidityError); + REQUIRE_NOTHROW(alignment.Add(std::move(phase_one))); + CHECK_THROWS_AS(alignment.Validate(), ValidityError); - ASSERT_NO_THROW(alignment.Add(std::move(phase_two))); - EXPECT_NO_THROW(alignment.Validate()); + REQUIRE_NOTHROW(alignment.Add(std::move(phase_two))); + CHECK_NOTHROW(alignment.Validate()); - ASSERT_NO_THROW(alignment.Add(std::move(phase_three))); - EXPECT_THROW(alignment.Validate(), ValidityError); + REQUIRE_NOTHROW(alignment.Add(std::move(phase_three))); + CHECK_THROWS_AS(alignment.Validate(), ValidityError); } -} // namespace test -} // namespace mef -} // namespace scram +} // namespace scram::mef::test diff -Nru scram-0.16.1/tests/bench_200_event_tests.cc scram-0.16.2/tests/bench_200_event_tests.cc --- scram-0.16.1/tests/bench_200_event_tests.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/bench_200_event_tests.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,13 +15,9 @@ * along with this program. If not, see . */ -#include - #include "risk_analysis_tests.h" -namespace scram { -namespace core { -namespace test { +namespace scram::core::test { // Benchmark Tests for auto-generated 200 event fault tree. TEST_P(RiskAnalysisTest, 200Event) { @@ -37,6 +33,4 @@ EXPECT_EQ(287, products().size()); } -} // namespace test -} // namespace core -} // namespace scram +} // namespace scram::core::test diff -Nru scram-0.16.1/tests/bench_attack.cc scram-0.16.2/tests/bench_attack.cc --- scram-0.16.1/tests/bench_attack.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/bench_attack.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,13 +15,9 @@ * along with this program. If not, see . */ -#include - #include "risk_analysis_tests.h" -namespace scram { -namespace core { -namespace test { +namespace scram::core::test { TEST_P(RiskAnalysisTest, AttackEventTree) { const char* tree_input = "input/EventTrees/attack.xml"; @@ -36,6 +32,4 @@ results); } -} // namespace test -} // namespace core -} // namespace scram +} // namespace scram::core::test diff -Nru scram-0.16.1/tests/bench_baobab1_tests.cc scram-0.16.2/tests/bench_baobab1_tests.cc --- scram-0.16.1/tests/bench_baobab1_tests.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/bench_baobab1_tests.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,13 +15,9 @@ * along with this program. If not, see . */ -#include - #include "risk_analysis_tests.h" -namespace scram { -namespace core { -namespace test { +namespace scram::core::test { // Benchmark Tests for Baobab 1 fault tree from XFTA. #ifdef NDEBUG @@ -73,6 +69,4 @@ 40, analysis->results().front().importance_analysis->importance().size()); } -} // namespace test -} // namespace core -} // namespace scram +} // namespace scram::core::test diff -Nru scram-0.16.1/tests/bench_baobab2_tests.cc scram-0.16.2/tests/bench_baobab2_tests.cc --- scram-0.16.1/tests/bench_baobab2_tests.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/bench_baobab2_tests.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,13 +15,9 @@ * along with this program. If not, see . */ -#include - #include "risk_analysis_tests.h" -namespace scram { -namespace core { -namespace test { +namespace scram::core::test { // Benchmark Tests for Baobab 2 fault tree from XFTA. TEST_P(RiskAnalysisTest, Baobab2) { @@ -34,6 +30,4 @@ EXPECT_EQ(distr, ProductDistribution()); } -} // namespace test -} // namespace core -} // namespace scram +} // namespace scram::core::test diff -Nru scram-0.16.1/tests/bench_bscu_tests.cc scram-0.16.2/tests/bench_bscu_tests.cc --- scram-0.16.1/tests/bench_bscu_tests.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/bench_bscu_tests.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2017 Olzhas Rakhimov + * Copyright (C) 2016-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,13 +15,9 @@ * along with this program. If not, see . */ -#include - #include "risk_analysis_tests.h" -namespace scram { -namespace core { -namespace test { +namespace scram::core::test { // Benchmark Tests for BSCU fault tree from XFTA. // This benchmark is for uncertainty analysis. @@ -57,6 +53,4 @@ } } -} // namespace test -} // namespace core -} // namespace scram +} // namespace scram::core::test diff -Nru scram-0.16.1/tests/bench_CEA9601_tests.cc scram-0.16.2/tests/bench_CEA9601_tests.cc --- scram-0.16.1/tests/bench_CEA9601_tests.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/bench_CEA9601_tests.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,13 +15,9 @@ * along with this program. If not, see . */ -#include - #include "risk_analysis_tests.h" -namespace scram { -namespace core { -namespace test { +namespace scram::core::test { // Benchmark Tests for CEA9601 fault tree from XFTA. #ifdef NDEBUG @@ -54,6 +50,4 @@ } #endif -} // namespace test -} // namespace core -} // namespace scram +} // namespace scram::core::test diff -Nru scram-0.16.1/tests/bench_chinese_tree_tests.cc scram-0.16.2/tests/bench_chinese_tree_tests.cc --- scram-0.16.1/tests/bench_chinese_tree_tests.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/bench_chinese_tree_tests.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,13 +15,9 @@ * along with this program. If not, see . */ -#include - #include "risk_analysis_tests.h" -namespace scram { -namespace core { -namespace test { +namespace scram::core::test { // Benchmark Tests for Chinese fault tree from XFTA. TEST_P(RiskAnalysisTest, ChineseTree) { @@ -93,6 +89,4 @@ EXPECT_EQ(distr, ProductDistribution()); } -} // namespace test -} // namespace core -} // namespace scram +} // namespace scram::core::test diff -Nru scram-0.16.1/tests/bench_core_tests.cc scram-0.16.2/tests/bench_core_tests.cc --- scram-0.16.1/tests/bench_core_tests.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/bench_core_tests.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,13 +15,9 @@ * along with this program. If not, see . */ -#include - #include "risk_analysis_tests.h" -namespace scram { -namespace core { -namespace test { +namespace scram::core::test { // Benchmark Tests for [A or B or C] fault tree. TEST_P(RiskAnalysisTest, ABC) { @@ -491,6 +487,4 @@ CheckReport({tree_input}); } -} // namespace test -} // namespace core -} // namespace scram +} // namespace scram::core::test diff -Nru scram-0.16.1/tests/bench_gas_leak.cc scram-0.16.2/tests/bench_gas_leak.cc --- scram-0.16.1/tests/bench_gas_leak.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/bench_gas_leak.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,13 +15,9 @@ * along with this program. If not, see . */ -#include - #include "risk_analysis_tests.h" -namespace scram { -namespace core { -namespace test { +namespace scram::core::test { TEST_F(RiskAnalysisTest, GasLeakReactive) { const char* tree_input = "input/EventTrees/gas_leak/gas_leak_reactive.xml"; @@ -35,8 +31,9 @@ const auto& results = sequences(); ASSERT_EQ(8, results.size()); for (const auto& result : expected) { - ASSERT_TRUE(results.count(result.first)) << result.first; - EXPECT_NEAR(result.second, results.at(result.first), 1e-5) << result.first; + INFO("seq: " + result.first); + ASSERT_TRUE(results.count(result.first)); + EXPECT_NEAR(result.second, results.at(result.first), 1e-5); } } @@ -50,6 +47,4 @@ EXPECT_EQ(2, analysis->event_tree_results().size()); } -} // namespace test -} // namespace core -} // namespace scram +} // namespace scram::core::test diff -Nru scram-0.16.1/tests/bench_hipps_tests.cc scram-0.16.2/tests/bench_hipps_tests.cc --- scram-0.16.1/tests/bench_hipps_tests.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/bench_hipps_tests.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,13 +15,9 @@ * along with this program. If not, see . */ -#include - #include "risk_analysis_tests.h" -namespace scram { -namespace core { -namespace test { +namespace scram::core::test { // Benchmark Tests for HIPPS fault tree from XFTA. // @todo Test Safety Integrity Level analysis. @@ -41,6 +37,4 @@ EXPECT_EQ(distr, ProductDistribution()); } -} // namespace test -} // namespace core -} // namespace scram +} // namespace scram::core::test diff -Nru scram-0.16.1/tests/bench_lift_tests.cc scram-0.16.2/tests/bench_lift_tests.cc --- scram-0.16.1/tests/bench_lift_tests.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/bench_lift_tests.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,13 +15,9 @@ * along with this program. If not, see . */ -#include - #include "risk_analysis_tests.h" -namespace scram { -namespace core { -namespace test { +namespace scram::core::test { // Benchmark tests for Lift system from OpenFTA. TEST_P(RiskAnalysisTest, Lift) { @@ -39,6 +35,4 @@ EXPECT_EQ(mcs, products()); } -} // namespace test -} // namespace core -} // namespace scram +} // namespace scram::core::test diff -Nru scram-0.16.1/tests/bench_ne574_tests.cc scram-0.16.2/tests/bench_ne574_tests.cc --- scram-0.16.1/tests/bench_ne574_tests.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/bench_ne574_tests.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,13 +15,9 @@ * along with this program. If not, see . */ -#include - #include "risk_analysis_tests.h" -namespace scram { -namespace core { -namespace test { +namespace scram::core::test { // Benchmark Tests for an example fault tree // given in NE574 Risk Analysis class at UW-Madison. @@ -42,6 +38,4 @@ EXPECT_EQ(mcs, products()); } -} // namespace test -} // namespace core -} // namespace scram +} // namespace scram::core::test diff -Nru scram-0.16.1/tests/bench_small_tree_tests.cc scram-0.16.2/tests/bench_small_tree_tests.cc --- scram-0.16.1/tests/bench_small_tree_tests.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/bench_small_tree_tests.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,13 +15,9 @@ * along with this program. If not, see . */ -#include - #include "risk_analysis_tests.h" -namespace scram { -namespace core { -namespace test { +namespace scram::core::test { // Benchmark Tests for Small Tree fault tree from XFTA. // This benchmark is for uncertainty analysis. @@ -45,6 +41,4 @@ } } -} // namespace test -} // namespace core -} // namespace scram +} // namespace scram::core::test diff -Nru scram-0.16.1/tests/bench_theatre_tests.cc scram-0.16.2/tests/bench_theatre_tests.cc --- scram-0.16.1/tests/bench_theatre_tests.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/bench_theatre_tests.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,13 +15,9 @@ * along with this program. If not, see . */ -#include - #include "risk_analysis_tests.h" -namespace scram { -namespace core { -namespace test { +namespace scram::core::test { // Benchmark Tests for Theatre fault tree from OpenFTA. TEST_P(RiskAnalysisTest, Theatre) { @@ -40,6 +36,4 @@ EXPECT_EQ(mcs, products()); } -} // namespace test -} // namespace core -} // namespace scram +} // namespace scram::core::test diff -Nru scram-0.16.1/tests/bench_three_motor_tests.cc scram-0.16.2/tests/bench_three_motor_tests.cc --- scram-0.16.1/tests/bench_three_motor_tests.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/bench_three_motor_tests.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,13 +15,9 @@ * along with this program. If not, see . */ -#include - #include "risk_analysis_tests.h" -namespace scram { -namespace core { -namespace test { +namespace scram::core::test { // Benchmark Tests for the ThreeMotor fault tree from OpenFTA. TEST_P(RiskAnalysisTest, ThreeMotor) { @@ -89,11 +85,10 @@ const auto& results = sequences(); ASSERT_EQ(8, results.size()); for (const auto& result : expected) { - ASSERT_TRUE(results.count(result.first)) << result.first; - EXPECT_NEAR(result.second, results.at(result.first), 1e-5) << result.first; + INFO("seq: " + result.first); + ASSERT_TRUE(results.count(result.first)); + EXPECT_NEAR(result.second, results.at(result.first), 1e-5); } } -} // namespace test -} // namespace core -} // namespace scram +} // namespace scram::core::test diff -Nru scram-0.16.1/tests/bench_two_train_tests.cc scram-0.16.2/tests/bench_two_train_tests.cc --- scram-0.16.1/tests/bench_two_train_tests.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/bench_two_train_tests.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,13 +15,9 @@ * along with this program. If not, see . */ -#include - #include "risk_analysis_tests.h" -namespace scram { -namespace core { -namespace test { +namespace scram::core::test { // Benchmark Tests for an example fault tree with // Two trains of Pumps and Valves. @@ -95,6 +91,4 @@ EXPECT_EQ(mcs, products()); } -} // namespace test -} // namespace core -} // namespace scram +} // namespace scram::core::test diff -Nru scram-0.16.1/tests/ccf_group_tests.cc scram-0.16.2/tests/ccf_group_tests.cc --- scram-0.16.1/tests/ccf_group_tests.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/ccf_group_tests.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2015, 2017 Olzhas Rakhimov + * Copyright (C) 2014-2015, 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,37 +17,33 @@ #include "ccf_group.h" -#include +#include #include "error.h" #include "expression/constant.h" -namespace scram { -namespace mef { -namespace test { +namespace scram::mef::test { -TEST(CcfGroupTest, AddMemberRepeated) { +TEST_CASE("CcfGroupTest.AddMemberRepeated", "[mef::ccf_group]") { BetaFactorModel ccf_group("general"); BasicEvent member("id"); - ASSERT_NO_THROW(ccf_group.AddMember(&member)); - EXPECT_THROW(ccf_group.AddMember(&member), ValidityError); + REQUIRE_NOTHROW(ccf_group.AddMember(&member)); + CHECK_THROWS_AS(ccf_group.AddMember(&member), ValidityError); } -TEST(CcfGroupTest, AddMemberAfterDistribution) { +TEST_CASE("CcfGroupTest.AddMemberAfterDistribution", "[mef::ccf_group]") { BetaFactorModel ccf_group("general"); BasicEvent member_one("id"); - ASSERT_NO_THROW(ccf_group.AddMember(&member_one)); + REQUIRE_NOTHROW(ccf_group.AddMember(&member_one)); BasicEvent member_two("two"); - EXPECT_NO_THROW(ccf_group.AddMember(&member_two)); + CHECK_NOTHROW(ccf_group.AddMember(&member_two)); - ASSERT_NO_THROW(ccf_group.AddDistribution(&ConstantExpression::kOne)); + REQUIRE_NOTHROW(ccf_group.AddDistribution(&ConstantExpression::kOne)); BasicEvent member_three("three"); - EXPECT_THROW(ccf_group.AddMember(&member_three), LogicError); + CHECK_THROWS_AS(ccf_group.AddMember(&member_three), LogicError); } -} // namespace test -} // namespace mef -} // namespace scram +} // namespace scram::mef::test diff -Nru scram-0.16.1/tests/CMakeLists.txt scram-0.16.2/tests/CMakeLists.txt --- scram-0.16.1/tests/CMakeLists.txt 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/CMakeLists.txt 2018-01-12 11:42:47.000000000 +0000 @@ -1,14 +1,4 @@ -# Exclude Debug warnings from the framework. -set(CURRENT_DEBUG_FLAGS "${CMAKE_CXX_FLAGS_DEBUG}") -set(CMAKE_CXX_FLAGS_DEBUG "-g") - -set(GTEST_DIR googletest/googletest) - -add_subdirectory("${GTEST_DIR}" EXCLUDE_FROM_ALL) - -set(CMAKE_CXX_FLAGS_DEBUG "${CURRENT_DEBUG_FLAGS}") # Restore the original flags. - -include_directories(SYSTEM "${GTEST_DIR}/include") +include_directories(SYSTEM "catch2/single_include") # Include the project headers. include_directories("${CMAKE_SOURCE_DIR}/src") @@ -28,8 +18,8 @@ alignment_tests.cc pdag_tests.cc initializer_tests.cc - risk_analysis_tests.cc serialization_tests.cc + risk_analysis_tests.cc bench_core_tests.cc bench_two_train_tests.cc bench_lift_tests.cc @@ -53,8 +43,8 @@ configure_file(scram_unit_test_driver.cc.in scram_unit_test_driver.cc @ONLY) add_executable(scram_tests ${CMAKE_CURRENT_BINARY_DIR}/scram_unit_test_driver.cc ${SCRAM_CORE_TEST_SOURCE}) - -target_link_libraries(scram_tests ${LIBS} scram gtest) +target_link_libraries(scram_tests ${LIBS} scram) +target_compile_options(scram_tests PRIVATE $<$:${SCRAM_CXX_FLAGS_DEBUG}>) install( TARGETS scram_tests @@ -64,6 +54,7 @@ # Create dummy library to test dynamic loading and extern function. add_library(scram_dummy_extern SHARED scram_dummy_extern.cc) +target_compile_options(scram_dummy_extern PRIVATE $<$:${SCRAM_CXX_FLAGS_DEBUG}>) if(WIN32) set(CMAKE_SHARED_LIBRARY_PREFIX "") install( diff -Nru scram-0.16.1/tests/config_tests.cc scram-0.16.2/tests/config_tests.cc --- scram-0.16.1/tests/config_tests.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/config_tests.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2015, 2017 Olzhas Rakhimov + * Copyright (C) 2014-2015, 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,93 +17,93 @@ #include "config.h" -#include +#include #include #include "error.h" -namespace scram { -namespace test { +namespace scram::test { // Test with a wrong input. -TEST(ConfigTest, IOError) { +TEST_CASE("ConfigTest.IOError", "[config]") { std::string config_file = "./nonexistent_configurations.xml"; - ASSERT_THROW(Config config(config_file), IOError); + REQUIRE_THROWS_AS(Config(config_file), IOError); } // Test with XML content validation issues. -TEST(ConfigTest, ValidityError) { +TEST_CASE("ConfigTest.ValidityError", "[config]") { std::string config_file = "tests/input/fta/invalid_configuration.xml"; - ASSERT_THROW(Config config(config_file), xml::ValidityError); + REQUIRE_THROWS_AS(Config(config_file), xml::ValidityError); } // Test with XML content numerical issues. -TEST(ConfigTest, NumericalErrors) { +TEST_CASE("ConfigTest.NumericalErrors", "[config]") { std::string config_file = "tests/input/fta/int_overflow_config.xml"; - ASSERT_THROW(Config config(config_file), xml::ValidityError); + REQUIRE_THROWS_AS(Config(config_file), xml::ValidityError); } // Tests all settings with one file. -TEST(ConfigTest, FullSettings) { +TEST_CASE("ConfigTest.FullSettings", "[config]") { std::string config_file = "tests/input/fta/full_configuration.xml"; std::string cwd = boost::filesystem::current_path().generic_string(); Config config(config_file); // Check the input files. - EXPECT_EQ(config.input_files().size(), 1); + CHECK(config.input_files().size() == 1); if (!config.input_files().empty()) { - EXPECT_EQ(cwd + "/tests/input/fta/correct_tree_input_with_probs.xml", - config.input_files().back()); + auto prob = cwd + "/tests/input/fta/correct_tree_input_with_probs.xml"; + CHECK(config.input_files().back() == prob); } // Check the output destination. - EXPECT_EQ(cwd + "/tests/input/fta/./temp_results.xml", config.output_path()); + auto out_dest = cwd + "/tests/input/fta/./temp_results.xml"; + CHECK(config.output_path() == out_dest); const core::Settings& settings = config.settings(); - EXPECT_EQ(core::Algorithm::kBdd, settings.algorithm()); - EXPECT_FALSE(settings.prime_implicants()); - EXPECT_TRUE(settings.probability_analysis()); - EXPECT_TRUE(settings.importance_analysis()); - EXPECT_TRUE(settings.uncertainty_analysis()); - EXPECT_TRUE(settings.ccf_analysis()); - EXPECT_TRUE(settings.safety_integrity_levels()); - EXPECT_EQ(core::Approximation::kRareEvent, settings.approximation()); - EXPECT_EQ(11, settings.limit_order()); - EXPECT_EQ(48, settings.mission_time()); - EXPECT_EQ(1, settings.time_step()); - EXPECT_EQ(0.009, settings.cut_off()); - EXPECT_EQ(777, settings.num_trials()); - EXPECT_EQ(13, settings.num_quantiles()); - EXPECT_EQ(31, settings.num_bins()); - EXPECT_EQ(97531, settings.seed()); + CHECK(settings.algorithm() == core::Algorithm::kBdd); + CHECK_FALSE(settings.prime_implicants()); + CHECK(settings.probability_analysis()); + CHECK(settings.importance_analysis()); + CHECK(settings.uncertainty_analysis()); + CHECK(settings.ccf_analysis()); + CHECK(settings.safety_integrity_levels()); + CHECK(settings.approximation() == core::Approximation::kRareEvent); + CHECK(settings.limit_order() == 11); + CHECK(settings.mission_time() == 48); + CHECK(settings.time_step() == 1); + CHECK(settings.cut_off() == 0.009); + CHECK(settings.num_trials() == 777); + CHECK(settings.num_quantiles() == 13); + CHECK(settings.num_bins() == 31); + CHECK(settings.seed() == 97531); } -TEST(ConfigTest, PrimeImplicantsSettings) { +TEST_CASE("ConfigTest.PrimeImplicantsSettings", "[config]") { std::string config_file = "tests/input/fta/pi_configuration.xml"; std::string cwd = boost::filesystem::current_path().generic_string(); Config config(config_file); // Check the input files. - EXPECT_EQ(config.input_files().size(), 1); + CHECK(config.input_files().size() == 1); if (!config.input_files().empty()) { - EXPECT_EQ(cwd + "/tests/input/fta/correct_tree_input_with_probs.xml", - config.input_files().back()); + auto prob = cwd + "/tests/input/fta/correct_tree_input_with_probs.xml"; + CHECK(config.input_files().back() == prob); } // Check the output destination. - EXPECT_EQ(cwd + "/tests/input/fta/temp_results.xml", config.output_path()); + auto out_dest = cwd + "/tests/input/fta/temp_results.xml"; + CHECK(config.output_path() == out_dest); const core::Settings& settings = config.settings(); - EXPECT_EQ(core::Algorithm::kBdd, settings.algorithm()); - EXPECT_TRUE(settings.prime_implicants()); + CHECK(settings.algorithm() == core::Algorithm::kBdd); + CHECK(settings.prime_implicants()); } -TEST(ConfigTest, CanonicalPath) { +TEST_CASE("ConfigTest.CanonicalPath", "[config]") { std::string config_file = "tests/input/win_path_in_config.xml"; std::string cwd = boost::filesystem::current_path().generic_string(); Config config(config_file); // Check the input files. - ASSERT_EQ(config.input_files().size(), 1); - ASSERT_EQ(cwd + "/tests/input/fta/correct_tree_input_with_probs.xml", - config.input_files().back()); + REQUIRE(config.input_files().size() == 1); + auto prob = cwd + "/tests/input/fta/correct_tree_input_with_probs.xml"; + REQUIRE(config.input_files().back() == prob); } -} // namespace test -} // namespace scram +} // namespace scram::test diff -Nru scram-0.16.1/tests/element_tests.cc scram-0.16.2/tests/element_tests.cc --- scram-0.16.1/tests/element_tests.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/element_tests.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,13 +17,11 @@ #include "element.h" -#include +#include #include "error.h" -namespace scram { -namespace mef { -namespace test { +namespace scram::mef::test { namespace { @@ -34,86 +32,86 @@ } // namespace -TEST(ElementTest, Name) { - EXPECT_THROW(NamedElement(""), LogicError); +TEST_CASE("ElementTest.Name", "[mef::element]") { + CHECK_THROWS_AS(NamedElement(""), LogicError); - EXPECT_THROW(NamedElement(".name"), ValidityError); - EXPECT_THROW(NamedElement("na.me"), ValidityError); - EXPECT_THROW(NamedElement("name."), ValidityError); + CHECK_THROWS_AS(NamedElement(".name"), ValidityError); + CHECK_THROWS_AS(NamedElement("na.me"), ValidityError); + CHECK_THROWS_AS(NamedElement("name."), ValidityError); - EXPECT_NO_THROW(NamedElement("name")); + CHECK_NOTHROW(NamedElement("name")); NamedElement el("name"); - EXPECT_EQ("name", el.name()); + CHECK(el.name() == "name"); // Illegal names by MEF. // However, this names don't mess with class and reference invariants. - EXPECT_NO_THROW(NamedElement("na me")); - EXPECT_NO_THROW(NamedElement("na\nme")); - EXPECT_NO_THROW(NamedElement("\tname")); - EXPECT_NO_THROW(NamedElement("name?")); + CHECK_NOTHROW(NamedElement("na me")); + CHECK_NOTHROW(NamedElement("na\nme")); + CHECK_NOTHROW(NamedElement("\tname")); + CHECK_NOTHROW(NamedElement("name?")); } -TEST(ElementTest, Label) { +TEST_CASE("ElementTest.Label", "[mef::element]") { NamedElement el("name"); - EXPECT_EQ("", el.label()); - EXPECT_NO_THROW(el.label("")); - ASSERT_NO_THROW(el.label("label")); - EXPECT_EQ("label", el.label()); - EXPECT_NO_THROW(el.label("new_label")); - EXPECT_NO_THROW(el.label("")); + CHECK(el.label() == ""); + CHECK_NOTHROW(el.label("")); + REQUIRE_NOTHROW(el.label("label")); + CHECK(el.label() == "label"); + CHECK_NOTHROW(el.label("new_label")); + CHECK_NOTHROW(el.label("")); } -TEST(ElementTest, AddAttribute) { +TEST_CASE("ElementTest.AddAttribute", "[mef::element]") { NamedElement el("name"); Attribute attr; attr.name = "impact"; attr.value = "0.1"; attr.type = "float"; - EXPECT_THROW(el.GetAttribute(attr.name), LogicError); - ASSERT_NO_THROW(el.AddAttribute(attr)); - EXPECT_THROW(el.AddAttribute(attr), DuplicateArgumentError); - ASSERT_TRUE(el.HasAttribute(attr.name)); - ASSERT_NO_THROW(el.GetAttribute(attr.name)); - EXPECT_EQ(attr.value, el.GetAttribute(attr.name).value); - EXPECT_EQ(attr.name, el.GetAttribute(attr.name).name); + CHECK_THROWS_AS(el.GetAttribute(attr.name), LogicError); + REQUIRE_NOTHROW(el.AddAttribute(attr)); + CHECK_THROWS_AS(el.AddAttribute(attr), DuplicateArgumentError); + REQUIRE(el.HasAttribute(attr.name)); + REQUIRE_NOTHROW(el.GetAttribute(attr.name)); + CHECK(el.GetAttribute(attr.name).value == attr.value); + CHECK(el.GetAttribute(attr.name).name == attr.name); } -TEST(ElementTest, SetAttribute) { +TEST_CASE("ElementTest.SetAttribute", "[mef::element]") { NamedElement el("name"); Attribute attr; attr.name = "impact"; attr.value = "0.1"; attr.type = "float"; - EXPECT_THROW(el.GetAttribute(attr.name), LogicError); - ASSERT_NO_THROW(el.SetAttribute(attr)); - EXPECT_THROW(el.AddAttribute(attr), DuplicateArgumentError); - ASSERT_TRUE(el.HasAttribute(attr.name)); - ASSERT_NO_THROW(el.GetAttribute(attr.name)); - EXPECT_EQ(attr.value, el.GetAttribute(attr.name).value); - EXPECT_EQ(attr.name, el.GetAttribute(attr.name).name); + CHECK_THROWS_AS(el.GetAttribute(attr.name), LogicError); + REQUIRE_NOTHROW(el.SetAttribute(attr)); + CHECK_THROWS_AS(el.AddAttribute(attr), DuplicateArgumentError); + REQUIRE(el.HasAttribute(attr.name)); + REQUIRE_NOTHROW(el.GetAttribute(attr.name)); + CHECK(el.GetAttribute(attr.name).value == attr.value); + CHECK(el.GetAttribute(attr.name).name == attr.name); attr.value = "0.2"; - ASSERT_NO_THROW(el.SetAttribute(attr)); - EXPECT_EQ(1, el.attributes().size()); - ASSERT_NO_THROW(el.GetAttribute(attr.name)); - EXPECT_EQ(attr.value, el.GetAttribute(attr.name).value); + REQUIRE_NOTHROW(el.SetAttribute(attr)); + CHECK(el.attributes().size() == 1); + REQUIRE_NOTHROW(el.GetAttribute(attr.name)); + CHECK(el.GetAttribute(attr.name).value == attr.value); } -TEST(ElementTest, RemoveAttribute) { +TEST_CASE("ElementTest.RemoveAttribute", "[mef::element]") { NamedElement el("name"); Attribute attr; attr.name = "impact"; attr.value = "0.1"; attr.type = "float"; - EXPECT_FALSE(el.HasAttribute(attr.name)); - EXPECT_TRUE(el.attributes().empty()); - EXPECT_FALSE(el.RemoveAttribute(attr.name)); - - ASSERT_NO_THROW(el.AddAttribute(attr)); - EXPECT_TRUE(el.RemoveAttribute(attr.name)); - EXPECT_FALSE(el.HasAttribute(attr.name)); - EXPECT_TRUE(el.attributes().empty()); + CHECK_FALSE(el.HasAttribute(attr.name)); + CHECK(el.attributes().empty()); + CHECK_FALSE(el.RemoveAttribute(attr.name)); + + REQUIRE_NOTHROW(el.AddAttribute(attr)); + CHECK(el.RemoveAttribute(attr.name)); + CHECK_FALSE(el.HasAttribute(attr.name)); + CHECK(el.attributes().empty()); } namespace { @@ -125,13 +123,13 @@ } // namespace -TEST(ElementTest, Role) { - EXPECT_THROW(TestRole(RoleSpecifier::kPublic, ".ref"), ValidityError); - EXPECT_THROW(TestRole(RoleSpecifier::kPublic, "ref."), ValidityError); - EXPECT_NO_THROW(TestRole(RoleSpecifier::kPublic, "ref.name")); +TEST_CASE("ElementTest.Role", "[mef::element]") { + CHECK_THROWS_AS(TestRole(RoleSpecifier::kPublic, ".ref"), ValidityError); + CHECK_THROWS_AS(TestRole(RoleSpecifier::kPublic, "ref."), ValidityError); + CHECK_NOTHROW(TestRole(RoleSpecifier::kPublic, "ref.name")); - EXPECT_THROW(TestRole(RoleSpecifier::kPrivate, ""), ValidityError); - EXPECT_NO_THROW(TestRole(RoleSpecifier::kPublic, "")); + CHECK_THROWS_AS(TestRole(RoleSpecifier::kPrivate, ""), ValidityError); + CHECK_NOTHROW(TestRole(RoleSpecifier::kPublic, "")); } namespace { @@ -143,29 +141,27 @@ } // namespace -TEST(ElementTest, Id) { - EXPECT_THROW(NameId(""), LogicError); - EXPECT_NO_THROW(NameId("name")); - EXPECT_THROW(NameId("name", "", RoleSpecifier::kPrivate), ValidityError); +TEST_CASE("ElementTest.Id", "[mef::element]") { + CHECK_THROWS_AS(NameId(""), LogicError); + CHECK_NOTHROW(NameId("name")); + CHECK_THROWS_AS(NameId("name", "", RoleSpecifier::kPrivate), ValidityError); NameId id_public("name"); - EXPECT_EQ(id_public.id(), id_public.name()); + CHECK(id_public.name() == id_public.id()); NameId id_private("name", "path", RoleSpecifier::kPrivate); - EXPECT_EQ("path.name", id_private.id()); - EXPECT_NE(id_private.id(), id_private.name()); + CHECK(id_private.id() == "path.name"); + CHECK_FALSE(id_private.name() == id_private.id()); - EXPECT_NE(id_public.id(), id_private.id()); + CHECK_FALSE(id_private.id() == id_public.id()); // Reset. id_public.id("id"); - EXPECT_EQ("id", id_public.id()); - EXPECT_EQ("id", id_public.name()); + CHECK(id_public.id() == "id"); + CHECK(id_public.name() == "id"); id_private.id("id"); - EXPECT_EQ("path.id", id_private.id()); - EXPECT_EQ("id", id_private.name()); + CHECK(id_private.id() == "path.id"); + CHECK(id_private.name() == "id"); } -} // namespace test -} // namespace mef -} // namespace scram +} // namespace scram::mef::test diff -Nru scram-0.16.1/tests/event_tests.cc scram-0.16.2/tests/event_tests.cc --- scram-0.16.1/tests/event_tests.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/event_tests.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,108 +17,106 @@ #include "event.h" -#include +#include #include "cycle.h" #include "error.h" #include "expression/constant.h" -namespace scram { -namespace mef { -namespace test { +namespace scram::mef::test { // Test for Event base class. -TEST(EventTest, Id) { +TEST_CASE("EventTest.Id", "[mef::event]") { BasicEvent event("event_name"); - EXPECT_EQ(event.id(), "event_name"); + CHECK("event_name" == event.id()); } -TEST(BasicEventTest, ExpressionReset) { +TEST_CASE("BasicEventTest.ExpressionReset", "[mef::event]") { BasicEvent event("event"); - EXPECT_FALSE(event.HasExpression()); + CHECK_FALSE(event.HasExpression()); ConstantExpression p_init(0.5); event.expression(&p_init); - ASSERT_TRUE(event.HasExpression()); - EXPECT_EQ(0.5, event.p()); + REQUIRE(event.HasExpression()); + CHECK(event.p() == 0.5); ConstantExpression p_change(0.1); event.expression(&p_change); - ASSERT_TRUE(event.HasExpression()); - EXPECT_EQ(0.1, event.p()); + REQUIRE(event.HasExpression()); + CHECK(event.p() == 0.1); } -TEST(BasicEventTest, Validate) { +TEST_CASE("BasicEventTest.Validate", "[mef::event]") { BasicEvent event("event"); - EXPECT_FALSE(event.HasExpression()); + CHECK_FALSE(event.HasExpression()); ConstantExpression p_valid(0.5); event.expression(&p_valid); - ASSERT_TRUE(event.HasExpression()); - EXPECT_NO_THROW(event.Validate()); + REQUIRE(event.HasExpression()); + CHECK_NOTHROW(event.Validate()); ConstantExpression p_negative(-0.1); event.expression(&p_negative); - ASSERT_TRUE(event.HasExpression()); - EXPECT_THROW(event.Validate(), ValidityError); + REQUIRE(event.HasExpression()); + CHECK_THROWS_AS(event.Validate(), ValidityError); ConstantExpression p_large(1.1); event.expression(&p_large); - ASSERT_TRUE(event.HasExpression()); - EXPECT_THROW(event.Validate(), ValidityError); + REQUIRE(event.HasExpression()); + CHECK_THROWS_AS(event.Validate(), ValidityError); } -TEST(FormulaTest, VoteNumber) { +TEST_CASE("FormulaTest.VoteNumber", "[mef::event]") { FormulaPtr top(new Formula(kAnd)); - EXPECT_EQ(kAnd, top->type()); + CHECK(top->type() == kAnd); // Setting a vote number for non-Vote formula is an error. - EXPECT_THROW(top->vote_number(2), LogicError); + CHECK_THROWS_AS(top->vote_number(2), LogicError); // Resetting to VOTE formula. top = FormulaPtr(new Formula(kVote)); - EXPECT_EQ(kVote, top->type()); + CHECK(top->type() == kVote); // No vote number. - EXPECT_THROW(top->vote_number(), LogicError); + CHECK_THROWS_AS(top->vote_number(), LogicError); // Illegal vote number. - EXPECT_THROW(top->vote_number(-2), ValidityError); + CHECK_THROWS_AS(top->vote_number(-2), ValidityError); // Legal vote number. - EXPECT_NO_THROW(top->vote_number(2)); + CHECK_NOTHROW(top->vote_number(2)); // Trying to reset the vote number. - EXPECT_THROW(top->vote_number(2), LogicError); + CHECK_THROWS_AS(top->vote_number(2), LogicError); // Requesting the vote number should succeed. - ASSERT_NO_THROW(top->vote_number()); - EXPECT_EQ(2, top->vote_number()); + REQUIRE_NOTHROW(top->vote_number()); + CHECK(top->vote_number() == 2); } -TEST(FormulaTest, EventArguments) { +TEST_CASE("FormulaTest.EventArguments", "[mef::event]") { FormulaPtr top(new Formula(kAnd)); BasicEvent first_child("first"); BasicEvent second_child("second"); - EXPECT_EQ(0, top->num_args()); + CHECK(top->num_args() == 0); // Adding first child. - EXPECT_NO_THROW(top->AddArgument(&first_child)); + CHECK_NOTHROW(top->AddArgument(&first_child)); // Re-adding a child must cause an error. - EXPECT_THROW(top->AddArgument(&first_child), ValidityError); + CHECK_THROWS_AS(top->AddArgument(&first_child), ValidityError); // Check the contents of the children container. - EXPECT_EQ(&first_child, boost::get(top->event_args().front())); + CHECK(std::get(top->event_args().front()) == &first_child); // Adding another child. - EXPECT_NO_THROW(top->AddArgument(&second_child)); - EXPECT_EQ(2, top->event_args().size()); - EXPECT_EQ(&second_child, boost::get(top->event_args().back())); - - EXPECT_NO_THROW(top->RemoveArgument(&first_child)); - EXPECT_EQ(1, top->num_args()); - EXPECT_THROW(top->RemoveArgument(&first_child), LogicError); + CHECK_NOTHROW(top->AddArgument(&second_child)); + CHECK(top->event_args().size() == 2); + CHECK(std::get(top->event_args().back()) == &second_child); + + CHECK_NOTHROW(top->RemoveArgument(&first_child)); + CHECK(top->num_args() == 1); + CHECK_THROWS_AS(top->RemoveArgument(&first_child), LogicError); } -TEST(FormulaTest, FormulaArguments) { +TEST_CASE("FormulaTest.FormulaArguments", "[mef::event]") { FormulaPtr top(new Formula(kAnd)); FormulaPtr arg(new Formula(kOr)); - EXPECT_EQ(0, top->num_args()); + CHECK(top->num_args() == 0); Formula* shadow = arg.get(); // Adding first child. - EXPECT_NO_THROW(top->AddArgument(std::move(arg))); // arg is gone. - EXPECT_EQ(shadow, top->formula_args().begin()->get()); + CHECK_NOTHROW(top->AddArgument(std::move(arg))); // arg is gone. + CHECK(top->formula_args().begin()->get() == shadow); } -TEST(MEFGateTest, Cycle) { +TEST_CASE("MEFGateTest.Cycle", "[mef::event]") { Gate root("root"); // Should not appear in the cycle. Gate top("Top"); Gate middle("Middle"); @@ -140,97 +138,97 @@ std::vector cycle; bool ret = cycle::DetectCycle(&root, &cycle); - EXPECT_TRUE(ret); + CHECK(ret); std::vector print_cycle = {&top, &bottom, &middle, &top}; - EXPECT_EQ(print_cycle, cycle); - EXPECT_EQ("Top->Middle->Bottom->Top", cycle::PrintCycle(cycle)); + CHECK(cycle == print_cycle); + CHECK(cycle::PrintCycle(cycle) == "Top->Middle->Bottom->Top"); } // Test gate type validation. -TEST(FormulaTest, Validate) { +TEST_CASE("FormulaTest.Validate", "[mef::event]") { FormulaPtr top(new Formula(kAnd)); BasicEvent arg_one("a"); BasicEvent arg_two("b"); BasicEvent arg_three("c"); // AND Formula tests. - EXPECT_THROW(top->Validate(), ValidityError); + CHECK_THROWS_AS(top->Validate(), ValidityError); top->AddArgument(&arg_one); - EXPECT_THROW(top->Validate(), ValidityError); + CHECK_THROWS_AS(top->Validate(), ValidityError); top->AddArgument(&arg_two); - EXPECT_NO_THROW(top->Validate()); + CHECK_NOTHROW(top->Validate()); top->AddArgument(&arg_three); - EXPECT_NO_THROW(top->Validate()); + CHECK_NOTHROW(top->Validate()); // OR Formula tests. top = FormulaPtr(new Formula(kOr)); - EXPECT_THROW(top->Validate(), ValidityError); + CHECK_THROWS_AS(top->Validate(), ValidityError); top->AddArgument(&arg_one); - EXPECT_THROW(top->Validate(), ValidityError); + CHECK_THROWS_AS(top->Validate(), ValidityError); top->AddArgument(&arg_two); - EXPECT_NO_THROW(top->Validate()); + CHECK_NOTHROW(top->Validate()); top->AddArgument(&arg_three); - EXPECT_NO_THROW(top->Validate()); + CHECK_NOTHROW(top->Validate()); // NOT Formula tests. top = FormulaPtr(new Formula(kNot)); - EXPECT_THROW(top->Validate(), ValidityError); + CHECK_THROWS_AS(top->Validate(), ValidityError); top->AddArgument(&arg_one); - EXPECT_NO_THROW(top->Validate()); + CHECK_NOTHROW(top->Validate()); top->AddArgument(&arg_two); - EXPECT_THROW(top->Validate(), ValidityError); + CHECK_THROWS_AS(top->Validate(), ValidityError); // NULL Formula tests. top = FormulaPtr(new Formula(kNull)); - EXPECT_THROW(top->Validate(), ValidityError); + CHECK_THROWS_AS(top->Validate(), ValidityError); top->AddArgument(&arg_one); - EXPECT_NO_THROW(top->Validate()); + CHECK_NOTHROW(top->Validate()); top->AddArgument(&arg_two); - EXPECT_THROW(top->Validate(), ValidityError); + CHECK_THROWS_AS(top->Validate(), ValidityError); // NOR Formula tests. top = FormulaPtr(new Formula(kNor)); - EXPECT_THROW(top->Validate(), ValidityError); + CHECK_THROWS_AS(top->Validate(), ValidityError); top->AddArgument(&arg_one); - EXPECT_THROW(top->Validate(), ValidityError); + CHECK_THROWS_AS(top->Validate(), ValidityError); top->AddArgument(&arg_two); - EXPECT_NO_THROW(top->Validate()); + CHECK_NOTHROW(top->Validate()); top->AddArgument(&arg_three); - EXPECT_NO_THROW(top->Validate()); + CHECK_NOTHROW(top->Validate()); // NAND Formula tests. top = FormulaPtr(new Formula(kNand)); - EXPECT_THROW(top->Validate(), ValidityError); + CHECK_THROWS_AS(top->Validate(), ValidityError); top->AddArgument(&arg_one); - EXPECT_THROW(top->Validate(), ValidityError); + CHECK_THROWS_AS(top->Validate(), ValidityError); top->AddArgument(&arg_two); - EXPECT_NO_THROW(top->Validate()); + CHECK_NOTHROW(top->Validate()); top->AddArgument(&arg_three); - EXPECT_NO_THROW(top->Validate()); + CHECK_NOTHROW(top->Validate()); // XOR Formula tests. top = FormulaPtr(new Formula(kXor)); - EXPECT_THROW(top->Validate(), ValidityError); + CHECK_THROWS_AS(top->Validate(), ValidityError); top->AddArgument(&arg_one); - EXPECT_THROW(top->Validate(), ValidityError); + CHECK_THROWS_AS(top->Validate(), ValidityError); top->AddArgument(&arg_two); - EXPECT_NO_THROW(top->Validate()); + CHECK_NOTHROW(top->Validate()); top->AddArgument(&arg_three); - EXPECT_THROW(top->Validate(), ValidityError); + CHECK_THROWS_AS(top->Validate(), ValidityError); // VOTE/ATLEAST formula tests. top = FormulaPtr(new Formula(kVote)); top->vote_number(2); - EXPECT_THROW(top->Validate(), ValidityError); + CHECK_THROWS_AS(top->Validate(), ValidityError); top->AddArgument(&arg_one); - EXPECT_THROW(top->Validate(), ValidityError); + CHECK_THROWS_AS(top->Validate(), ValidityError); top->AddArgument(&arg_two); - EXPECT_THROW(top->Validate(), ValidityError); + CHECK_THROWS_AS(top->Validate(), ValidityError); top->AddArgument(&arg_three); - EXPECT_NO_THROW(top->Validate()); + CHECK_NOTHROW(top->Validate()); } -TEST(MEFGateTest, Inhibit) { +TEST_CASE("MEFGateTest.Inhibit", "[mef::event]") { BasicEvent arg_one("a"); BasicEvent arg_two("b"); BasicEvent arg_three("c"); @@ -241,14 +239,14 @@ GatePtr top(new Gate("top")); top->formula(FormulaPtr(new Formula(kAnd))); top->AddAttribute(inh_attr); - EXPECT_THROW(top->Validate(), ValidityError); + CHECK_THROWS_AS(top->Validate(), ValidityError); top->formula().AddArgument(&arg_one); - EXPECT_THROW(top->Validate(), ValidityError); + CHECK_THROWS_AS(top->Validate(), ValidityError); top->formula().AddArgument(&arg_two); - EXPECT_THROW(top->Validate(), ValidityError); + CHECK_THROWS_AS(top->Validate(), ValidityError); top->formula().AddArgument(&arg_three); - EXPECT_THROW(top->Validate(), ValidityError); + CHECK_THROWS_AS(top->Validate(), ValidityError); top = GatePtr(new Gate("top")); top->formula(FormulaPtr(new Formula(kAnd))); @@ -260,22 +258,20 @@ arg_three.AddAttribute(cond); top->formula().AddArgument(&arg_one); // Basic event. top->formula().AddArgument(&arg_three); // Conditional event. - EXPECT_NO_THROW(top->Validate()); + CHECK_NOTHROW(top->Validate()); arg_one.AddAttribute(cond); - EXPECT_THROW(top->Validate(), ValidityError); + CHECK_THROWS_AS(top->Validate(), ValidityError); } -TEST(PrimaryEventTest, HouseProbability) { +TEST_CASE("PrimaryEventTest.HouseProbability", "[mef::event]") { // House primary event. HouseEventPtr primary(new HouseEvent("valve")); - EXPECT_FALSE(primary->state()); // Default state. + CHECK_FALSE(primary->state()); // Default state. // Setting with a valid values. - EXPECT_NO_THROW(primary->state(true)); - EXPECT_TRUE(primary->state()); - EXPECT_NO_THROW(primary->state(false)); - EXPECT_FALSE(primary->state()); + CHECK_NOTHROW(primary->state(true)); + CHECK(primary->state()); + CHECK_NOTHROW(primary->state(false)); + CHECK_FALSE(primary->state()); } -} // namespace test -} // namespace mef -} // namespace scram +} // namespace scram::mef::test diff -Nru scram-0.16.1/tests/expression_tests.cc scram-0.16.2/tests/expression_tests.cc --- scram-0.16.1/tests/expression_tests.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/expression_tests.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,13 +24,15 @@ #include "expression/random_deviate.h" #include "parameter.h" -#include +#include #include "error.h" -namespace scram { -namespace mef { -namespace test { +#define EXPECT_DOUBLE_EQ(expected, value) CHECK((value) == Approx(expected)) +#define EXPECT_NEAR(expected, value, delta) \ + CHECK((value) == Approx(expected).margin(delta)) + +namespace scram::mef::test { // This mock class is used to specify // return values and samples in a hard coded way. @@ -60,117 +62,117 @@ void TestProbability(Expression* expr, OpenExpression* arg, bool sample = true) { - ASSERT_NO_THROW(expr->Validate()); + REQUIRE_NOTHROW(expr->Validate()); double value = arg->mean; arg->mean = -1; - EXPECT_THROW(expr->Validate(), DomainError); + CHECK_THROWS_AS(expr->Validate(), DomainError); arg->mean = 0.0; - EXPECT_NO_THROW(expr->Validate()); + CHECK_NOTHROW(expr->Validate()); arg->mean = 2; - EXPECT_THROW(expr->Validate(), DomainError); + CHECK_THROWS_AS(expr->Validate(), DomainError); arg->mean = value; - ASSERT_NO_THROW(expr->Validate()); + REQUIRE_NOTHROW(expr->Validate()); if (!sample) return; double sample_value = arg->sample; arg->sample = -1; - EXPECT_THROW(expr->Validate(), DomainError); + CHECK_THROWS_AS(expr->Validate(), DomainError); arg->sample = 0.0; - EXPECT_NO_THROW(expr->Validate()); + CHECK_NOTHROW(expr->Validate()); arg->sample = 2; - EXPECT_THROW(expr->Validate(), DomainError); + CHECK_THROWS_AS(expr->Validate(), DomainError); arg->sample = sample_value; - ASSERT_NO_THROW(expr->Validate()); + REQUIRE_NOTHROW(expr->Validate()); } void TestNegative(Expression* expr, OpenExpression* arg, bool sample = true) { - ASSERT_NO_THROW(expr->Validate()); + REQUIRE_NOTHROW(expr->Validate()); double value = arg->mean; arg->mean = -1; - EXPECT_THROW(expr->Validate(), DomainError); + CHECK_THROWS_AS(expr->Validate(), DomainError); arg->mean = 0.0; - EXPECT_NO_THROW(expr->Validate()); + CHECK_NOTHROW(expr->Validate()); arg->mean = 100; - EXPECT_NO_THROW(expr->Validate()); + CHECK_NOTHROW(expr->Validate()); arg->mean = value; - ASSERT_NO_THROW(expr->Validate()); + REQUIRE_NOTHROW(expr->Validate()); if (!sample) return; double sample_value = arg->sample; arg->sample = -1; - EXPECT_THROW(expr->Validate(), DomainError); + CHECK_THROWS_AS(expr->Validate(), DomainError); arg->sample = 0.0; - EXPECT_NO_THROW(expr->Validate()); + CHECK_NOTHROW(expr->Validate()); arg->sample = 100; - EXPECT_NO_THROW(expr->Validate()); + CHECK_NOTHROW(expr->Validate()); arg->sample = sample_value; - ASSERT_NO_THROW(expr->Validate()); + REQUIRE_NOTHROW(expr->Validate()); } void TestNonPositive(Expression* expr, OpenExpression* arg, bool sample = true) { - ASSERT_NO_THROW(expr->Validate()); + REQUIRE_NOTHROW(expr->Validate()); double value = arg->mean; arg->mean = -1; - EXPECT_THROW(expr->Validate(), DomainError); + CHECK_THROWS_AS(expr->Validate(), DomainError); arg->mean = 0.0; - EXPECT_THROW(expr->Validate(), DomainError); + CHECK_THROWS_AS(expr->Validate(), DomainError); arg->mean = 100; - EXPECT_NO_THROW(expr->Validate()); + CHECK_NOTHROW(expr->Validate()); arg->mean = value; - ASSERT_NO_THROW(expr->Validate()); + REQUIRE_NOTHROW(expr->Validate()); if (!sample) return; double sample_value = arg->sample; arg->sample = -1; - EXPECT_THROW(expr->Validate(), DomainError); + CHECK_THROWS_AS(expr->Validate(), DomainError); arg->sample = 0.0; - EXPECT_THROW(expr->Validate(), DomainError); + CHECK_THROWS_AS(expr->Validate(), DomainError); arg->sample = 100; - EXPECT_NO_THROW(expr->Validate()); + CHECK_NOTHROW(expr->Validate()); arg->sample = sample_value; - ASSERT_NO_THROW(expr->Validate()); + REQUIRE_NOTHROW(expr->Validate()); } } // namespace -TEST(ExpressionTest, Parameter) { +TEST_CASE("ExpressionTest.Parameter", "[mef::expression]") { OpenExpression expr(10, 8); ParameterPtr param; - ASSERT_NO_THROW(param = ParameterPtr(new Parameter("param"))); - ASSERT_NO_THROW(param->expression(&expr)); - ASSERT_THROW(param->expression(&expr), LogicError); + REQUIRE_NOTHROW(param = ParameterPtr(new Parameter("param"))); + REQUIRE_NOTHROW(param->expression(&expr)); + REQUIRE_THROWS_AS(param->expression(&expr), LogicError); } -TEST(ExpressionTest, Exponential) { +TEST_CASE("ExpressionTest.Exponential", "[mef::expression]") { OpenExpression lambda(10, 8); OpenExpression time(5, 4); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&lambda, &time)); + REQUIRE_NOTHROW(dev = std::make_unique(&lambda, &time)); EXPECT_DOUBLE_EQ(1 - std::exp(-50), dev->value()); TestNegative(dev.get(), &lambda); TestNegative(dev.get(), &time); double sampled_value = 0; - ASSERT_NO_THROW(sampled_value = dev->Sample()); - EXPECT_EQ(sampled_value, dev->Sample()); // Resampling without resetting. - ASSERT_FALSE(dev->IsDeviate()); + REQUIRE_NOTHROW(sampled_value = dev->Sample()); + CHECK(dev->Sample() == sampled_value); // Resampling without resetting. + REQUIRE_FALSE(dev->IsDeviate()); } -TEST(ExpressionTest, GLM) { +TEST_CASE("ExpressionTest.GLM", "[mef::expression]") { OpenExpression gamma(0.10, 0.8); OpenExpression lambda(10, 8); OpenExpression mu(100, 80); OpenExpression time(5, 4); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&gamma, &lambda, &mu, &time)); + REQUIRE_NOTHROW(dev = std::make_unique(&gamma, &lambda, &mu, &time)); EXPECT_DOUBLE_EQ((10 - (10 - 0.10 * 110) * std::exp(-110 * 5)) / 110, dev->value()); @@ -180,18 +182,18 @@ TestNegative(dev.get(), &time); double sampled_value = 0; - ASSERT_NO_THROW(sampled_value = dev->Sample()); - EXPECT_EQ(sampled_value, dev->Sample()); // Re-sampling without resetting. - ASSERT_FALSE(dev->IsDeviate()); + REQUIRE_NOTHROW(sampled_value = dev->Sample()); + CHECK(dev->Sample() == sampled_value); // Re-sampling without resetting. + REQUIRE_FALSE(dev->IsDeviate()); } -TEST(ExpressionTest, Weibull) { +TEST_CASE("ExpressionTest.Weibull", "[mef::expression]") { OpenExpression alpha(0.10, 0.8); OpenExpression beta(10, 8); OpenExpression t0(10, 10); OpenExpression time(500, 500); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&alpha, &beta, &t0, &time)); + REQUIRE_NOTHROW(dev = std::make_unique(&alpha, &beta, &t0, &time)); EXPECT_DOUBLE_EQ(1 - std::exp(-std::pow(40 / 0.1, 10)), dev->value()); TestNonPositive(dev.get(), &alpha); @@ -200,25 +202,25 @@ TestNegative(dev.get(), &time); t0.mean = 1000; // More than the mission time. - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); t0.mean = 10; - ASSERT_NO_THROW(dev->Validate()); + REQUIRE_NOTHROW(dev->Validate()); t0.sample = 1000; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); double sampled_value = 0; - ASSERT_FALSE(dev->IsDeviate()); - ASSERT_NO_THROW(sampled_value = dev->Sample()); - EXPECT_EQ(sampled_value, dev->Sample()); // Resampling without resetting. + REQUIRE_FALSE(dev->IsDeviate()); + REQUIRE_NOTHROW(sampled_value = dev->Sample()); + CHECK(dev->Sample() == sampled_value); // Resampling without resetting. } -TEST(ExpressionTest, PeriodicTest4) { +TEST_CASE("ExpressionTest.PeriodicTest4", "[mef::expression]") { OpenExpression lambda(0.10, 0.10); OpenExpression tau(1, 1); OpenExpression theta(2, 2); OpenExpression time(5, 5); std::unique_ptr dev; - ASSERT_NO_THROW( + REQUIRE_NOTHROW( dev = std::make_unique(&lambda, &tau, &theta, &time)); EXPECT_DOUBLE_EQ(1 - std::exp(-0.10), dev->value()); @@ -228,24 +230,24 @@ TestNegative(dev.get(), &time); double sampled_value = 0; - ASSERT_NO_THROW(sampled_value = dev->Sample()); - EXPECT_EQ(sampled_value, dev->Sample()); // Resampling without resetting. - ASSERT_FALSE(dev->IsDeviate()); + REQUIRE_NOTHROW(sampled_value = dev->Sample()); + CHECK(dev->Sample() == sampled_value); // Resampling without resetting. + REQUIRE_FALSE(dev->IsDeviate()); } -TEST(ExpressionTest, PeriodicTest5) { +TEST_CASE("ExpressionTest.PeriodicTest5", "[mef::expression]") { OpenExpression lambda(7e-4, 7e-4); OpenExpression mu(4e-4, 4e-4); OpenExpression tau(4020, 4020); OpenExpression theta(4740, 4740); OpenExpression time(8760, 8760); std::unique_ptr dev; - ASSERT_NO_THROW( + REQUIRE_NOTHROW( dev = std::make_unique(&lambda, &mu, &tau, &theta, &time)); - EXPECT_FALSE(dev->IsDeviate()); + CHECK_FALSE(dev->IsDeviate()); TestNegative(dev.get(), &mu); - EXPECT_EQ(dev->value(), dev->Sample()); + CHECK(dev->Sample() == dev->value()); EXPECT_NEAR(0.817508, dev->value(), 1e-5); tau.mean = 2010; @@ -264,7 +266,7 @@ EXPECT_NEAR(0.997828, dev->value(), 1e-5); } -TEST(ExpressionTest, PeriodicTest11) { +TEST_CASE("ExpressionTest.PeriodicTest11", "[mef::expression]") { OpenExpression lambda(7e-4, 7e-4); OpenExpression lambda_test(6e-4, 6e-4); OpenExpression mu(4e-4, 4e-4); @@ -277,11 +279,11 @@ OpenExpression omega(0.01, 0.01); OpenExpression time(8760, 8760); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique( + REQUIRE_NOTHROW(dev = std::make_unique( &lambda, &lambda_test, &mu, &tau, &theta, &gamma, &test_duration, &available_at_test, &sigma, &omega, &time)); - EXPECT_FALSE(dev->IsDeviate()); + CHECK_FALSE(dev->IsDeviate()); TestNegative(dev.get(), &lambda_test); TestNonPositive(dev.get(), &test_duration); TestProbability(dev.get(), &gamma); @@ -292,7 +294,7 @@ available_at_test.mean = false; EXPECT_NEAR(0.668316, dev->value(), 1e-5); time.mean = 4750; - EXPECT_EQ(1, dev->value()); + CHECK(dev->value() == 1); time.mean = 4870; EXPECT_NEAR(0.996715, dev->value(), 1e-5); time.mean = 8710; @@ -320,200 +322,200 @@ } // Uniform deviate test for invalid minimum and maximum values. -TEST(ExpressionTest, UniformDeviate) { +TEST_CASE("ExpressionTest.UniformDeviate", "[mef::expression]") { OpenExpression min(1, 2); OpenExpression max(5, 4); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&min, &max)); + REQUIRE_NOTHROW(dev = std::make_unique(&min, &max)); EXPECT_DOUBLE_EQ(3, dev->value()); min.mean = 10; - EXPECT_THROW(dev->Validate(), ValidityError); + CHECK_THROWS_AS(dev->Validate(), ValidityError); min.mean = 1; - ASSERT_NO_THROW(dev->Validate()); + REQUIRE_NOTHROW(dev->Validate()); - ASSERT_NO_THROW(dev->Validate()); + REQUIRE_NOTHROW(dev->Validate()); min.sample = 10; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); min.sample = 1; - ASSERT_NO_THROW(dev->Validate()); + REQUIRE_NOTHROW(dev->Validate()); double sampled_value = 0; - ASSERT_TRUE(dev->IsDeviate()); - ASSERT_NO_THROW(sampled_value = dev->Sample()); - EXPECT_EQ(sampled_value, dev->Sample()); // Re-sampling without resetting. - ASSERT_NO_THROW(dev->Reset()); - EXPECT_NE(sampled_value, dev->Sample()); + REQUIRE(dev->IsDeviate()); + REQUIRE_NOTHROW(sampled_value = dev->Sample()); + CHECK(dev->Sample() == sampled_value); // Re-sampling without resetting. + REQUIRE_NOTHROW(dev->Reset()); + CHECK_FALSE(dev->Sample() == sampled_value); } // Normal deviate test for invalid standard deviation. -TEST(ExpressionTest, NormalDeviate) { +TEST_CASE("ExpressionTest.NormalDeviate", "[mef::expression]") { OpenExpression mean(10, 1); OpenExpression sigma(5, 4); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&mean, &sigma)); + REQUIRE_NOTHROW(dev = std::make_unique(&mean, &sigma)); - ASSERT_NO_THROW(dev->Validate()); + REQUIRE_NOTHROW(dev->Validate()); mean.mean = 2; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); mean.mean = 0; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); mean.mean = 10; - ASSERT_NO_THROW(dev->Validate()); + REQUIRE_NOTHROW(dev->Validate()); TestNonPositive(dev.get(), &sigma, /*sample=*/false); double sampled_value = 0; - ASSERT_TRUE(dev->IsDeviate()); - ASSERT_NO_THROW(sampled_value = dev->Sample()); - EXPECT_EQ(sampled_value, dev->Sample()); // Re-sampling without resetting. - ASSERT_NO_THROW(dev->Reset()); - EXPECT_NE(sampled_value, dev->Sample()); + REQUIRE(dev->IsDeviate()); + REQUIRE_NOTHROW(sampled_value = dev->Sample()); + CHECK(dev->Sample() == sampled_value); // Re-sampling without resetting. + REQUIRE_NOTHROW(dev->Reset()); + CHECK_FALSE(dev->Sample() == sampled_value); } // Log-Normal deviate test for invalid mean, error factor, and level. -TEST(ExpressionTest, LognormalDeviateLogarithmic) { +TEST_CASE("ExpressionTest.LognormalDeviateLogarithmic", "[mef::expression]") { OpenExpression mean(10, 5); OpenExpression ef(5, 3); OpenExpression level(0.95, 0.95, 0.6, 0.9); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&mean, &ef, &level)); + REQUIRE_NOTHROW(dev = std::make_unique(&mean, &ef, &level)); - EXPECT_EQ(mean.value(), dev->value()); - EXPECT_EQ(0, dev->interval().lower()); - EXPECT_EQ(IntervalBounds::left_open(), dev->interval().bounds()); + CHECK(dev->value() == mean.value()); + CHECK(dev->interval().lower() == 0); + CHECK(dev->interval().bounds() == IntervalBounds::left_open()); level.mean = 0; - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); level.mean = 2; - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); level.mean = 0.95; TestNonPositive(dev.get(), &mean, /*sample=*/false); ef.mean = -1; // ef < 0 - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); ef.mean = 1; // ef = 0 - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); ef.mean = 2; - ASSERT_NO_THROW(dev->Validate()); + REQUIRE_NOTHROW(dev->Validate()); - ASSERT_NO_THROW(dev->Validate()); + REQUIRE_NOTHROW(dev->Validate()); ef.sample = 1; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); ef.sample = -1; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); ef.sample = 3; - ASSERT_NO_THROW(dev->Validate()); + REQUIRE_NOTHROW(dev->Validate()); double sampled_value = 0; - ASSERT_TRUE(dev->IsDeviate()); - ASSERT_NO_THROW(sampled_value = dev->Sample()); - EXPECT_EQ(sampled_value, dev->Sample()); // Re-sampling without resetting. - ASSERT_NO_THROW(dev->Reset()); - EXPECT_NE(sampled_value, dev->Sample()); + REQUIRE(dev->IsDeviate()); + REQUIRE_NOTHROW(sampled_value = dev->Sample()); + CHECK(dev->Sample() == sampled_value); // Re-sampling without resetting. + REQUIRE_NOTHROW(dev->Reset()); + CHECK_FALSE(dev->Sample() == sampled_value); } // Log-Normal deviate with invalid normal mean and standard deviation. -TEST(ExpressionTest, LognormalDeviateNormal) { +TEST_CASE("ExpressionTest.LognormalDeviateNormal", "[mef::expression]") { OpenExpression mu(10, 1); OpenExpression sigma(5, 4); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&mu, &sigma)); + REQUIRE_NOTHROW(dev = std::make_unique(&mu, &sigma)); EXPECT_NEAR(5.9105e9, dev->value(), 1e6); - EXPECT_EQ(0, dev->interval().lower()); - EXPECT_EQ(IntervalBounds::left_open(), dev->interval().bounds()); + CHECK(dev->interval().lower() == 0); + CHECK(dev->interval().bounds() == IntervalBounds::left_open()); - ASSERT_NO_THROW(dev->Validate()); + REQUIRE_NOTHROW(dev->Validate()); mu.mean = 2; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); mu.mean = 0; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); mu.mean = 10; - ASSERT_NO_THROW(dev->Validate()); + REQUIRE_NOTHROW(dev->Validate()); TestNonPositive(dev.get(), &sigma, /*sample=*/false); - ASSERT_NO_THROW(dev->Validate()); + REQUIRE_NOTHROW(dev->Validate()); double sampled_value = 0; - ASSERT_TRUE(dev->IsDeviate()); - ASSERT_NO_THROW(sampled_value = dev->Sample()); - EXPECT_EQ(sampled_value, dev->Sample()); // Re-sampling without resetting. - ASSERT_NO_THROW(dev->Reset()); - EXPECT_NE(sampled_value, dev->Sample()); + REQUIRE(dev->IsDeviate()); + REQUIRE_NOTHROW(sampled_value = dev->Sample()); + CHECK(dev->Sample() == sampled_value); // Re-sampling without resetting. + REQUIRE_NOTHROW(dev->Reset()); + CHECK_FALSE(dev->Sample() == sampled_value); } // Gamma deviate test for invalid arguments. -TEST(ExpressionTest, GammaDeviate) { +TEST_CASE("ExpressionTest.GammaDeviate", "[mef::expression]") { OpenExpression k(3, 5); OpenExpression theta(7, 1); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&k, &theta)); + REQUIRE_NOTHROW(dev = std::make_unique(&k, &theta)); EXPECT_DOUBLE_EQ(21, dev->value()); TestNonPositive(dev.get(), &k, /*sample=*/false); TestNonPositive(dev.get(), &theta, /*sample=*/false); - ASSERT_NO_THROW(dev->Validate()); + REQUIRE_NOTHROW(dev->Validate()); k.sample = -1; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); k.sample = 0; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); k.sample = 1; - ASSERT_NO_THROW(dev->Validate()); + REQUIRE_NOTHROW(dev->Validate()); theta.sample = -1; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); theta.sample = 0; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); theta.sample = 1; - ASSERT_NO_THROW(dev->Validate()); + REQUIRE_NOTHROW(dev->Validate()); double sampled_value = 0; - ASSERT_TRUE(dev->IsDeviate()); - ASSERT_NO_THROW(sampled_value = dev->Sample()); - EXPECT_EQ(sampled_value, dev->Sample()); // Re-sampling without resetting. - ASSERT_NO_THROW(dev->Reset()); - EXPECT_NE(sampled_value, dev->Sample()); + REQUIRE(dev->IsDeviate()); + REQUIRE_NOTHROW(sampled_value = dev->Sample()); + CHECK(dev->Sample() == sampled_value); // Re-sampling without resetting. + REQUIRE_NOTHROW(dev->Reset()); + CHECK_FALSE(dev->Sample() == sampled_value); } // Beta deviate test for invalid arguments. -TEST(ExpressionTest, BetaDeviate) { +TEST_CASE("ExpressionTest.BetaDeviate", "[mef::expression]") { OpenExpression alpha(8, 5); OpenExpression beta(2, 1); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&alpha, &beta)); - EXPECT_DOUBLE_EQ(0.8, dev->value()); + REQUIRE_NOTHROW(dev = std::make_unique(&alpha, &beta)); + CHECK(dev->value() == Approx(0.8)); TestNonPositive(dev.get(), &alpha, /*sample=*/false); TestNonPositive(dev.get(), &beta, /*sample=*/false); - ASSERT_NO_THROW(dev->Validate()); + REQUIRE_NOTHROW(dev->Validate()); alpha.sample = -1; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); alpha.sample = 0; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); alpha.sample = 1; - ASSERT_NO_THROW(dev->Validate()); + REQUIRE_NOTHROW(dev->Validate()); beta.sample = -1; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); beta.sample = 0; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); beta.sample = 1; - ASSERT_NO_THROW(dev->Validate()); + REQUIRE_NOTHROW(dev->Validate()); double sampled_value = 0; - ASSERT_TRUE(dev->IsDeviate()); - ASSERT_NO_THROW(sampled_value = dev->Sample()); - EXPECT_EQ(sampled_value, dev->Sample()); // Re-sampling without resetting. - ASSERT_NO_THROW(dev->Reset()); - EXPECT_NE(sampled_value, dev->Sample()); + REQUIRE(dev->IsDeviate()); + REQUIRE_NOTHROW(sampled_value = dev->Sample()); + CHECK(dev->Sample() == sampled_value); // Re-sampling without resetting. + REQUIRE_NOTHROW(dev->Reset()); + CHECK_FALSE(dev->Sample() == sampled_value); } // Test for histogram distribution arguments and sampling. -TEST(ExpressionTest, Histogram) { +TEST_CASE("ExpressionTest.Histogram", "[mef::expression]") { std::vector boundaries; std::vector weights; OpenExpression b0(0, 0); @@ -530,172 +532,176 @@ // Size mismatch. weights.push_back(&w3); - EXPECT_THROW(Histogram(boundaries, weights), ValidityError); + CHECK_THROWS_AS(Histogram(boundaries, weights), ValidityError); weights.pop_back(); - ASSERT_NO_THROW(Histogram(boundaries, weights)); + REQUIRE_NOTHROW(Histogram(boundaries, weights)); auto dev = std::make_unique(boundaries, weights); - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); b0.mean = 0.5; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); b0.mean = 0; - EXPECT_DOUBLE_EQ(1.5, dev->value()); + CHECK(dev->value() == Approx(1.5)); b1.mean = -1; - EXPECT_THROW(dev->Validate(), ValidityError); + CHECK_THROWS_AS(dev->Validate(), ValidityError); b1.mean = 0; - EXPECT_THROW(dev->Validate(), ValidityError); + CHECK_THROWS_AS(dev->Validate(), ValidityError); b1.mean = b2.mean; - EXPECT_THROW(dev->Validate(), ValidityError); + CHECK_THROWS_AS(dev->Validate(), ValidityError); b1.mean = b2.mean + 1; - EXPECT_THROW(dev->Validate(), ValidityError); + CHECK_THROWS_AS(dev->Validate(), ValidityError); b1.mean = 1; - ASSERT_NO_THROW(dev->Validate()); + REQUIRE_NOTHROW(dev->Validate()); w1.mean = -1; - EXPECT_THROW(dev->Validate(), ValidityError); + CHECK_THROWS_AS(dev->Validate(), ValidityError); w1.mean = 2; - ASSERT_NO_THROW(dev->Validate()); + REQUIRE_NOTHROW(dev->Validate()); - ASSERT_NO_THROW(dev->Validate()); + REQUIRE_NOTHROW(dev->Validate()); b1.sample = -1; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); b1.sample = 0; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); b1.sample = b2.sample; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); b1.sample = b2.sample + 1; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); b1.sample = 1; - ASSERT_NO_THROW(dev->Validate()); + REQUIRE_NOTHROW(dev->Validate()); w1.sample = -1; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); w1.sample = 2; - ASSERT_NO_THROW(dev->Validate()); + REQUIRE_NOTHROW(dev->Validate()); double sampled_value = 0; - ASSERT_TRUE(dev->IsDeviate()); - ASSERT_NO_THROW(sampled_value = dev->Sample()); - EXPECT_EQ(sampled_value, dev->Sample()); // Re-sampling without resetting. - ASSERT_NO_THROW(dev->Reset()); - EXPECT_NE(sampled_value, dev->Sample()); + REQUIRE(dev->IsDeviate()); + REQUIRE_NOTHROW(sampled_value = dev->Sample()); + CHECK(dev->Sample() == sampled_value); // Re-sampling without resetting. + REQUIRE_NOTHROW(dev->Reset()); + CHECK_FALSE(dev->Sample() == sampled_value); } // Test for negation of an expression. -TEST(ExpressionTest, Neg) { +TEST_CASE("ExpressionTest.Neg", "[mef::expression]") { OpenExpression expression(10, 8); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&expression)); - EXPECT_DOUBLE_EQ(-10, dev->value()); - EXPECT_DOUBLE_EQ(-8, dev->Sample()); + REQUIRE_NOTHROW(dev = std::make_unique(&expression)); + CHECK(dev->value() == -10); + CHECK(dev->Sample() == -8); expression.max = 100; expression.min = 1; - EXPECT_TRUE(Interval::closed(-100, -1) == dev->interval()) << dev->interval(); + INFO(dev->interval()); + CHECK(Interval::closed(-100, -1) == dev->interval()); } // Test expression initialization with 2 or more arguments. -TEST(ExpressionTest, BinaryExpression) { +TEST_CASE("ExpressionTest.BinaryExpression", "[mef::expression]") { std::vector arguments; - EXPECT_THROW(Add{arguments}, ValidityError); + CHECK_THROWS_AS(Add{arguments}, ValidityError); OpenExpression arg_one(10, 20); arguments.push_back(&arg_one); - EXPECT_THROW(Add{arguments}, ValidityError); + CHECK_THROWS_AS(Add{arguments}, ValidityError); OpenExpression arg_two(30, 40); arguments.push_back(&arg_two); - EXPECT_NO_THROW(Add{arguments}); + CHECK_NOTHROW(Add{arguments}); arguments.push_back(&arg_two); - EXPECT_NO_THROW(Add{arguments}); + CHECK_NOTHROW(Add{arguments}); } // Test for addition of expressions. -TEST(ExpressionTest, Add) { +TEST_CASE("ExpressionTest.Add", "[mef::expression]") { OpenExpression arg_one(10, 20); OpenExpression arg_two(30, 40); OpenExpression arg_three(50, 60); std::unique_ptr dev; - ASSERT_NO_THROW(dev = MakeUnique({&arg_one, &arg_two, &arg_three})); - EXPECT_DOUBLE_EQ(90, dev->value()); - EXPECT_DOUBLE_EQ(120, dev->Sample()); - EXPECT_TRUE(Interval::closed(120, 120) == dev->interval()) << dev->interval(); + REQUIRE_NOTHROW(dev = MakeUnique({&arg_one, &arg_two, &arg_three})); + CHECK(dev->value() == 90); + CHECK(dev->Sample() == 120); + INFO(dev->interval()); + CHECK(Interval::closed(120, 120) == dev->interval()); } // Test for subtraction of expressions. -TEST(ExpressionTest, Sub) { +TEST_CASE("ExpressionTest.Sub", "[mef::expression]") { OpenExpression arg_one(10, 20); OpenExpression arg_two(30, 40); OpenExpression arg_three(50, 60); std::unique_ptr dev; - ASSERT_NO_THROW(dev = MakeUnique({&arg_one, &arg_two, &arg_three})); - EXPECT_DOUBLE_EQ(-70, dev->value()); - EXPECT_DOUBLE_EQ(-80, dev->Sample()); - EXPECT_TRUE(Interval::closed(-80, -80) == dev->interval()) << dev->interval(); + REQUIRE_NOTHROW(dev = MakeUnique({&arg_one, &arg_two, &arg_three})); + CHECK(dev->value() == -70); + CHECK(dev->Sample() == -80); + INFO(dev->interval()); + CHECK(Interval::closed(-80, -80) == dev->interval()); } // Test for multiplication of expressions. -TEST(ExpressionTest, Mul) { +TEST_CASE("ExpressionTest.Mul", "[mef::expression]") { OpenExpression arg_one(1, 2, 0.1, 10); OpenExpression arg_two(3, 4, 1, 5); OpenExpression arg_three(5, 6, 2, 6); std::unique_ptr dev; - ASSERT_NO_THROW(dev = MakeUnique({&arg_one, &arg_two, &arg_three})); - EXPECT_DOUBLE_EQ(15, dev->value()); - EXPECT_DOUBLE_EQ(48, dev->Sample()); - EXPECT_TRUE(Interval::closed(0.2, 300) == dev->interval()) << dev->interval(); + REQUIRE_NOTHROW(dev = MakeUnique({&arg_one, &arg_two, &arg_three})); + CHECK(dev->value() == 15); + CHECK(dev->Sample() == 48); + INFO(dev->interval()); + CHECK(Interval::closed(0.2, 300) == dev->interval()); } // Test for the special case of finding maximum and minimum multiplication. -TEST(ExpressionTest, MultiplicationMaxAndMin) { +TEST_CASE("ExpressionTest.MultiplicationMaxAndMin", "[mef::expression]") { OpenExpression arg_one(1, 2, -1, 2); OpenExpression arg_two(3, 4, -7, -4); OpenExpression arg_three(5, 6, 1, 5); OpenExpression arg_four(4, 3, -2, 4); std::unique_ptr dev; - ASSERT_NO_THROW( + REQUIRE_NOTHROW( dev = MakeUnique({&arg_one, &arg_two, &arg_three, &arg_four})); - EXPECT_DOUBLE_EQ(60, dev->value()); - EXPECT_DOUBLE_EQ(144, dev->Sample()); - EXPECT_TRUE(Interval::closed(-280, 140) == dev->interval()) - << dev->interval(); + CHECK(dev->value() == 60); + CHECK(dev->Sample() == 144); + INFO(dev->interval()); + CHECK(Interval::closed(-280, 140) == dev->interval()); } // Test for division of expressions. -TEST(ExpressionTest, Div) { +TEST_CASE("ExpressionTest.Div", "[mef::expression]") { OpenExpression arg_one(1, 2, 0.1, 10); OpenExpression arg_two(3, 4, 1, 5); OpenExpression arg_three(5, 6, 2, 6); std::unique_ptr dev; - ASSERT_NO_THROW(dev = MakeUnique
({&arg_one, &arg_two, &arg_three})); + REQUIRE_NOTHROW(dev = MakeUnique
({&arg_one, &arg_two, &arg_three})); EXPECT_DOUBLE_EQ(1.0 / 3 / 5, dev->value()); EXPECT_DOUBLE_EQ(2.0 / 4 / 6, dev->Sample()); - EXPECT_TRUE(Interval::closed(0.1 / 5 / 6, 10.0 / 1 / 2) == dev->interval()) - << dev->interval(); + INFO(dev->interval()); + CHECK(Interval::closed(0.1 / 5 / 6, 10.0 / 1 / 2) == dev->interval()); arg_two.mean = 0; // Division by 0. - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); } // Test for the special case of finding maximum and minimum division. -TEST(ExpressionTest, DivisionMaxAndMin) { +TEST_CASE("ExpressionTest.DivisionMaxAndMin", "[mef::expression]") { OpenExpression arg_one(1, 2, -1, 2); OpenExpression arg_two(3, 4, -7, -4); OpenExpression arg_three(5, 6, 1, 5); OpenExpression arg_four(4, 3, -2, 4); std::unique_ptr dev; - ASSERT_NO_THROW( + REQUIRE_NOTHROW( dev = MakeUnique
({&arg_one, &arg_two, &arg_three, &arg_four})); EXPECT_DOUBLE_EQ(1.0 / 3 / 5 / 4, dev->value()); EXPECT_DOUBLE_EQ(2.0 / 4 / 6 / 3, dev->Sample()); - EXPECT_TRUE(Interval::closed(-1.0 / -4 / 1 / -2, 2.0 / -4 / 1 / -2) == - dev->interval()) - << dev->interval(); + INFO(dev->interval()); + CHECK(Interval::closed(-1.0 / -4 / 1 / -2, 2.0 / -4 / 1 / -2) == + dev->interval()); } -TEST(ExpressionTest, Abs) { +TEST_CASE("ExpressionTest.Abs", "[mef::expression]") { OpenExpression arg_one(1); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&arg_one)); + REQUIRE_NOTHROW(dev = std::make_unique(&arg_one)); EXPECT_DOUBLE_EQ(1, dev->value()); arg_one.mean = 0; EXPECT_DOUBLE_EQ(0, dev->value()); @@ -703,10 +709,10 @@ EXPECT_DOUBLE_EQ(1, dev->value()); } -TEST(ExpressionTest, Acos) { +TEST_CASE("ExpressionTest.Acos", "[mef::expression]") { OpenExpression arg_one(1); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&arg_one)); + REQUIRE_NOTHROW(dev = std::make_unique(&arg_one)); EXPECT_DOUBLE_EQ(0, dev->value()); arg_one.mean = 0; EXPECT_DOUBLE_EQ(0.5 * ConstantExpression::kPi.value(), dev->value()); @@ -714,28 +720,28 @@ EXPECT_DOUBLE_EQ(ConstantExpression::kPi.value(), dev->value()); arg_one.mean = -1.001; - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); arg_one.mean = 1.001; - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); arg_one.mean = 100; - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); arg_one.mean = 1; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); arg_one.max = 1.001; - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); arg_one.max = 1; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); - EXPECT_TRUE(Interval::closed(0, ConstantExpression::kPi.value()) == - dev->interval()) - << dev->interval(); + INFO(dev->interval()); + CHECK(Interval::closed(0, ConstantExpression::kPi.value()) == + dev->interval()); } -TEST(ExpressionTest, Asin) { +TEST_CASE("ExpressionTest.Asin", "[mef::expression]") { OpenExpression arg_one(1); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&arg_one)); + REQUIRE_NOTHROW(dev = std::make_unique(&arg_one)); double half_pi = 0.5 * ConstantExpression::kPi.value(); EXPECT_DOUBLE_EQ(half_pi, dev->value()); arg_one.mean = 0; @@ -744,27 +750,27 @@ EXPECT_DOUBLE_EQ(-half_pi, dev->value()); arg_one.mean = -1.001; - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); arg_one.mean = 1.001; - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); arg_one.mean = 100; - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); arg_one.mean = 1; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); arg_one.max = 1.001; - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); arg_one.max = 1; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); - EXPECT_TRUE(Interval::closed(-half_pi, half_pi) == dev->interval()) - << dev->interval(); + INFO(dev->interval()); + CHECK(Interval::closed(-half_pi, half_pi) == dev->interval()); } -TEST(ExpressionTest, Atan) { +TEST_CASE("ExpressionTest.Atan", "[mef::expression]") { OpenExpression arg_one(1); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&arg_one)); + REQUIRE_NOTHROW(dev = std::make_unique(&arg_one)); double half_pi = 0.5 * ConstantExpression::kPi.value(); double quarter_pi = 0.25 * ConstantExpression::kPi.value(); EXPECT_DOUBLE_EQ(quarter_pi, dev->value()); @@ -773,118 +779,120 @@ arg_one.mean = -1; EXPECT_DOUBLE_EQ(-quarter_pi, dev->value()); - EXPECT_TRUE(Interval::closed(-half_pi, half_pi) == dev->interval()) - << dev->interval(); + INFO(dev->interval()); + CHECK(Interval::closed(-half_pi, half_pi) == dev->interval()); } -TEST(ExpressionTest, Cos) { +TEST_CASE("ExpressionTest.Cos", "[mef::expression]") { OpenExpression arg_one(0); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&arg_one)); + REQUIRE_NOTHROW(dev = std::make_unique(&arg_one)); EXPECT_DOUBLE_EQ(1, dev->value()); arg_one.mean = ConstantExpression::kPi.value(); EXPECT_DOUBLE_EQ(-1, dev->value()); - EXPECT_TRUE(Interval::closed(-1, 1) == dev->interval()) << dev->interval(); + INFO(dev->interval()); + CHECK(Interval::closed(-1, 1) == dev->interval()); } -TEST(ExpressionTest, Sin) { +TEST_CASE("ExpressionTest.Sin", "[mef::expression]") { OpenExpression arg_one(0); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&arg_one)); + REQUIRE_NOTHROW(dev = std::make_unique(&arg_one)); EXPECT_DOUBLE_EQ(0, dev->value()); arg_one.mean = 0.5 * ConstantExpression::kPi.value(); EXPECT_DOUBLE_EQ(1, dev->value()); - EXPECT_TRUE(Interval::closed(-1, 1) == dev->interval()) << dev->interval(); + INFO(dev->interval()); + CHECK(Interval::closed(-1, 1) == dev->interval()); } -TEST(ExpressionTest, Tan) { +TEST_CASE("ExpressionTest.Tan", "[mef::expression]") { OpenExpression arg_one(0); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&arg_one)); + REQUIRE_NOTHROW(dev = std::make_unique(&arg_one)); EXPECT_DOUBLE_EQ(0, dev->value()); arg_one.mean = 0.25 * ConstantExpression::kPi.value(); EXPECT_DOUBLE_EQ(1, dev->value()); } -TEST(ExpressionTest, Cosh) { +TEST_CASE("ExpressionTest.Cosh", "[mef::expression]") { OpenExpression arg_one(0); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&arg_one)); + REQUIRE_NOTHROW(dev = std::make_unique(&arg_one)); EXPECT_DOUBLE_EQ(1, dev->value()); } -TEST(ExpressionTest, Sinh) { +TEST_CASE("ExpressionTest.Sinh", "[mef::expression]") { OpenExpression arg_one(0); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&arg_one)); + REQUIRE_NOTHROW(dev = std::make_unique(&arg_one)); EXPECT_DOUBLE_EQ(0, dev->value()); } -TEST(ExpressionTest, Tanh) { +TEST_CASE("ExpressionTest.Tanh", "[mef::expression]") { OpenExpression arg_one(0); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&arg_one)); + REQUIRE_NOTHROW(dev = std::make_unique(&arg_one)); EXPECT_DOUBLE_EQ(0, dev->value()); } -TEST(ExpressionTest, Exp) { +TEST_CASE("ExpressionTest.Exp", "[mef::expression]") { OpenExpression arg_one(0); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&arg_one)); + REQUIRE_NOTHROW(dev = std::make_unique(&arg_one)); EXPECT_DOUBLE_EQ(1, dev->value()); } -TEST(ExpressionTest, Log) { +TEST_CASE("ExpressionTest.Log", "[mef::expression]") { OpenExpression arg_one(1); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&arg_one)); + REQUIRE_NOTHROW(dev = std::make_unique(&arg_one)); EXPECT_DOUBLE_EQ(0, dev->value()); arg_one.mean = -1; - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); arg_one.mean = 0; - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); arg_one.mean = 1; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); arg_one.sample = arg_one.min = 0; arg_one.max = 1; - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); arg_one.min = 0.5; arg_one.max = 1; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); } -TEST(ExpressionTest, Log10) { +TEST_CASE("ExpressionTest.Log10", "[mef::expression]") { OpenExpression arg_one(1); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&arg_one)); + REQUIRE_NOTHROW(dev = std::make_unique(&arg_one)); EXPECT_DOUBLE_EQ(0, dev->value()); arg_one.mean = 10; EXPECT_DOUBLE_EQ(1, dev->value()); arg_one.mean = -1; - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); arg_one.mean = 0; - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); arg_one.mean = 1; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); arg_one.sample = arg_one.min = 0; arg_one.max = 1; - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); arg_one.min = 0.5; arg_one.max = 1; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); } -TEST(ExpressionTest, Modulo) { +TEST_CASE("ExpressionTest.Modulo", "[mef::expression]") { OpenExpression arg_one(4, 1, 1, 2); OpenExpression arg_two(2, 1, 1, 2); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&arg_one, &arg_two)); + REQUIRE_NOTHROW(dev = std::make_unique(&arg_one, &arg_two)); EXPECT_DOUBLE_EQ(0, dev->value()); arg_one.mean = 5; EXPECT_DOUBLE_EQ(1, dev->value()); @@ -899,41 +907,41 @@ arg_one.mean = 4; arg_two.mean = 2; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); arg_two.mean = 0; - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); arg_two.mean = 0.9; - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); arg_two.mean = -0.9; - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); arg_two.mean = 2; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); arg_two.sample = arg_two.min = 0; arg_two.max = 10; - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); arg_two.min = 0.9; - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); arg_two.min = -0.9; - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); arg_two.min = 1; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); arg_two.min = -1; - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); arg_two.min = -5; arg_two.max = -1; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); arg_two.max = -0.9; - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); arg_two.max = 0.9; - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); } -TEST(ExpressionTest, Power) { +TEST_CASE("ExpressionTest.Power", "[mef::expression]") { OpenExpression arg_one(4, 1, 1, 2); OpenExpression arg_two(2, 1, 1, 2); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&arg_one, &arg_two)); + REQUIRE_NOTHROW(dev = std::make_unique(&arg_one, &arg_two)); EXPECT_DOUBLE_EQ(16, dev->value()); arg_one.mean = 5; EXPECT_DOUBLE_EQ(25, dev->value()); @@ -948,55 +956,55 @@ arg_one.mean = 4; arg_two.mean = 2; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); arg_one.mean = 0; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); arg_two.mean = 0; - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); arg_two.mean = -1; - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); arg_one.mean = 2; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); arg_two.min = -1; arg_two.max = 1; arg_one.sample = arg_one.min = 0; arg_one.max = 10; - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); arg_one.min = 0.9; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); arg_one.min = -0.9; - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); arg_one.min = -5; arg_one.max = -1; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); } -TEST(ExpressionTest, Sqrt) { +TEST_CASE("ExpressionTest.Sqrt", "[mef::expression]") { OpenExpression arg_one(0); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&arg_one)); + REQUIRE_NOTHROW(dev = std::make_unique(&arg_one)); EXPECT_DOUBLE_EQ(0, dev->value()); arg_one.mean = 4; EXPECT_DOUBLE_EQ(2, dev->value()); arg_one.mean = 0.0625; EXPECT_DOUBLE_EQ(0.25, dev->value()); - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); arg_one.mean = -1; - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); arg_one.mean = 4; - EXPECT_NO_THROW(dev->Validate()); + CHECK_NOTHROW(dev->Validate()); arg_one.min = -1; arg_one.max = -1; - EXPECT_THROW(dev->Validate(), DomainError); + CHECK_THROWS_AS(dev->Validate(), DomainError); } -TEST(ExpressionTest, Ceil) { +TEST_CASE("ExpressionTest.Ceil", "[mef::expression]") { OpenExpression arg_one(0); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&arg_one)); + REQUIRE_NOTHROW(dev = std::make_unique(&arg_one)); EXPECT_DOUBLE_EQ(0, dev->value()); arg_one.mean = 0.25; EXPECT_DOUBLE_EQ(1, dev->value()); @@ -1004,10 +1012,10 @@ EXPECT_DOUBLE_EQ(0, dev->value()); } -TEST(ExpressionTest, Floor) { +TEST_CASE("ExpressionTest.Floor", "[mef::expression]") { OpenExpression arg_one(0); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&arg_one)); + REQUIRE_NOTHROW(dev = std::make_unique(&arg_one)); EXPECT_DOUBLE_EQ(0, dev->value()); arg_one.mean = 0.25; EXPECT_DOUBLE_EQ(0, dev->value()); @@ -1015,40 +1023,40 @@ EXPECT_DOUBLE_EQ(-1, dev->value()); } -TEST(ExpressionTest, Min) { +TEST_CASE("ExpressionTest.Min", "[mef::expression]") { OpenExpression arg_one(10); OpenExpression arg_two(100); std::unique_ptr dev; - ASSERT_NO_THROW(dev = MakeUnique({&arg_one, &arg_two})); + REQUIRE_NOTHROW(dev = MakeUnique({&arg_one, &arg_two})); EXPECT_DOUBLE_EQ(10, dev->value()); } -TEST(ExpressionTest, Max) { +TEST_CASE("ExpressionTest.Max", "[mef::expression]") { OpenExpression arg_one(10); OpenExpression arg_two(100); std::unique_ptr dev; - ASSERT_NO_THROW(dev = MakeUnique({&arg_one, &arg_two})); + REQUIRE_NOTHROW(dev = MakeUnique({&arg_one, &arg_two})); EXPECT_DOUBLE_EQ(100, dev->value()); } -TEST(ExpressionTest, Mean) { +TEST_CASE("ExpressionTest.Mean", "[mef::expression]") { OpenExpression arg_one(10, 10, 5, 15); OpenExpression arg_two(90, 90, 80, 100); OpenExpression arg_three(20, 20, 10, 30); OpenExpression arg_four(40, 40, 30, 50); std::unique_ptr dev; - ASSERT_NO_THROW( + REQUIRE_NOTHROW( dev = MakeUnique({&arg_one, &arg_two, &arg_three, &arg_four})); EXPECT_DOUBLE_EQ(40, dev->value()); - EXPECT_TRUE(Interval::closed(31.25, 48.75) == dev->interval()) - << dev->interval(); + INFO(dev->interval()); + CHECK(Interval::closed(31.25, 48.75) == dev->interval()); } -TEST(ExpressionTest, Not) { +TEST_CASE("ExpressionTest.Not", "[mef::expression]") { OpenExpression arg_one(1); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&arg_one)); + REQUIRE_NOTHROW(dev = std::make_unique(&arg_one)); EXPECT_DOUBLE_EQ(0, dev->value()); arg_one.mean = 0; EXPECT_DOUBLE_EQ(1, dev->value()); @@ -1056,12 +1064,12 @@ EXPECT_DOUBLE_EQ(0, dev->value()); } -TEST(ExpressionTest, And) { +TEST_CASE("ExpressionTest.And", "[mef::expression]") { OpenExpression arg_one(1); OpenExpression arg_two(1); OpenExpression arg_three(1); std::unique_ptr dev; - ASSERT_NO_THROW(dev = MakeUnique({&arg_one, &arg_two, &arg_three})); + REQUIRE_NOTHROW(dev = MakeUnique({&arg_one, &arg_two, &arg_three})); EXPECT_DOUBLE_EQ(1, dev->value()); arg_three.mean = 0; EXPECT_DOUBLE_EQ(0, dev->value()); @@ -1069,12 +1077,12 @@ EXPECT_DOUBLE_EQ(1, dev->value()); } -TEST(ExpressionTest, Or) { +TEST_CASE("ExpressionTest.Or", "[mef::expression]") { OpenExpression arg_one(1); OpenExpression arg_two(1); OpenExpression arg_three(1); std::unique_ptr dev; - ASSERT_NO_THROW(dev = MakeUnique({&arg_one, &arg_two, &arg_three})); + REQUIRE_NOTHROW(dev = MakeUnique({&arg_one, &arg_two, &arg_three})); EXPECT_DOUBLE_EQ(1, dev->value()); arg_three.mean = 0; EXPECT_DOUBLE_EQ(1, dev->value()); @@ -1082,31 +1090,31 @@ EXPECT_DOUBLE_EQ(0, dev->value()); } -TEST(ExpressionTest, Eq) { +TEST_CASE("ExpressionTest.Eq", "[mef::expression]") { OpenExpression arg_one(100); OpenExpression arg_two(10); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&arg_one, &arg_two)); + REQUIRE_NOTHROW(dev = std::make_unique(&arg_one, &arg_two)); EXPECT_DOUBLE_EQ(0, dev->value()); arg_two.mean = arg_one.mean; EXPECT_DOUBLE_EQ(1, dev->value()); } -TEST(ExpressionTest, Df) { +TEST_CASE("ExpressionTest.Df", "[mef::expression]") { OpenExpression arg_one(100); OpenExpression arg_two(10); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&arg_one, &arg_two)); + REQUIRE_NOTHROW(dev = std::make_unique(&arg_one, &arg_two)); EXPECT_DOUBLE_EQ(1, dev->value()); arg_two.mean = arg_one.mean; EXPECT_DOUBLE_EQ(0, dev->value()); } -TEST(ExpressionTest, Lt) { +TEST_CASE("ExpressionTest.Lt", "[mef::expression]") { OpenExpression arg_one(100); OpenExpression arg_two(10); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&arg_one, &arg_two)); + REQUIRE_NOTHROW(dev = std::make_unique(&arg_one, &arg_two)); EXPECT_DOUBLE_EQ(0, dev->value()); arg_two.mean = arg_one.mean; EXPECT_DOUBLE_EQ(0, dev->value()); @@ -1114,11 +1122,11 @@ EXPECT_DOUBLE_EQ(1, dev->value()); } -TEST(ExpressionTest, Gt) { +TEST_CASE("ExpressionTest.Gt", "[mef::expression]") { OpenExpression arg_one(100); OpenExpression arg_two(10); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&arg_one, &arg_two)); + REQUIRE_NOTHROW(dev = std::make_unique(&arg_one, &arg_two)); EXPECT_DOUBLE_EQ(1, dev->value()); arg_two.mean = arg_one.mean; EXPECT_DOUBLE_EQ(0, dev->value()); @@ -1126,11 +1134,11 @@ EXPECT_DOUBLE_EQ(0, dev->value()); } -TEST(ExpressionTest, Leq) { +TEST_CASE("ExpressionTest.Leq", "[mef::expression]") { OpenExpression arg_one(100); OpenExpression arg_two(10); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&arg_one, &arg_two)); + REQUIRE_NOTHROW(dev = std::make_unique(&arg_one, &arg_two)); EXPECT_DOUBLE_EQ(0, dev->value()); arg_two.mean = arg_one.mean; EXPECT_DOUBLE_EQ(1, dev->value()); @@ -1138,11 +1146,11 @@ EXPECT_DOUBLE_EQ(1, dev->value()); } -TEST(ExpressionTest, Geq) { +TEST_CASE("ExpressionTest.Geq", "[mef::expression]") { OpenExpression arg_one(100); OpenExpression arg_two(10); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&arg_one, &arg_two)); + REQUIRE_NOTHROW(dev = std::make_unique(&arg_one, &arg_two)); EXPECT_DOUBLE_EQ(1, dev->value()); arg_two.mean = arg_one.mean; EXPECT_DOUBLE_EQ(1, dev->value()); @@ -1150,27 +1158,28 @@ EXPECT_DOUBLE_EQ(0, dev->value()); } -TEST(ExpressionTest, Ite) { +TEST_CASE("ExpressionTest.Ite", "[mef::expression]") { OpenExpression arg_one(1); OpenExpression arg_two(42, 42, 32, 52); OpenExpression arg_three(10, 10, 5, 15); std::unique_ptr dev; - ASSERT_NO_THROW(dev = std::make_unique(&arg_one, &arg_two, &arg_three)); + REQUIRE_NOTHROW(dev = std::make_unique(&arg_one, &arg_two, &arg_three)); EXPECT_DOUBLE_EQ(42, dev->value()); arg_one.mean = 0; EXPECT_DOUBLE_EQ(10, dev->value()); arg_one.mean = 0.5; EXPECT_DOUBLE_EQ(42, dev->value()); - EXPECT_TRUE(Interval::closed(5, 52) == dev->interval()) << dev->interval(); + INFO(dev->interval()); + CHECK(Interval::closed(5, 52) == dev->interval()); } -TEST(ExpressionTest, Switch) { +TEST_CASE("ExpressionTest.Switch", "[mef::expression]") { OpenExpression arg_one(1); OpenExpression arg_two(42, 42, 32, 52); OpenExpression arg_three(10, 10, 5, 15); std::unique_ptr dev; - ASSERT_NO_THROW( + REQUIRE_NOTHROW( dev = std::make_unique( std::vector{{arg_one, arg_two}}, &arg_three)); EXPECT_DOUBLE_EQ(42, dev->value()); @@ -1179,11 +1188,10 @@ arg_one.mean = 0.5; EXPECT_DOUBLE_EQ(42, dev->value()); - EXPECT_TRUE(Interval::closed(5, 52) == dev->interval()) << dev->interval(); + INFO(dev->interval()); + CHECK(Interval::closed(5, 52) == dev->interval()); EXPECT_DOUBLE_EQ(10, Switch({}, &arg_three).value()); } -} // namespace test -} // namespace mef -} // namespace scram +} // namespace scram::mef::test diff -Nru scram-0.16.1/tests/extern_function_tests.cc scram-0.16.2/tests/extern_function_tests.cc --- scram-0.16.1/tests/extern_function_tests.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/extern_function_tests.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,7 +19,7 @@ #include -#include +#include #include @@ -31,9 +31,7 @@ #include "expression/constant.h" -namespace scram { -namespace mef { -namespace test { +namespace scram::mef::test { const char kLibName[] = "scram_dummy_extern"; const char kLibRelPath[] = "build/lib/scram/scram_dummy_extern"; @@ -42,84 +40,84 @@ const char kLibRelPathLinux[] = "build/lib/scram/libscram_dummy_extern.so"; #endif -TEST(ExternTest, ExternLibraryLoad) { +TEST_CASE("ExternTest.ExternLibraryLoad", "[mef::extern_function]") { const std::string cwd_dir = boost::filesystem::current_path().string(); - EXPECT_THROW(ExternLibrary("dummy", kLibName, "", false, false), DLError); - EXPECT_THROW(ExternLibrary("dummy", kLibName, "", false, true), DLError); - EXPECT_THROW(ExternLibrary("dummy", kLibName, "", true, true), DLError); - EXPECT_THROW(ExternLibrary("dummy", kLibRelPath, cwd_dir, false, false), - DLError); - EXPECT_NO_THROW(ExternLibrary("dummy", kLibRelPath, cwd_dir, false, true)); - EXPECT_NO_THROW(ExternLibrary("dummy", kLibRelPath, cwd_dir, true, true)); - - EXPECT_THROW(ExternLibrary("d", "", "", false, false), ValidityError); - EXPECT_THROW(ExternLibrary("d", ".", "", false, false), ValidityError); - EXPECT_THROW(ExternLibrary("d", "/", "", false, false), ValidityError); - EXPECT_THROW(ExternLibrary("d", "//", "", false, false), ValidityError); - EXPECT_THROW(ExternLibrary("d", "..", "", false, false), ValidityError); - EXPECT_THROW(ExternLibrary("d", "./", "", false, false), ValidityError); - EXPECT_THROW(ExternLibrary("d", "lib/", "", false, false), ValidityError); - EXPECT_THROW(ExternLibrary("d", "lib:", "", false, false), ValidityError); + CHECK_THROWS_AS(ExternLibrary("dummy", kLibName, "", false, false), DLError); + CHECK_THROWS_AS(ExternLibrary("dummy", kLibName, "", false, true), DLError); + CHECK_THROWS_AS(ExternLibrary("dummy", kLibName, "", true, true), DLError); + CHECK_THROWS_AS(ExternLibrary("dummy", kLibRelPath, cwd_dir, false, false), + DLError); + CHECK_NOTHROW(ExternLibrary("dummy", kLibRelPath, cwd_dir, false, true)); + CHECK_NOTHROW(ExternLibrary("dummy", kLibRelPath, cwd_dir, true, true)); + + CHECK_THROWS_AS(ExternLibrary("d", "", "", false, false), ValidityError); + CHECK_THROWS_AS(ExternLibrary("d", ".", "", false, false), ValidityError); + CHECK_THROWS_AS(ExternLibrary("d", "/", "", false, false), ValidityError); + CHECK_THROWS_AS(ExternLibrary("d", "//", "", false, false), ValidityError); + CHECK_THROWS_AS(ExternLibrary("d", "..", "", false, false), ValidityError); + CHECK_THROWS_AS(ExternLibrary("d", "./", "", false, false), ValidityError); + CHECK_THROWS_AS(ExternLibrary("d", "lib/", "", false, false), ValidityError); + CHECK_THROWS_AS(ExternLibrary("d", "lib:", "", false, false), ValidityError); #if BOOST_OS_LINUX // The system search with LD_LIBRARY_PATH must be tested outside. - EXPECT_NO_THROW( + CHECK_NOTHROW( ExternLibrary("dummy", kLibRelPathLinux, cwd_dir, false, false)); #endif } -TEST(ExternTest, ExternLibraryGet) { +TEST_CASE("ExternTest.ExternLibraryGet", "[mef::extern_function]") { const std::string cwd_dir = boost::filesystem::current_path().string(); std::unique_ptr library; - ASSERT_NO_THROW(library = std::make_unique( + REQUIRE_NOTHROW(library = std::make_unique( "dummy", kLibRelPath, cwd_dir, false, true)); - EXPECT_NO_THROW(library->get("foo")); - EXPECT_NO_THROW(library->get("bar")); - EXPECT_NO_THROW(library->get("baz")); - EXPECT_THROW(library->get("foobar"), UndefinedElement); - - EXPECT_EQ(42, library->get("foo")()); - EXPECT_EQ(42, library->get("bar")()); - EXPECT_EQ(42, library->get("baz")()); + CHECK_NOTHROW(library->get("foo")); + CHECK_NOTHROW(library->get("bar")); + CHECK_NOTHROW(library->get("baz")); + CHECK_THROWS_AS(library->get("foobar"), UndefinedElement); + + CHECK(library->get("foo")() == 42); + CHECK(library->get("bar")() == 42); + CHECK(library->get("baz")() == 42); } -TEST(ExternTest, ExternFunction) { +TEST_CASE("ExternTest.ExternFunction", "[mef::extern_function]") { const std::string cwd_dir = boost::filesystem::current_path().string(); ExternLibrary library("dummy", kLibRelPath, cwd_dir, false, true); - EXPECT_NO_THROW(ExternFunction("extern", "foo", library)); - EXPECT_NO_THROW(ExternFunction("extern", "bar", library)); - EXPECT_NO_THROW(ExternFunction("extern", "baz", library)); - EXPECT_THROW(ExternFunction("extern", "foobar", library), - UndefinedElement); + CHECK_NOTHROW(ExternFunction("extern", "foo", library)); + CHECK_NOTHROW(ExternFunction("extern", "bar", library)); + CHECK_NOTHROW(ExternFunction("extern", "baz", library)); + CHECK_THROWS_AS(ExternFunction("extern", "foobar", library), + UndefinedElement); - EXPECT_EQ(42, ExternFunction("extern", "foo", library)()); + CHECK(ExternFunction("extern", "foo", library)() == 42); } -TEST(ExternTest, ExternExpression) { +TEST_CASE("ExternTest.ExternExpression", "[mef::extern_function]") { const std::string cwd_dir = boost::filesystem::current_path().string(); ExternLibrary library("dummy", kLibRelPath, cwd_dir, false, true); ExternFunction foo("dummy_foo", "foo", library); ExternFunction identity("dummy_id", "identity", library); ConstantExpression arg_one(12); - EXPECT_NO_THROW(ExternExpression(&foo, {})); - EXPECT_THROW(ExternExpression(&foo, {&arg_one}), ValidityError); + CHECK_NOTHROW(ExternExpression(&foo, {})); + CHECK_THROWS_AS(ExternExpression(&foo, {&arg_one}), ValidityError); - EXPECT_EQ(42, ExternExpression(&foo, {}).value()); - EXPECT_EQ(42, ExternExpression(&foo, {}).Sample()); - EXPECT_FALSE(ExternExpression(&foo, {}).IsDeviate()); - - EXPECT_NO_THROW((ExternExpression(&identity, {&arg_one}))); - EXPECT_THROW((ExternExpression(&identity, {})), - ValidityError); - EXPECT_EQ(arg_one.value(), - (ExternExpression(&identity, {&arg_one})).value()); + CHECK(ExternExpression(&foo, {}).value() == 42); + CHECK(ExternExpression(&foo, {}).Sample() == 42); + CHECK_FALSE(ExternExpression(&foo, {}).IsDeviate()); + + CHECK_NOTHROW((ExternExpression(&identity, {&arg_one}))); + CHECK_THROWS_AS((ExternExpression(&identity, {})), + ValidityError); + CHECK((ExternExpression(&identity, {&arg_one})).value() == + arg_one.value()); } -TEST(ExternTest, ExternFunctionApply) { +TEST_CASE("ExternTest.ExternFunctionApply", "[mef::extern_function]") { const std::string cwd_dir = boost::filesystem::current_path().string(); ExternLibrary library("dummy", kLibRelPath, cwd_dir, false, true); ExternFunctionPtr foo(new ExternFunction("dummy_foo", "foo", library)); @@ -127,14 +125,12 @@ new ExternFunction("dummy_id", "identity", library)); ConstantExpression arg_one(12); - EXPECT_NO_THROW(foo->apply({})); - EXPECT_EQ(42, foo->apply({})->value()); + CHECK_NOTHROW(foo->apply({})); + CHECK(foo->apply({})->value() == 42); - EXPECT_THROW(identity->apply({}), ValidityError); - EXPECT_NO_THROW(identity->apply({&arg_one})); - EXPECT_EQ(arg_one.value(), identity->apply({&arg_one})->value()); + CHECK_THROWS_AS(identity->apply({}), ValidityError); + CHECK_NOTHROW(identity->apply({&arg_one})); + CHECK(identity->apply({&arg_one})->value() == arg_one.value()); } -} // namespace test -} // namespace mef -} // namespace scram +} // namespace scram::mef::test diff -Nru scram-0.16.1/tests/fault_tree_tests.cc scram-0.16.2/tests/fault_tree_tests.cc --- scram-0.16.1/tests/fault_tree_tests.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/fault_tree_tests.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2015, 2017 Olzhas Rakhimov + * Copyright (C) 2014-2015, 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,64 +17,60 @@ #include "fault_tree.h" -#include +#include #include "error.h" -namespace scram { -namespace mef { -namespace test { +namespace scram::mef::test { -TEST(FaultTreeTest, AddGate) { +TEST_CASE("FaultTreeTest.AddGate", "[mef::fault_tree]") { FaultTree ft("never_fail"); Gate gate("Golden"); - EXPECT_NO_THROW(ft.Add(&gate)); - EXPECT_THROW(ft.Add(&gate), ValidityError); // Trying to re-add. + CHECK_NOTHROW(ft.Add(&gate)); + CHECK_THROWS_AS(ft.Add(&gate), ValidityError); // Trying to re-add. Gate gate_two("Iron"); - EXPECT_NO_THROW(ft.Add(&gate_two)); // No parent. + CHECK_NOTHROW(ft.Add(&gate_two)); // No parent. } -TEST(FaultTreeTest, AddBasicEvent) { +TEST_CASE("FaultTreeTest.AddBasicEvent", "[mef::fault_tree]") { FaultTree ft("never_fail"); BasicEvent event("Golden"); - EXPECT_NO_THROW(ft.Add(&event)); - EXPECT_THROW(ft.Add(&event), ValidityError); // Trying to re-add. + CHECK_NOTHROW(ft.Add(&event)); + CHECK_THROWS_AS(ft.Add(&event), ValidityError); // Trying to re-add. BasicEvent event_two("Iron"); - EXPECT_NO_THROW(ft.Add(&event_two)); // No parent. + CHECK_NOTHROW(ft.Add(&event_two)); // No parent. } -TEST(FaultTreeTest, AddHouseEvent) { +TEST_CASE("FaultTreeTest.AddHouseEvent", "[mef::fault_tree]") { FaultTree ft("never_fail"); HouseEvent event("Golden"); - EXPECT_NO_THROW(ft.Add(&event)); - EXPECT_THROW(ft.Add(&event), ValidityError); // Trying to re-add. + CHECK_NOTHROW(ft.Add(&event)); + CHECK_THROWS_AS(ft.Add(&event), ValidityError); // Trying to re-add. HouseEvent event_two("Iron"); - EXPECT_NO_THROW(ft.Add(&event_two)); // No parent. + CHECK_NOTHROW(ft.Add(&event_two)); // No parent. } -TEST(FaultTreeTest, AddCcfGroup) { +TEST_CASE("FaultTreeTest.AddCcfGroup", "[mef::fault_tree]") { FaultTree ft("never_fail"); BetaFactorModel group("Golden"); - EXPECT_NO_THROW(ft.Add(&group)); - EXPECT_THROW(ft.Add(&group), ValidityError); // Trying to re-add. + CHECK_NOTHROW(ft.Add(&group)); + CHECK_THROWS_AS(ft.Add(&group), ValidityError); // Trying to re-add. BetaFactorModel group_two("Iron"); - EXPECT_NO_THROW(ft.Add(&group_two)); + CHECK_NOTHROW(ft.Add(&group_two)); } -TEST(FaultTreeTest, AddParameter) { +TEST_CASE("FaultTreeTest.AddParameter", "[mef::fault_tree]") { FaultTree ft("never_fail"); Parameter parameter("Golden"); - EXPECT_NO_THROW(ft.Add(¶meter)); - EXPECT_THROW(ft.Add(¶meter), ValidityError); + CHECK_NOTHROW(ft.Add(¶meter)); + CHECK_THROWS_AS(ft.Add(¶meter), ValidityError); Parameter parameter_two("Iron"); - EXPECT_NO_THROW(ft.Add(¶meter_two)); + CHECK_NOTHROW(ft.Add(¶meter_two)); } -} // namespace test -} // namespace mef -} // namespace scram +} // namespace scram::mef::test diff -Nru scram-0.16.1/tests/initializer_tests.cc scram-0.16.2/tests/initializer_tests.cc --- scram-0.16.1/tests/initializer_tests.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/initializer_tests.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,80 +17,80 @@ #include "initializer.h" -#include +#include #include "error.h" #include "settings.h" -namespace scram { -namespace mef { -namespace test { +namespace scram::mef::test { // Test if the XML is well formed. -TEST(InitializerTest, XMLFormatting) { - EXPECT_THROW( +TEST_CASE("InitializerTest.XMLFormatting", "[mef::initializer]") { + CHECK_THROWS_AS( Initializer({"tests/input/xml_formatting_error.xml"}, core::Settings()), xml::ParseError); } // XML custom namespace errors. -TEST(InitializerTest, XMLNameSpace) { - EXPECT_THROW( +TEST_CASE("InitializerTest.XMLNameSpace", "[mef::initializer]") { + CHECK_THROWS_AS( Initializer({"tests/input/undefined_xmlns.xml"}, core::Settings()), xml::ParseError); - EXPECT_THROW(Initializer({"tests/input/custom_xmlns.xml"}, core::Settings()), - xml::ValidityError); + CHECK_THROWS_AS( + Initializer({"tests/input/custom_xmlns.xml"}, core::Settings()), + xml::ValidityError); } // Test the response for non-existent file. -TEST(InitializerTest, NonExistentFile) { +TEST_CASE("InitializerTest.NonExistentFile", "[mef::initializer]") { // Access issues. IOErrors - EXPECT_THROW( + CHECK_THROWS_AS( Initializer({"tests/input/nonexistent_file.xml"}, core::Settings()), IOError); } // Test if passing the same file twice causing an error. -TEST(InitializerTest, PassTheSameFileTwice) { +TEST_CASE("InitializerTest.PassTheSameFileTwice", "[mef::initializer]") { std::string input_correct = "tests/input/fta/correct_tree_input.xml"; std::string the_same_path = // Path obfuscation. "tests/../tests/input/fta/correct_tree_input.xml"; - EXPECT_THROW(Initializer({input_correct, the_same_path}, core::Settings()), - ValidityError); + CHECK_THROWS_AS(Initializer({input_correct, the_same_path}, core::Settings()), + ValidityError); } // Test if the schema catches errors. // This is trusted to XML libraries and the correctness of the RELAX NG schema, // so the test is very basic calls. -TEST(InitializerTest, FailSchemaValidation) { - EXPECT_THROW(Initializer({"tests/input/schema_fail.xml"}, core::Settings()), - xml::ValidityError); +TEST_CASE("InitializerTest.FailSchemaValidation", "[mef::initializer]") { + CHECK_THROWS_AS( + Initializer({"tests/input/schema_fail.xml"}, core::Settings()), + xml::ValidityError); } // Unsupported operations. -TEST(InitializerTest, UnsupportedFeature) { +TEST_CASE("InitializerTest.UnsupportedFeature", "[mef::initializer]") { std::string dir = "tests/input/"; const char* incorrect_inputs[] = {"unsupported_feature.xml", "unsupported_gate.xml", "unsupported_expression.xml"}; for (const auto& input : incorrect_inputs) { - EXPECT_THROW(Initializer({dir + input}, core::Settings()), - xml::ValidityError) - << " Filename: " << input; + CAPTURE(input); + CHECK_THROWS_AS(Initializer({dir + input}, core::Settings()), + xml::ValidityError); } } -TEST(InitializerTest, EmptyAttributeElementText) { +TEST_CASE("InitializerTest.EmptyAttributeElementText", "[mef::initializer]") { std::string dir = "tests/input/"; const char* incorrect_inputs[] = {"empty_element.xml", "empty_attribute.xml"}; for (const auto& input : incorrect_inputs) { - EXPECT_THROW(Initializer({dir + input}, core::Settings()), - xml::ValidityError) - << " Filename: " << input; + CAPTURE(input); + CHECK_THROWS_AS(Initializer({dir + input}, core::Settings()), + xml::ValidityError); } } -TEST(InitializerTest, CorrectEtaInputs) { +TEST_CASE("InitializerTest.CorrectEtaInputs", "[mef::initializer]") { std::string dir = "tests/input/eta/"; const char* correct_inputs[] = {"simplest_correct.xml", "public_sequence.xml", @@ -106,12 +106,12 @@ "test_initiating_event.xml", "test_functional_event.xml"}; for (const auto& input : correct_inputs) { - EXPECT_NO_THROW(Initializer({dir + input}, core::Settings())) - << " Filename: " << input; + CAPTURE(input); + CHECK_NOTHROW(Initializer({dir + input}, core::Settings())); } } -TEST(InitializerTest, IncorrectEtaInputs) { +TEST_CASE("InitializerTest.IncorrectEtaInputs", "[mef::initializer]") { std::string dir = "tests/input/eta/"; const char* incorrect_inputs[] = {"doubly_defined_initiating_event.xml", "doubly_defined_event_tree.xml", @@ -151,18 +151,20 @@ "mixing_collect_instructions_link.xml", "mixing_collect_instructions_fork.xml"}; for (const auto& input : incorrect_inputs) { - EXPECT_THROW(Initializer({dir + input}, core::Settings()), ValidityError) - << " Filename: " << input; + CAPTURE(input); + CHECK_THROWS_AS(Initializer({dir + input}, core::Settings()), + ValidityError); } } -TEST(InitializerTest, CorrectLabelsAndAttributes) { +TEST_CASE("InitializerTest.CorrectLabelsAndAttributes", "[mef::initializer]") { const char* input = "tests/input/fta/labels_and_attributes.xml"; - EXPECT_NO_THROW(Initializer({input}, core::Settings())); + CAPTURE(input); + CHECK_NOTHROW(Initializer({input}, core::Settings())); } // Test correct inputs without probability information. -TEST(InitializerTest, CorrectFtaInputs) { +TEST_CASE("InitializerTest.CorrectFtaInputs", "[mef::initializer]") { std::string dir = "tests/input/fta/"; const char* correct_inputs[] = {"correct_tree_input.xml", "correct_formulas.xml", @@ -189,32 +191,32 @@ "weibull_lnorm_deviate_3p.xml"}; for (const auto& input : correct_inputs) { - EXPECT_NO_THROW(Initializer({dir + input}, core::Settings())) - << " Filename: " << input; + CAPTURE(input); + CHECK_NOTHROW(Initializer({dir + input}, core::Settings())); } } -TEST(InitializerTest, CorrectInclude) { +TEST_CASE("InitializerTest.CorrectInclude", "[mef::initializer]") { std::string dir = "tests/input/"; const char* correct_inputs[] = {"xinclude.xml", "xinclude_transitive.xml"}; for (const auto& input : correct_inputs) { - EXPECT_NO_THROW(Initializer({dir + input}, core::Settings())) - << " Filename: " << input; + CAPTURE(input); + CHECK_NOTHROW(Initializer({dir + input}, core::Settings())); } } -TEST(InitializerTest, IncorrectInclude) { +TEST_CASE("InitializerTest.IncorrectInclude", "[mef::initializer]") { std::string dir = "tests/input/"; const char* correct_inputs[] = {"xinclude_no_file.xml", "xinclude_cycle.xml"}; for (const auto& input : correct_inputs) { - EXPECT_THROW(Initializer({dir + input}, core::Settings()), - xml::XIncludeError) - << " Filename: " << input; + CAPTURE(input); + CHECK_THROWS_AS(Initializer({dir + input}, core::Settings()), + xml::XIncludeError); } } // Test correct inputs with probability information. -TEST(InitializerTest, CorrectProbabilityInputs) { +TEST_CASE("InitializerTest.CorrectProbabilityInputs", "[mef::initializer]") { std::string dir = "tests/input/fta/"; const char* correct_inputs[] = { "missing_bool_constant.xml", // House event is implicitly false. @@ -225,13 +227,13 @@ settings.probability_analysis(true); for (const auto& input : correct_inputs) { - EXPECT_NO_THROW(Initializer({dir + input}, settings)) - << " Filename: " << input; + CAPTURE(input); + CHECK_NOTHROW(Initializer({dir + input}, settings)); } } // Test incorrect fault tree inputs -TEST(InitializerTest, IncorrectFtaInputs) { +TEST_CASE("InitializerTest.IncorrectFtaInputs", "[mef::initializer]") { std::string dir = "tests/input/fta/"; const char* incorrect_inputs[] = {"invalid_probability.xml", "private_at_model_scope.xml", @@ -279,40 +281,41 @@ "repeated_ccf_members.xml"}; for (const auto& input : incorrect_inputs) { - EXPECT_THROW(Initializer({dir + input}, core::Settings()), ValidityError) - << " Filename: " << input; + CAPTURE(input); + CHECK_THROWS_AS(Initializer({dir + input}, core::Settings()), + ValidityError); } } -TEST(InitializerTest, IncorrectXMLOverflow) { +TEST_CASE("InitializerTest.IncorrectXMLOverflow", "[mef::initializer]") { std::string input = "tests/input/fta/int_overflow.xml"; - EXPECT_THROW(Initializer({input}, core::Settings()), xml::ValidityError); + CHECK_THROWS_AS(Initializer({input}, core::Settings()), xml::ValidityError); } // Test failures triggered only in with probability analysis. -TEST(InitializerTest, IncorrectProbabilityInputs) { +TEST_CASE("InitializerTest.IncorrectProbabilityInputs", "[mef::initializer]") { std::string dir = "tests/input/fta/"; const char* incorrect_inputs[] = {"missing_expression.xml"}; core::Settings settings; settings.probability_analysis(true); for (const auto& input : incorrect_inputs) { - EXPECT_THROW(Initializer({dir + input}, settings), ValidityError) - << " Filename: " << input; + CAPTURE(input); + CHECK_THROWS_AS(Initializer({dir + input}, settings), ValidityError); } } // Test the case when a top event is not orphan. // The top event of one fault tree // can be a child of a gate of another fault tree. -TEST(InitializerTest, NonOrphanTopEvent) { +TEST_CASE("InitializerTest.NonOrphanTopEvent", "[mef::initializer]") { std::string dir = "tests/input/fta/"; - EXPECT_NO_THROW(Initializer( + CHECK_NOTHROW(Initializer( {dir + "correct_tree_input.xml", dir + "second_fault_tree.xml"}, core::Settings())); } -TEST(InitializerTest, CorrectModelInputs) { +TEST_CASE("InitializerTest.CorrectModelInputs", "[mef::initializer]") { std::string dir = "tests/input/model/"; const char* correct_inputs[] = { "extern_library.xml", @@ -332,12 +335,12 @@ core::Settings settings; settings.approximation(core::Approximation::kRareEvent); for (const auto& input : correct_inputs) { - EXPECT_NO_THROW(Initializer({dir + input}, settings, true)) - << " Filename: " << input; + CAPTURE(input); + CHECK_NOTHROW(Initializer({dir + input}, settings, true)); } } -TEST(InitializerTest, IncorrectModelInputs) { +TEST_CASE("InitializerTest.IncorrectModelInputs", "[mef::initializer]") { std::string dir = "tests/input/model/"; const char* incorrect_inputs[] = { "duplicate_extern_libraries.xml", @@ -381,51 +384,50 @@ core::Settings settings; settings.approximation(core::Approximation::kRareEvent); for (const auto& input : incorrect_inputs) { - EXPECT_THROW(Initializer({dir + input}, settings, true), ValidityError) - << " Filename: " << input; + CAPTURE(input); + CHECK_THROWS_AS(Initializer({dir + input}, settings, true), ValidityError); } } -TEST(InitializerTest, IncorrectModelEmptyInputs) { +TEST_CASE("InitializerTest.IncorrectModelEmptyInputs", "[mef::initializer]") { std::string dir = "tests/input/model/"; const char* incorrect_inputs[] = {"empty_extern_function.xml", "empty_alignment.xml"}; for (const auto& input : incorrect_inputs) { - EXPECT_THROW(Initializer({dir + input}, core::Settings(), true), - xml::ValidityError) - << " Filename: " << input; + CAPTURE(input); + CHECK_THROWS_AS(Initializer({dir + input}, core::Settings(), true), + xml::ValidityError); } } -TEST(InitializerTest, ExternDLError) { +TEST_CASE("InitializerTest.ExternDLError", "[mef::initializer]") { std::string input = "tests/input/model/extern_library_ioerror.xml"; - EXPECT_THROW(Initializer({input}, core::Settings(), true), DLError); + CHECK_THROWS_AS(Initializer({input}, core::Settings(), true), DLError); } // Tests that external libraries are disabled by default. -TEST(InitializerTest, DefaultExternDisable) { +TEST_CASE("InitializerTest.DefaultExternDisable", "[mef::initializer]") { std::string input = "tests/input/model/extern_library.xml"; - EXPECT_NO_THROW(Initializer({input}, core::Settings(), true)); - EXPECT_THROW(Initializer({input}, core::Settings()), IllegalOperation); + CHECK_NOTHROW(Initializer({input}, core::Settings(), true)); + CHECK_THROWS_AS(Initializer({input}, core::Settings()), IllegalOperation); } // Non-declarative substitutions with approximations only. -TEST(InitializerTest, NonDeclarativeSubstitutionsWithAppproximations) { +TEST_CASE("InitializerTest.NonDeclarativeSubstitutionsWithAppproximations", + "[mef::initializer]") { std::string input = "tests/input/model/substitution_types.xml"; - EXPECT_THROW(Initializer({input}, core::Settings()), ValidityError); + CHECK_THROWS_AS(Initializer({input}, core::Settings()), ValidityError); core::Settings settings; settings.approximation(core::Approximation::kRareEvent); - EXPECT_NO_THROW(Initializer({input}, settings)); + CHECK_NOTHROW(Initializer({input}, settings)); settings.approximation(core::Approximation::kMcub); - EXPECT_NO_THROW(Initializer({input}, settings)); + CHECK_NOTHROW(Initializer({input}, settings)); settings.prime_implicants(true); - EXPECT_THROW(Initializer({input}, core::Settings()), ValidityError); + CHECK_THROWS_AS(Initializer({input}, core::Settings()), ValidityError); } -} // namespace test -} // namespace mef -} // namespace scram +} // namespace scram::mef::test diff -Nru scram-0.16.1/tests/linear_map_tests.cc scram-0.16.2/tests/linear_map_tests.cc --- scram-0.16.1/tests/linear_map_tests.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/linear_map_tests.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2017 Olzhas Rakhimov + * Copyright (C) 2016-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,7 +21,7 @@ #include -#include +#include // Explicit instantiations with some common types. template class ext::linear_map; @@ -53,272 +53,391 @@ boost::container::vector>; #endif -namespace scram { -namespace test { +namespace std { + +template +std::ostream& operator<<(std::ostream& out, const std::pair& value) { + out << "{" << Catch::StringMaker::convert(value.first) << ", " + << Catch::StringMaker::convert(value.second) << "}"; + return out; +} + +} // namespace std + +namespace scram::test { using IntMap = ext::linear_map; -TEST(LinearMapTest, Constructors) { - IntMap m_default; - EXPECT_EQ(0, m_default.size()); - EXPECT_TRUE(m_default.empty()); +TEST_CASE("linear map ctors", "[linear_map]") { + SECTION("default ctor") { + IntMap m_default; + CHECK(m_default.size() == 0); + CHECK(m_default.empty()); + } IntMap m_init_list = {{1, -1}, {2, -2}, {3, -3}}; - EXPECT_EQ(3, m_init_list.size()); - EXPECT_FALSE(m_init_list.empty()); + SECTION("initializer list") { + CHECK(m_init_list.size() == 3); + CHECK_FALSE(m_init_list.empty()); + } + + SECTION("copy ctor") { + auto m_copy(m_init_list); + CHECK(m_copy.size() == 3); + CHECK_FALSE(m_copy.empty()); + CHECK(m_copy == m_init_list); + + SECTION("copy itself") { + m_copy = m_copy; + CHECK(m_copy.size() == 3); + CHECK(m_copy == m_init_list); + } + } + + SECTION("move ctor") { + auto construct_extra_copy(m_init_list); + auto m_move(std::move(construct_extra_copy)); + CHECK(construct_extra_copy.empty()); + CHECK(m_move.size() == 3); + CHECK_FALSE(m_move.empty()); + CHECK(m_move == m_init_list); + } + + SECTION("copy assignment") { + IntMap m_assign_copy; + m_assign_copy = m_init_list; + CHECK(m_assign_copy == m_init_list); + } + + SECTION("move assignment") { + IntMap m_assign_move; + auto assign_extra_copy(m_init_list); + m_assign_move = std::move(assign_extra_copy); + CHECK(assign_extra_copy.empty()); + CHECK(m_assign_move == m_init_list); + } - auto m_copy(m_init_list); - EXPECT_EQ(3, m_copy.size()); - EXPECT_FALSE(m_copy.empty()); - EXPECT_EQ(m_init_list, m_copy); - - // Copy yourself. - m_copy = m_copy; - EXPECT_EQ(3, m_copy.size()); - EXPECT_EQ(m_init_list, m_copy); - - auto construct_extra_copy(m_init_list); - auto m_move(std::move(construct_extra_copy)); - EXPECT_TRUE(construct_extra_copy.empty()); - EXPECT_EQ(3, m_move.size()); - EXPECT_FALSE(m_move.empty()); - EXPECT_EQ(m_init_list, m_move); - - // Assignments. - IntMap m_assign_copy; - m_assign_copy = m_init_list; - EXPECT_EQ(m_init_list, m_assign_copy); - - IntMap m_assign_move; - auto assign_extra_copy(m_init_list); - m_assign_move = std::move(assign_extra_copy); - EXPECT_TRUE(assign_extra_copy.empty()); - EXPECT_EQ(m_init_list, m_assign_move); - - IntMap::container_type m_data = {{1, -1}, {2, -2}, {3, -3}, {3, -4}}; - IntMap m_range(m_data.begin(), m_data.end()); - EXPECT_EQ(m_init_list, m_range); + SECTION("range ctor") { + IntMap::container_type m_data = {{1, -1}, {2, -2}, {3, -3}, {3, -4}}; + IntMap m_range(m_data.begin(), m_data.end()); + CHECK(m_range == m_init_list); + } - IntMap m_repeat_init{{1, -1}, {2, -2}, {3, -3}, {3, -4}}; - EXPECT_EQ(m_init_list, m_repeat_init); + SECTION("repeat") { + IntMap m_repeat_init{{1, -1}, {2, -2}, {3, -3}, {3, -4}}; + CHECK(m_repeat_init == m_init_list); + } } -TEST(LinearMapTest, Equality) { +TEST_CASE("linear map equality", "[linear_map]") { IntMap m1; - EXPECT_EQ(m1, m1); + SECTION("compare to itself") { CHECK(m1 == m1); } IntMap m2; - EXPECT_EQ(m1, m2); + SECTION("compare to new") { CHECK(m2 == m1); } m1 = {{1, -1}, {2, -2}, {3, -3}}; - EXPECT_EQ(m1, m1); - EXPECT_NE(m1, m2); - m2 = m1; - EXPECT_EQ(m1, m2); - m2 = {{1, -1}, {2, -2}, {3, -3}}; - EXPECT_EQ(m1, m2); - - m2 = {{2, -2}, {1, -1}, {3, -3}}; // Different order. - EXPECT_EQ(m1, m2); - - m2 = {{1, -1}, {2, -2}}; - EXPECT_NE(m1, m2); - - m2 = {{1, 1}, {2, 2}, {3, 3}}; // The same keys, but different values. - EXPECT_NE(m1, m2); + SECTION("with equal values") { + CHECK(m1 == m1); + CHECK_FALSE(m2 == m1); + SECTION("copy") { + m2 = m1; + CHECK(m2 == m1); + } + SECTION("new with the same values") { + m2 = {{1, -1}, {2, -2}, {3, -3}}; + CHECK(m2 == m1); + } + SECTION("new with different order") { + m2 = {{2, -2}, {1, -1}, {3, -3}}; + CHECK(m2 == m1); + } + } + SECTION("with unequal values") { + SECTION("one less") { + m2 = {{1, -1}, {2, -2}}; + CHECK_FALSE(m2 == m1); + } + SECTION("same keys but different values") { + m2 = {{1, 1}, {2, 2}, {3, 3}}; + CHECK_FALSE(m2 == m1); + } + } } -TEST(LinearMapTest, Iterators) { +TEST_CASE("linear map iterators", "[linear_map]") { IntMap m = {{1, -1}, {2, -2}, {3, -3}}; IntMap::container_type c = {{1, -1}, {2, -2}, {3, -3}}; - EXPECT_EQ(std::next(m.begin(), m.size()), m.end()); - EXPECT_EQ(std::next(m.rbegin(), m.size()), m.rend()); - EXPECT_EQ(std::next(m.cbegin(), m.size()), m.cend()); - EXPECT_EQ(std::next(m.crbegin(), m.size()), m.crend()); + CHECK(std::next(m.begin(), m.size()) == m.end()); + CHECK(std::next(m.rbegin(), m.size()) == m.rend()); + CHECK(std::next(m.cbegin(), m.size()) == m.cend()); + CHECK(std::next(m.crbegin(), m.size()) == m.crend()); const auto& m_ref = m; - EXPECT_EQ(std::next(m_ref.begin(), m_ref.size()), m_ref.end()); - EXPECT_EQ(std::next(m_ref.rbegin(), m_ref.size()), m_ref.rend()); - EXPECT_EQ(std::next(m_ref.cbegin(), m_ref.size()), m_ref.cend()); - EXPECT_EQ(std::next(m_ref.crbegin(), m_ref.size()), m_ref.crend()); + CHECK(std::next(m_ref.begin(), m_ref.size()) == m_ref.end()); + CHECK(std::next(m_ref.rbegin(), m_ref.size()) == m_ref.rend()); + CHECK(std::next(m_ref.cbegin(), m_ref.size()) == m_ref.cend()); + CHECK(std::next(m_ref.crbegin(), m_ref.size()) == m_ref.crend()); auto it_c = c.begin(); int num_elements = 0; int key_sum = 0; int value_sum = 0; for (const auto& entry : m) { - EXPECT_EQ(*it_c++, entry); + INFO(std::distance(c.begin(), it_c)); + CHECK(*it_c++ == entry); ++num_elements; key_sum += entry.first; value_sum += entry.second; } - EXPECT_EQ(3, num_elements); - EXPECT_EQ(6, key_sum); - EXPECT_EQ(-6, value_sum); - EXPECT_EQ(c, m.data()); -} + CHECK(num_elements == 3); + CHECK(key_sum == 6); + CHECK(value_sum == -6); + CHECK(m.data() == c); +} + +SCENARIO("linear map clear", "[linear_map]") { + GIVEN("empty linear map") { + IntMap m; + REQUIRE(m.empty()); + REQUIRE(m.capacity() >= m.size()); + auto init_capacity = m.capacity(); + + WHEN("clear") { + m.clear(); + THEN("no change") { + CHECK(m.empty()); + CHECK(m.capacity() == init_capacity); + } + } + } -TEST(LinearMapTest, Clear) { - IntMap m = {{1, -1}, {2, -2}, {3, -3}}; - EXPECT_FALSE(m.empty()); - m.clear(); - EXPECT_TRUE(m.empty()); + GIVEN("non empty linear map") { + IntMap m = {{1, -1}, {2, -2}, {3, -3}}; + CHECK_FALSE(m.empty()); + REQUIRE(m.capacity() >= m.size()); + auto init_capacity = m.capacity(); + + WHEN("clear") { + m.clear(); + THEN("the map is empty but capacity is not") { + CHECK(m.empty()); + CHECK(m.capacity() == init_capacity); + } + } + } } -TEST(LinearMapTest, Reserve) { - IntMap m; - m.reserve(1000); - EXPECT_LE(1000, m.capacity()); +SCENARIO("linear map capacity reserve", "[linear_map]") { + GIVEN("A linear map with some items") { + IntMap m = {{1, -1}, {2, -2}, {3, -3}}; + + REQUIRE(m.size() == 3); + REQUIRE(m.capacity() >= 3); + + WHEN("the capacity is increased") { + m.reserve(10); + + THEN("the capacity change but not size") { + REQUIRE(m.size() == 3); + REQUIRE(m.capacity() >= 10); + } + } + WHEN("the capacity is reduced") { + m.reserve(0); + + THEN("the size and capacity do not change") { + REQUIRE(m.size() == 3); + REQUIRE(m.capacity() >= 3); + } + } + } } -TEST(LinearMapTest, Swap) { - IntMap m1 = {{1, -1}, {2, -2}, {3, -3}}; - IntMap m2 = {{4, -4}, {5, -5}}; +TEST_CASE("linear map swap", "[linear_map]") { + const IntMap m1 = {{1, -1}, {2, -2}, {3, -3}}; + const IntMap m2 = {{4, -4}, {5, -5}}; IntMap ms1 = m1; IntMap ms2 = m2; - ms1.swap(ms2); - EXPECT_EQ(m1, ms2); - EXPECT_EQ(m2, ms1); - swap(ms1, ms2); - EXPECT_EQ(m1, ms1); - EXPECT_EQ(m2, ms2); + SECTION("member swap") { + ms1.swap(ms2); + CHECK(ms2 == m1); + CHECK(ms1 == m2); + } + + SECTION("ADL swap") { + swap(ms1, ms2); + CHECK(ms2 == m1); + CHECK(ms1 == m2); + } + + SECTION("STD swap") { + std::swap(ms1, ms2); + CHECK(ms2 == m1); + CHECK(ms1 == m2); + } } -TEST(LinearMapTest, DefaultErase) { +TEST_CASE("linear map default erase", "[linear_map]") { IntMap m = {{1, -1}, {2, -2}, {3, -3}}; - m.erase(1); IntMap m_expected = {{2, -2}, {3, -3}}; - EXPECT_EQ(m_expected, m); - m.erase(m.begin()); - m_expected = {{3, -3}}; - EXPECT_EQ(m_expected, m); + SECTION("erase w/ key") { + m.erase(1); + CHECK(m == m_expected); + CHECK(m.data() == m_expected.data()); + } + + SECTION("erase w/ iterator") { + m.erase(m.begin()); + CHECK(m == m_expected); + CHECK(m.data() == m_expected.data()); + } - m.erase(m.cbegin()); - EXPECT_TRUE(m.empty()); + SECTION("erase w/ const iterator") { + m.erase(m.cbegin()); + CHECK(m == m_expected); + CHECK(m.data() == m_expected.data()); + } } -TEST(LinearMapTest, MoveErase) { +TEST_CASE("linear map move erase", "[linear_map]") { using MoveMap = ext::linear_map; MoveMap m = {{1, -1}, {2, -2}, {3, -3}}; - m.erase(1); MoveMap m_expected = {{3, -3}, {2, -2}}; - EXPECT_EQ(m_expected, m); - m.erase(m.begin()); - m_expected = {{2, -2}}; - EXPECT_EQ(m_expected, m); + SECTION("erase w/ key") { + m.erase(1); + CHECK(m == m_expected); + CHECK(m.data() == m_expected.data()); + } + + SECTION("erase w/ iterator") { + m.erase(m.begin()); + CHECK(m == m_expected); + CHECK(m.data() == m_expected.data()); + } - m.erase(m.cbegin()); - EXPECT_TRUE(m.empty()); + SECTION("erase w/ const iterator") { + m.erase(m.cbegin()); + CHECK(m == m_expected); + CHECK(m.data() == m_expected.data()); + } } -TEST(LinearMapTest, Find) { +TEST_CASE("linear map find", "[linear_map]") { IntMap m = {{1, -1}, {2, -2}, {3, -3}}; - EXPECT_EQ(1, m.count(1)); - EXPECT_EQ(0, m.count(5)); - EXPECT_EQ(m.begin(), m.find(1)); - EXPECT_EQ(1, m.find(1)->first); + CHECK(m.count(1) == 1); + CHECK(m.count(5) == 0); + + CHECK(m.find(1) == m.begin()); + CHECK(m.find(1)->first == 1); int key = 2; - EXPECT_EQ(m.begin() + 1, m.find(key)); - EXPECT_EQ(key, m.find(key)->first); - EXPECT_EQ(m.begin() + 2, m.find(3)); - EXPECT_EQ(m.end(), m.find(5)); + CHECK(m.find(key) == std::next(m.begin(), 1)); + CHECK(m.find(key)->first == key); + CHECK(m.find(3) == std::next(m.begin(), 2)); + CHECK(m.find(5) == m.end()); } -TEST(LinearMapTest, OperatorIndex) { +TEST_CASE("linear map operator index", "[linear_map]") { IntMap m; m[1] = -1; int k = 2; m[k] = -2; m[3] = -3; IntMap expected = {{1, -1}, {2, -2}, {3, -3}}; - EXPECT_EQ(expected, m); + REQUIRE(m == expected); m[3] = -4; IntMap changed = {{1, -1}, {2, -2}, {3, -4}}; - EXPECT_EQ(changed, m); + REQUIRE(m == changed); } -TEST(LinearMapTest, At) { +TEST_CASE("linear map at", "[linear_map]") { IntMap m = {{1, -1}, {2, -2}, {3, -3}}; - EXPECT_EQ(-1, m.at(1)); - EXPECT_THROW(m.at(5), std::out_of_range); + CHECK(m.at(1) == -1); + CHECK_THROWS_AS(m.at(5), std::out_of_range); const auto& m_ref = m; - EXPECT_EQ(-2, m_ref.at(2)); + CHECK(m_ref.at(2) == -2); m.at(2) = -4; IntMap m_expected = {{1, -1}, {2, -4}, {3, -3}}; - EXPECT_EQ(m_expected, m); + CHECK(m == m_expected); } -TEST(LinearMapTest, InsertSingle) { +TEST_CASE("linear map insert single", "[linear_map]") { IntMap m; auto ret = m.insert({1, -1}); - EXPECT_TRUE(ret.second); - EXPECT_EQ(m.begin(), ret.first); - EXPECT_EQ(1, ret.first->first); - EXPECT_EQ(-1, ret.first->second); + CHECK(ret.second); + REQUIRE_FALSE(ret.first == m.end()); + CHECK(ret.first == m.begin()); + CHECK(ret.first->first == 1); + CHECK(ret.first->second == -1); IntMap::value_type v = {2, -2}; ret = m.insert(v); - EXPECT_TRUE(ret.second); - EXPECT_EQ(m.begin() + 1, ret.first); - EXPECT_EQ(2, ret.first->first); - EXPECT_EQ(-2, ret.first->second); + CHECK(ret.second); + CHECK(ret.first == std::next(m.begin(), 1)); + CHECK(ret.first->first == 2); + CHECK(ret.first->second == -2); auto repeat = m.insert({2, -3}); - EXPECT_FALSE(repeat.second); - EXPECT_EQ(ret.first, repeat.first); + CHECK_FALSE(repeat.second); + CHECK(ret.first == repeat.first); m.insert({3, -3}); IntMap expected = {{1, -1}, {2, -2}, {3, -3}}; - EXPECT_EQ(expected, m); + CHECK(m == expected); } -TEST(LinearMapTest, InsertRange) { +TEST_CASE("linear map insert range", "[linear_map]") { IntMap m; std::vector> data = {{1, -1}, {2, -2}, {3, -3}, {3, -4}}; IntMap expected = {{1, -1}, {2, -2}, {3, -3}}; - m.insert(data.begin(), data.begin()); - EXPECT_TRUE(m.empty()); + SECTION("equal iterators") { + m.insert(data.begin(), data.begin()); + CHECK(m.empty()); + } - m.insert(data.begin(), data.begin() + 2); - EXPECT_EQ(2, m.size()); + SECTION("shift two") { + m.insert(data.begin(), data.begin() + 2); + CHECK(m.size() == 2); + } - m.insert(data.begin(), data.end()); - EXPECT_EQ(expected.size(), m.size()); - EXPECT_EQ(expected, m); + SECTION("begin to end") { + m.insert(data.begin(), data.end()); + CHECK(m.size() == expected.size()); + CHECK(m == expected); + } } -TEST(LinearMapTest, Emplace) { +TEST_CASE("linear map emplace", "[linear_map]") { IntMap m; auto ret = m.emplace(1, -1); - EXPECT_TRUE(ret.second); - EXPECT_EQ(m.begin(), ret.first); - EXPECT_EQ(1, ret.first->first); - EXPECT_EQ(-1, ret.first->second); + CHECK(ret.second); + CHECK(ret.first == m.begin()); + CHECK(ret.first->first == 1); + CHECK(ret.first->second == -1); int k = 2; int v = -2; ret = m.emplace(k, v); - EXPECT_TRUE(ret.second); - EXPECT_EQ(m.begin() + 1, ret.first); - EXPECT_EQ(2, ret.first->first); - EXPECT_EQ(-2, ret.first->second); + CHECK(ret.second); + CHECK(ret.first == std::next(m.begin())); + CHECK(ret.first->first == 2); + CHECK(ret.first->second == -2); auto repeat = m.emplace(2, -3); - EXPECT_FALSE(repeat.second); - EXPECT_EQ(ret.first, repeat.first); + CHECK_FALSE(repeat.second); + CHECK(repeat.first == ret.first); m.emplace(3, -3); IntMap expected = {{1, -1}, {2, -2}, {3, -3}}; - EXPECT_EQ(expected, m); + CHECK(m == expected); } -} // namespace test -} // namespace scram +} // namespace scram::test diff -Nru scram-0.16.1/tests/pdag_tests.cc scram-0.16.2/tests/pdag_tests.cc --- scram-0.16.1/tests/pdag_tests.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/pdag_tests.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2017 Olzhas Rakhimov + * Copyright (C) 2015-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,20 +17,24 @@ #include "pdag.h" -#include +#include #include "fault_tree.h" #include "initializer.h" #include "model.h" #include "settings.h" -namespace scram { -namespace core { -namespace test { +/// @todo: Replace w/ proper Catch macros. +#define ASSERT_TRUE REQUIRE +#define ASSERT_FALSE REQUIRE_FALSE -TEST(PdagTest, Print) { +#define STR(arg) #arg // Wrapper to use catenation. + +namespace scram::core::test { + +TEST_CASE("PdagTest.Print", "[mef::pdag]") { std::unique_ptr init; - ASSERT_NO_THROW(init.reset(new mef::Initializer( + REQUIRE_NOTHROW(init.reset(new mef::Initializer( {"tests/input/fta/correct_formulas.xml"}, Settings()))); const mef::FaultTreePtr& ft = *init->model()->fault_trees().begin(); Pdag graph(*ft->top_events().front()); @@ -39,9 +43,9 @@ static_assert(kNumOperators == 8, "New gate types are not considered!"); -class GateTest : public ::testing::Test { - protected: - void SetUp() override { +class GateTest { + public: + GateTest() { var_one = std::make_shared(&graph); var_two = std::make_shared(&graph); var_three = std::make_shared(&graph); @@ -50,8 +54,7 @@ vars_.emplace_back(new Variable(&graph)); // Extra. } - void TearDown() override {} - + protected: /// Sets up the main gate with the default variables. /// /// @param[in] type Type for the main gate. @@ -87,49 +90,29 @@ std::vector vars_; // For convenience only. }; -#ifndef NDEBUG -TEST_F(GateTest, AddArgDeathTests) { - DefineGate(kNull, 1); - EXPECT_DEATH(g->AddArg(var_two), ""); - DefineGate(kNot, 1); - EXPECT_DEATH(g->AddArg(var_two), ""); - DefineGate(kXor, 2); - EXPECT_DEATH(g->AddArg(var_three), ""); - DefineGate(kAnd, 1); - EXPECT_DEATH(g->AddArg(1, var_two), ""); // Wrong index. - DefineGate(kAnd, 1); - EXPECT_DEATH(g->AddArg(0, var_two), ""); // Wrong index. - DefineGate(kAnd, 2); - g->MakeConstant(false); // Constant state. - EXPECT_DEATH(g->AddArg(var_two->index(), var_two), ""); // Wrong index. - DefineGate(kVote, 3); - g->vote_number(-1); // Negative vote number. - EXPECT_DEATH(g->AddArg(var_three->index(), var_three), ""); -} -#endif - /// Collection of tests /// for addition of an existing argument to a gate. /// /// @param short_type Short name of the gate, i.e., 'And'. /// It must have the same root in Operator, i.e., 'kAnd'. /// @param num_vars The number of variables to initialize the gate. -#define ADD_ARG_IGNORE_TEST(short_type, num_vars) \ - DefineGate(k##short_type, num_vars); \ - g->AddArg(var_one); \ - ASSERT_FALSE(g->constant()); \ - EXPECT_EQ(num_vars, g->args().size()); \ - EXPECT_EQ(num_vars, g->args().size()); \ - EXPECT_TRUE(g->args().empty()) +#define ADD_ARG_IGNORE_TEST(short_type, num_vars) \ + DefineGate(k##short_type, num_vars); \ + g->AddArg(var_one); \ + REQUIRE_FALSE(g->constant()); \ + CHECK(g->args().size() == num_vars); \ + CHECK(g->args().size() == num_vars); \ + CHECK(g->args().empty()) /// Tests addition of an existing argument to PDAG gates /// that do not change the type of the gate. /// /// @param short_type Short name of the gate type, i.e., 'And'. -#define TEST_DUP_ARG_IGNORE(short_type) \ - TEST_F(GateTest, DuplicateArgIgnore##short_type) { \ - ADD_ARG_IGNORE_TEST(short_type, 2); \ - EXPECT_EQ(k##short_type, g->type()); \ +#define TEST_DUP_ARG_IGNORE(short_type) \ + TEST_CASE_METHOD(GateTest, "pdag." STR(DuplicateArgIgnore##short_type), \ + "[pdag]") { \ + ADD_ARG_IGNORE_TEST(short_type, 2); \ + CHECK(g->type() == k##short_type); \ } TEST_DUP_ARG_IGNORE(And) @@ -144,10 +127,11 @@ /// /// @param init_type Short name of the initial type of the gate, i.e., 'And'. /// @param final_type The resulting type of addition operation. -#define TEST_DUP_ARG_TYPE_CHANGE(init_type, final_type) \ - TEST_F(GateTest, DuplicateArgChange##init_type##Type) { \ - ADD_ARG_IGNORE_TEST(init_type, 1); \ - EXPECT_EQ(k##final_type, g->type()); \ +#define TEST_DUP_ARG_TYPE_CHANGE(init_type, final_type) \ + TEST_CASE_METHOD(GateTest, "pdag." STR(DuplicateArgChange##init_type##Type), \ + "[pdag]") { \ + ADD_ARG_IGNORE_TEST(init_type, 1); \ + CHECK(g->type() == k##final_type); \ } TEST_DUP_ARG_TYPE_CHANGE(Or, Null) @@ -158,75 +142,75 @@ #undef TEST_DUP_ARG_TYPE_CHANGE #undef ADD_ARG_IGNORE_TEST -TEST_F(GateTest, DuplicateArgXor) { +TEST_CASE_METHOD(GateTest, "pdag.DuplicateArgXor", "[pdag]") { DefineGate(kXor, 1); g->AddArg(var_one); - ASSERT_TRUE(g->constant()); - ASSERT_EQ(1, g->args().size()); - EXPECT_GT(0, *g->args().begin()); + REQUIRE(g->constant()); + REQUIRE(g->args().size() == 1); + CHECK(*g->args().begin() == -1); } -TEST_F(GateTest, DuplicateArgVoteToNull) { +TEST_CASE_METHOD(GateTest, "pdag.DuplicateArgVoteToNull", "[pdag]") { DefineGate(kVote, 2); g->AddArg(var_one); - ASSERT_FALSE(g->constant()); - EXPECT_EQ(kNull, g->type()); - EXPECT_EQ(1, g->args().size()); - EXPECT_EQ(var_two->index(), g->args().begin()->first); + REQUIRE_FALSE(g->constant()); + CHECK(g->type() == kNull); + CHECK(g->args().size() == 1); + CHECK(g->args().begin()->first == var_two->index()); } -TEST_F(GateTest, DuplicateArgVoteToAnd) { +TEST_CASE_METHOD(GateTest, "pdag.DuplicateArgVoteToAnd", "[pdag]") { DefineGate(kVote, 3); g->vote_number(3); // K equals to the number of input arguments. g->AddArg(var_one); - ASSERT_FALSE(g->constant()); - EXPECT_EQ(kAnd, g->type()); - EXPECT_EQ(2, g->args().size()); - ASSERT_EQ(1, g->args().size()); - EXPECT_EQ(var_one->index(), g->args().begin()->first); - ASSERT_EQ(1, g->args().size()); + REQUIRE_FALSE(g->constant()); + CHECK(g->type() == kAnd); + CHECK(g->args().size() == 2); + REQUIRE(g->args().size() == 1); + CHECK(g->args().begin()->first == var_one->index()); + REQUIRE(g->args().size() == 1); GatePtr sub = g->args().begin()->second; - EXPECT_EQ(kOr, sub->type()); // Special case. K/N is in general. - EXPECT_EQ(1, sub->vote_number()); // This is the reason. + CHECK(sub->type() == kOr); // Special case. K/N is in general. + CHECK(sub->vote_number() == 1); // This is the reason. Gate::ArgSet vars; vars.insert(var_two->index()); vars.insert(var_three->index()); - EXPECT_EQ(vars, sub->args()); - EXPECT_EQ(2, sub->args().size()); + CHECK(sub->args() == vars); + CHECK(sub->args().size() == 2); } -TEST_F(GateTest, DuplicateArgVoteToOrWithOneClone) { +TEST_CASE_METHOD(GateTest, "pdag.DuplicateArgVoteToOrWithOneClone", "[pdag]") { DefineGate(kVote, 3); g->vote_number(2); g->AddArg(var_one); - ASSERT_FALSE(g->constant()); - EXPECT_EQ(kOr, g->type()); - EXPECT_EQ(2, g->args().size()); - ASSERT_EQ(1, g->args().size()); - EXPECT_EQ(var_one->index(), g->args().begin()->first); - ASSERT_EQ(1, g->args().size()); + REQUIRE_FALSE(g->constant()); + CHECK(g->type() == kOr); + CHECK(g->args().size() == 2); + REQUIRE(g->args().size() == 1); + CHECK(g->args().begin()->first == var_one->index()); + REQUIRE(g->args().size() == 1); GatePtr sub = g->args().begin()->second; - EXPECT_EQ(kAnd, sub->type()); // Special case. K/N is in general. - EXPECT_EQ(2, sub->vote_number()); - EXPECT_EQ(2, sub->args().size()); // This is the reason. + CHECK(sub->type() == kAnd); // Special case. K/N is in general. + CHECK(sub->vote_number() == 2); + CHECK(sub->args().size() == 2); // This is the reason. Gate::ArgSet vars; vars.insert(var_two->index()); vars.insert(var_three->index()); - EXPECT_EQ(vars, sub->args()); - EXPECT_EQ(2, sub->args().size()); + CHECK(sub->args() == vars); + CHECK(sub->args().size() == 2); } -TEST_F(GateTest, DuplicateArgVoteToOrWithTwoClones) { +TEST_CASE_METHOD(GateTest, "pdag.DuplicateArgVoteToOrWithTwoClones", "[pdag]") { DefineGate(kVote, 5); g->vote_number(3); g->AddArg(var_one); - ASSERT_FALSE(g->constant()); - EXPECT_EQ(kOr, g->type()); - EXPECT_EQ(2, g->args().size()); - EXPECT_TRUE(g->args().empty()); - ASSERT_EQ(2, g->args().size()); + REQUIRE_FALSE(g->constant()); + CHECK(g->type() == kOr); + CHECK(g->args().size() == 2); + CHECK(g->args().empty()); + REQUIRE(g->args().size() == 2); auto it = g->args().begin(); GatePtr and_gate = it->second; // Guessing. ++it; @@ -234,26 +218,26 @@ // Correcting the guess. if (and_gate->type() != kAnd) std::swap(and_gate, clone_one); - ASSERT_EQ(kAnd, and_gate->type()); - ASSERT_EQ(kVote, clone_one->type()); + REQUIRE(and_gate->type() == kAnd); + REQUIRE(clone_one->type() == kVote); - ASSERT_FALSE(clone_one->constant()); - EXPECT_EQ(3, clone_one->vote_number()); - EXPECT_EQ(4, clone_one->args().size()); - EXPECT_EQ(4, clone_one->args().size()); - - ASSERT_FALSE(and_gate->constant()); - EXPECT_EQ(2, and_gate->args().size()); - ASSERT_EQ(1, and_gate->args().size()); - EXPECT_EQ(var_one->index(), and_gate->args().begin()->first); - ASSERT_EQ(1, and_gate->args().size()); + REQUIRE_FALSE(clone_one->constant()); + CHECK(clone_one->vote_number() == 3); + CHECK(clone_one->args().size() == 4); + CHECK(clone_one->args().size() == 4); + + REQUIRE_FALSE(and_gate->constant()); + CHECK(and_gate->args().size() == 2); + REQUIRE(and_gate->args().size() == 1); + CHECK(and_gate->args().begin()->first == var_one->index()); + REQUIRE(and_gate->args().size() == 1); GatePtr clone_two = and_gate->args().begin()->second; - ASSERT_FALSE(clone_two->constant()); - EXPECT_EQ(kOr, clone_two->type()); // Special case. K/N is in general. - EXPECT_EQ(1, clone_two->vote_number()); // This is the reason. - EXPECT_EQ(4, clone_two->args().size()); - EXPECT_EQ(4, clone_two->args().size()); + REQUIRE_FALSE(clone_two->constant()); + CHECK(clone_two->type() == kOr); // Special case. K/N is in general. + CHECK(clone_two->vote_number() == 1); // This is the reason. + CHECK(clone_two->args().size() == 4); + CHECK(clone_two->args().size() == 4); } /// Collection of tests @@ -262,15 +246,16 @@ /// @param short_type Short name of the gate, i.e., 'And'. /// It must have the same root in Operator, i.e., 'kAnd'. /// @param const_state The notion of Boolean constant in the gate (TRUE/FALSE). -#define TEST_ADD_COMPLEMENT_ARG(short_type, const_state) \ - TEST_F(GateTest, ComplementArg##short_type) { \ - DefineGate(k##short_type, 1); \ - g->AddArg(var_one, true); \ - ASSERT_TRUE(g->constant()); \ - ASSERT_EQ(1, g->args().size()); \ - ASSERT_##const_state(*g->args().begin() > 0); \ - EXPECT_TRUE(g->args().empty()); \ - EXPECT_TRUE(g->args().empty()); \ +#define TEST_ADD_COMPLEMENT_ARG(short_type, const_state) \ + TEST_CASE_METHOD(GateTest, "pdag." STR(ComplementArg##short_type), \ + "[pdag]") { \ + DefineGate(k##short_type, 1); \ + g->AddArg(var_one, true); \ + REQUIRE(g->constant()); \ + REQUIRE(g->args().size() == 1); \ + ASSERT_##const_state(*g->args().begin() > 0); \ + CHECK(g->args().empty()); \ + CHECK(g->args().empty()); \ } TEST_ADD_COMPLEMENT_ARG(And, FALSE) @@ -287,17 +272,18 @@ /// @param num_vars Initial number of variables. /// @param v_num Initial K number of the gate. /// @param final_type Short name of the final type of the gate, i.e., 'And'. -#define TEST_ADD_COMPLEMENT_ARG_KN(num_vars, v_num, final_type) \ - TEST_F(GateTest, ComplementArgVoteTo##final_type) { \ - DefineGate(kVote, num_vars); \ - g->vote_number(v_num); \ - g->AddArg(var_one, true); \ - ASSERT_FALSE(g->constant()); \ - EXPECT_EQ(k##final_type, g->type()); \ - EXPECT_EQ(num_vars - 1, g->args().size()); \ - EXPECT_EQ(num_vars - 1, g->args().size()); \ - EXPECT_EQ(v_num - 1, g->vote_number()); \ - EXPECT_TRUE(g->args().empty()); \ +#define TEST_ADD_COMPLEMENT_ARG_KN(num_vars, v_num, final_type) \ + TEST_CASE_METHOD(GateTest, "pdag." STR(ComplementArgVoteTo##final_type), \ + "[pdag]") { \ + DefineGate(kVote, num_vars); \ + g->vote_number(v_num); \ + g->AddArg(var_one, true); \ + REQUIRE_FALSE(g->constant()); \ + CHECK(g->type() == k##final_type); \ + CHECK(g->args().size() == (num_vars - 1)); \ + CHECK(g->args().size() == (num_vars - 1)); \ + CHECK(g->vote_number() == (v_num - 1)); \ + CHECK(g->args().empty()); \ } TEST_ADD_COMPLEMENT_ARG_KN(2, 2, Null) // Join operation. @@ -314,14 +300,15 @@ /// @param init_type The initial type of the gate. /// @param const_state The notion of Boolean constant in the gate (TRUE/FALSE). #define TEST_CONSTANT_ARG_STATE(arg_state, num_vars, init_type, const_state) \ - TEST_F(GateTest, arg_state##ConstantArg##init_type) { \ + TEST_CASE_METHOD(GateTest, "pdag." STR(arg_state##ConstantArg##init_type), \ + "[pdag]") { \ DefineGate(k##init_type, num_vars); \ g->ProcessConstantArg(var_one, arg_state); \ - ASSERT_TRUE(g->constant()); \ - ASSERT_EQ(1, g->args().size()); \ + REQUIRE(g->constant()); \ + REQUIRE(g->args().size() == 1); \ ASSERT_##const_state(*g->args().begin() > 0); \ - EXPECT_TRUE(g->args().empty()); \ - EXPECT_TRUE(g->args().empty()); \ + CHECK(g->args().empty()); \ + CHECK(g->args().empty()); \ } TEST_CONSTANT_ARG_STATE(true, 1, Null, TRUE) @@ -343,18 +330,21 @@ /// @param v_num The initial vote number of the gate. /// @param init_type The initial type of the gate. /// @param final_type The final type of the gate. -#define TEST_CONSTANT_ARG_VNUM(arg_state, num_vars, v_num, init_type, \ - final_type) \ - TEST_F(GateTest, arg_state##ConstantArg##init_type##To##final_type) { \ - DefineGate(k##init_type, num_vars); \ - if (v_num) \ - g->vote_number(v_num); \ - g->ProcessConstantArg(var_one, arg_state); \ - ASSERT_FALSE(g->constant()); \ - EXPECT_EQ(k##final_type, g->type()); \ - EXPECT_EQ(num_vars - 1, g->args().size()); \ - EXPECT_EQ(num_vars - 1, g->args().size()); \ - EXPECT_TRUE(g->args().empty()); \ +#define TEST_CONSTANT_ARG_VNUM(arg_state, num_vars, v_num, init_type, \ + final_type) \ + TEST_CASE_METHOD( \ + GateTest, \ + "pdag." STR(arg_state##ConstantArg##init_type##To##final_type), \ + "[pdag]") { \ + DefineGate(k##init_type, num_vars); \ + if (v_num) \ + g->vote_number(v_num); \ + g->ProcessConstantArg(var_one, arg_state); \ + REQUIRE_FALSE(g->constant()); \ + CHECK(g->type() == k##final_type); \ + CHECK(g->args().size() == (num_vars - 1)); \ + CHECK(g->args().size() == (num_vars - 1)); \ + CHECK(g->args().empty()); \ } TEST_CONSTANT_ARG_VNUM(true, 3, 2, Vote, Or) @@ -381,6 +371,4 @@ #undef TEST_CONSTANT_ARG_VNUM #undef TEST_CONSTANT_ARG -} // namespace test -} // namespace core -} // namespace scram +} // namespace scram::core::test diff -Nru scram-0.16.1/tests/performance_tests.cc scram-0.16.2/tests/performance_tests.cc --- scram-0.16.1/tests/performance_tests.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/performance_tests.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -46,52 +46,50 @@ #include "bdd.h" #include "zbdd.h" -namespace scram { -namespace core { -namespace test { +namespace scram::core::test { // Regression check for performance assumptions of developers. #ifndef NDEBUG // Test for performance critical object sizes. -TEST(RegressionTest, ObjectSize) { +TEST_CASE("regression test BDD/ZBDD", "[object_size]") { // x86-64 platform. // 64-bit platform with alignment at 8-byte boundaries. - EXPECT_EQ(8, sizeof(WeakIntrusivePtr>)); - EXPECT_EQ(8, sizeof(IntrusivePtr>)); - EXPECT_EQ(16, sizeof(Vertex)); - EXPECT_EQ(48, sizeof(NonTerminal)); - EXPECT_EQ(64, sizeof(Ite)); - EXPECT_EQ(56, sizeof(SetNode)); + CHECK(sizeof(WeakIntrusivePtr>) == 8); + CHECK(sizeof(IntrusivePtr>) == 8); + CHECK(sizeof(Vertex) == 16); + CHECK(sizeof(NonTerminal) == 48); + CHECK(sizeof(Ite) == 64); + CHECK(sizeof(SetNode) == 56); } #endif // Tests the performance of probability calculations. -TEST_F(PerformanceTest, DISABLED_ThreeMotor) { +TEST_CASE_METHOD(PerformanceTest, "probability", "[.perf]") { double p_time_std = 0.01; std::string input = "input/ThreeMotor/three_motor.xml"; settings.probability_analysis(true); - ASSERT_NO_THROW(Analyze({input})); - EXPECT_LT(ProbabilityCalculationTime(), p_time_std); + REQUIRE_NOTHROW(Analyze({input})); + REQUIRE(ProbabilityCalculationTime() < p_time_std); } -TEST_F(PerformanceTest, DISABLED_ChineseTree) { +TEST_CASE_METHOD(PerformanceTest, "perf chinese", "[.perf]") { double mcs_time = 0.1; std::vector input_files{ "input/Chinese/chinese.xml", "input/Chinese/chinese-basic-events.xml"}; settings.probability_analysis(false); - ASSERT_NO_THROW(Analyze(input_files)); - EXPECT_LT(ProductGenerationTime(), mcs_time); + REQUIRE_NOTHROW(Analyze(input_files)); + REQUIRE(ProductGenerationTime() < mcs_time); } -TEST_F(PerformanceTest, DISABLED_200Event) { +TEST_CASE_METHOD(PerformanceTest, "perf 200Event", "[.perf]") { double mcs_time = 0.2; std::string input = "input/Autogenerated/200_event.xml"; - ASSERT_NO_THROW(Analyze({input})); - EXPECT_EQ(15347, NumOfProducts()); - EXPECT_LT(ProductGenerationTime(), mcs_time); + REQUIRE_NOTHROW(Analyze({input})); + CHECK(NumOfProducts() == 15347); + CHECK(ProductGenerationTime() < mcs_time); } -TEST_F(PerformanceTest, DISABLED_Baobab1L7) { +TEST_CASE_METHOD(PerformanceTest, "perf Baobab1L7", "[.perf]") { double mcs_time = 1.8; #ifdef NDEBUG mcs_time = 0.35; @@ -99,12 +97,12 @@ std::vector input_files{"input/Baobab/baobab1.xml", "input/Baobab/baobab1-basic-events.xml"}; settings.limit_order(7); - ASSERT_NO_THROW(Analyze(input_files)); - EXPECT_EQ(17432, NumOfProducts()); - EXPECT_NEAR(mcs_time, ProductGenerationTime(), mcs_time * delta); + REQUIRE_NOTHROW(Analyze(input_files)); + CHECK(NumOfProducts() == 17432); + CHECK(ProductGenerationTime() == Approx(mcs_time).epsilon(delta)); } -TEST_F(PerformanceTest, DISABLED_CEA9601_L4) { +TEST_CASE_METHOD(PerformanceTest, "perf CEA9601_L4", "[.perf]") { double mcs_time = 7.7; #ifdef NDEBUG mcs_time = 2.0; @@ -112,55 +110,55 @@ std::vector input_files{ "input/CEA9601/CEA9601.xml", "input/CEA9601/CEA9601-basic-events.xml"}; settings.limit_order(4).algorithm("bdd"); - ASSERT_NO_THROW(Analyze(input_files)); - EXPECT_EQ(54436, NumOfProducts()); - EXPECT_NEAR(mcs_time, ProductGenerationTime(), mcs_time * delta); + REQUIRE_NOTHROW(Analyze(input_files)); + CHECK(NumOfProducts() == 54436); + CHECK(ProductGenerationTime() == Approx(mcs_time).epsilon(delta)); } #ifdef NDEBUG -TEST_F(PerformanceTest, DISABLED_CEA9601_L5) { +TEST_CASE_METHOD(PerformanceTest, "perf CEA9601_L5", "[.perf]") { double mcs_time = 3.8; std::vector input_files{ "input/CEA9601/CEA9601.xml", "input/CEA9601/CEA9601-basic-events.xml"}; settings.limit_order(5).algorithm("bdd"); - ASSERT_NO_THROW(Analyze(input_files)); - EXPECT_EQ(1615876, NumOfProducts()); - EXPECT_NEAR(mcs_time, ProductGenerationTime(), mcs_time * delta); + REQUIRE_NOTHROW(Analyze(input_files)); + CHECK(NumOfProducts() == 1615876); + CHECK(ProductGenerationTime() == Approx(mcs_time).epsilon(delta)); } -TEST_F(PerformanceTest, DISABLED_CEA9601_L3_ZBDD) { +TEST_CASE_METHOD(PerformanceTest, "perf CEA9601_L3_ZBDD", "[.perf]") { double mcs_time = 1.5; std::vector input_files{ "input/CEA9601/CEA9601.xml", "input/CEA9601/CEA9601-basic-events.xml"}; settings.limit_order(3).algorithm("zbdd"); - ASSERT_NO_THROW(Analyze(input_files)); - EXPECT_EQ(1144, NumOfProducts()); - EXPECT_NEAR(mcs_time, ProductGenerationTime(), mcs_time * delta); + REQUIRE_NOTHROW(Analyze(input_files)); + CHECK(NumOfProducts() == 1144); + CHECK(ProductGenerationTime() == Approx(mcs_time).epsilon(delta)); } #endif -TEST_F(PerformanceTest, DISABLED_Baobab2) { +TEST_CASE_METHOD(PerformanceTest, "perf Baobab2", "[.perf]") { double mcs_time = 0.1; std::vector input_files{"input/Baobab/baobab2.xml", "input/Baobab/baobab2-basic-events.xml"}; - ASSERT_NO_THROW(Analyze(input_files)); - EXPECT_EQ(4805, NumOfProducts()); - EXPECT_LT(ProductGenerationTime(), mcs_time); + REQUIRE_NOTHROW(Analyze(input_files)); + CHECK(NumOfProducts() == 4805); + CHECK(ProductGenerationTime() < mcs_time); } -TEST_F(PerformanceTest, DISABLED_Baobab1) { +TEST_CASE_METHOD(PerformanceTest, "perf Baobab1", "[.perf]") { double mcs_time = 1.9; #ifdef NDEBUG mcs_time = 0.30; #endif std::vector input_files{"input/Baobab/baobab1.xml", "input/Baobab/baobab1-basic-events.xml"}; - ASSERT_NO_THROW(Analyze(input_files)); - EXPECT_EQ(46188, NumOfProducts()); - EXPECT_NEAR(mcs_time, ProductGenerationTime(), mcs_time * delta); + REQUIRE_NOTHROW(Analyze(input_files)); + CHECK(NumOfProducts() == 46188); + CHECK(ProductGenerationTime() == Approx(mcs_time).epsilon(delta)); } -TEST_F(PerformanceTest, DISABLED_Baobab1_ZBDD) { +TEST_CASE_METHOD(PerformanceTest, "perf Baobab1_ZBDD", "[.perf]") { double mcs_time = 0.95; #ifdef NDEBUG mcs_time = 0.15; @@ -168,11 +166,9 @@ std::vector input_files{"input/Baobab/baobab1.xml", "input/Baobab/baobab1-basic-events.xml"}; settings.algorithm("zbdd"); - ASSERT_NO_THROW(Analyze(input_files)); - EXPECT_EQ(46188, NumOfProducts()); - EXPECT_NEAR(mcs_time, ProductGenerationTime(), mcs_time * delta); + REQUIRE_NOTHROW(Analyze(input_files)); + CHECK(NumOfProducts() == 46188); + CHECK(ProductGenerationTime() == Approx(mcs_time).epsilon(delta)); } -} // namespace test -} // namespace core -} // namespace scram +} // namespace scram::core::test diff -Nru scram-0.16.1/tests/performance_tests.h scram-0.16.2/tests/performance_tests.h --- scram-0.16.1/tests/performance_tests.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/performance_tests.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,32 +15,28 @@ * along with this program. If not, see . */ -#ifndef SCRAM_TESTS_PERFORMANCE_TESTS_H_ -#define SCRAM_TESTS_PERFORMANCE_TESTS_H_ +#pragma once #include #include -#include +#include #include "fault_tree_analysis.h" #include "initializer.h" #include "probability_analysis.h" #include "risk_analysis.h" -namespace scram { -namespace core { -namespace test { +namespace scram::core::test { -class PerformanceTest : public ::testing::Test { - protected: - void SetUp() override { +class PerformanceTest { + public: + PerformanceTest() { settings.algorithm("mocus"); delta = 0.10; // % variation of values. } - void TearDown() override {} - + protected: // Convenient function to manage analysis of one model in input files. void Analyze(const std::vector& input_files) { { @@ -82,8 +78,4 @@ double delta; // The range indicator for values. }; -} // namespace test -} // namespace core -} // namespace scram - -#endif // SCRAM_TESTS_PERFORMANCE_TESTS_H_ +} // namespace scram::core::test diff -Nru scram-0.16.1/tests/risk_analysis_tests.cc scram-0.16.2/tests/risk_analysis_tests.cc --- scram-0.16.1/tests/risk_analysis_tests.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/risk_analysis_tests.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,21 +27,21 @@ #include "reporter.h" #include "xml.h" -namespace scram { -namespace core { -namespace test { +namespace scram::core::test { + +const char* scram::core::test::RiskAnalysisTest::parameter_ = nullptr; const std::set> RiskAnalysisTest::kUnity = { std::set{}}; -void RiskAnalysisTest::SetUp() { +RiskAnalysisTest::RiskAnalysisTest() { if (HasParam()) { - std::string param = GetParam(); + std::string_view param = GetParam(); if (param == "pi") { settings.algorithm("bdd"); settings.prime_implicants(true); } else { - settings.algorithm(GetParam()); + settings.algorithm(param); } } } @@ -55,15 +55,15 @@ } void RiskAnalysisTest::CheckReport(const std::vector& tree_input) { - static xml::Validator validator(Env::report_schema()); + static xml::Validator validator(env::report_schema()); - ASSERT_NO_THROW(ProcessInputFiles(tree_input)); - ASSERT_NO_THROW(analysis->Analyze()); + REQUIRE_NOTHROW(ProcessInputFiles(tree_input)); + REQUIRE_NOTHROW(analysis->Analyze()); fs::path temp_file = utility::GenerateFilePath(); - ASSERT_NO_THROW(Reporter().Report(*analysis, temp_file.string())) - << tree_input.front() << " => " << temp_file; - ASSERT_NO_THROW(xml::Document(temp_file.string(), &validator)) - << tree_input.front() << " => " << temp_file; + INFO("input: " + tree_input.front()); + INFO("output: " + temp_file.string()); + REQUIRE_NOTHROW(Reporter().Report(*analysis, temp_file.string())); + REQUIRE_NOTHROW(xml::Document(temp_file.string(), &validator)); fs::remove(temp_file); } @@ -126,91 +126,91 @@ TEST_F(RiskAnalysisTest, ProcessInput) { std::string tree_input = "tests/input/fta/correct_tree_input.xml"; - ASSERT_NO_THROW(ProcessInputFiles({tree_input})); - EXPECT_EQ(3, gates().size()); - EXPECT_EQ(1, gates().count("TrainOne")); - EXPECT_EQ(1, gates().count("TrainTwo")); - EXPECT_EQ(1, gates().count("TopEvent")); - EXPECT_EQ(4, basic_events().size()); - EXPECT_EQ(1, basic_events().count("PumpOne")); - EXPECT_EQ(1, basic_events().count("PumpTwo")); - EXPECT_EQ(1, basic_events().count("ValveOne")); - EXPECT_EQ(1, basic_events().count("ValveTwo")); + REQUIRE_NOTHROW(ProcessInputFiles({tree_input})); + CHECK(gates().size() == 3); + CHECK(gates().count("TrainOne") == 1); + CHECK(gates().count("TrainTwo") == 1); + CHECK(gates().count("TopEvent") == 1); + CHECK(basic_events().size() == 4); + CHECK(basic_events().count("PumpOne") == 1); + CHECK(basic_events().count("PumpTwo") == 1); + CHECK(basic_events().count("ValveOne") == 1); + CHECK(basic_events().count("ValveTwo") == 1); - ASSERT_TRUE(gates().count("TopEvent")); + REQUIRE(gates().count("TopEvent")); mef::Gate* top = gates().find("TopEvent")->get(); - EXPECT_EQ("TopEvent", top->id()); - ASSERT_NO_THROW(top->formula().type()); - EXPECT_EQ(mef::kAnd, top->formula().type()); - EXPECT_EQ(2, top->formula().event_args().size()); + CHECK(top->id() == "TopEvent"); + REQUIRE_NOTHROW(top->formula().type()); + CHECK(top->formula().type() == mef::kAnd); + CHECK(top->formula().event_args().size() == 2); - ASSERT_TRUE(gates().count("TrainOne")); + REQUIRE(gates().count("TrainOne")); mef::Gate* inter = gates().find("TrainOne")->get(); - EXPECT_EQ("TrainOne", inter->id()); - ASSERT_NO_THROW(inter->formula().type()); - EXPECT_EQ(mef::kOr, inter->formula().type()); - EXPECT_EQ(2, inter->formula().event_args().size()); + CHECK(inter->id() == "TrainOne"); + REQUIRE_NOTHROW(inter->formula().type()); + CHECK(inter->formula().type() == mef::kOr); + CHECK(inter->formula().event_args().size() == 2); - ASSERT_TRUE(basic_events().count("ValveOne")); + REQUIRE(basic_events().count("ValveOne")); mef::BasicEvent* primary = basic_events().find("ValveOne")->get(); - EXPECT_EQ("ValveOne", primary->id()); + CHECK(primary->id() == "ValveOne"); } // Test Probability Assignment TEST_F(RiskAnalysisTest, PopulateProbabilities) { // Input with probabilities std::string tree_input = "tests/input/fta/correct_tree_input_with_probs.xml"; - ASSERT_NO_THROW(ProcessInputFiles({tree_input})); - ASSERT_EQ(4, basic_events().size()); - ASSERT_EQ(1, basic_events().count("PumpOne")); - ASSERT_EQ(1, basic_events().count("PumpTwo")); - ASSERT_EQ(1, basic_events().count("ValveOne")); - ASSERT_EQ(1, basic_events().count("ValveTwo")); + REQUIRE_NOTHROW(ProcessInputFiles({tree_input})); + REQUIRE(basic_events().size() == 4); + REQUIRE(basic_events().count("PumpOne") == 1); + REQUIRE(basic_events().count("PumpTwo") == 1); + REQUIRE(basic_events().count("ValveOne") == 1); + REQUIRE(basic_events().count("ValveTwo") == 1); mef::BasicEvent* p1 = basic_events().find("PumpOne")->get(); mef::BasicEvent* p2 = basic_events().find("PumpTwo")->get(); mef::BasicEvent* v1 = basic_events().find("ValveOne")->get(); mef::BasicEvent* v2 = basic_events().find("ValveTwo")->get(); - ASSERT_NO_THROW(p1->p()); - ASSERT_NO_THROW(p2->p()); - ASSERT_NO_THROW(v1->p()); - ASSERT_NO_THROW(v2->p()); - EXPECT_EQ(0.6, p1->p()); - EXPECT_EQ(0.7, p2->p()); - EXPECT_EQ(0.4, v1->p()); - EXPECT_EQ(0.5, v2->p()); + REQUIRE_NOTHROW(p1->p()); + REQUIRE_NOTHROW(p2->p()); + REQUIRE_NOTHROW(v1->p()); + REQUIRE_NOTHROW(v2->p()); + CHECK(p1->p() == 0.6); + CHECK(p2->p() == 0.7); + CHECK(v1->p() == 0.4); + CHECK(v2->p() == 0.5); } // Test Analysis of Two train system. TEST_P(RiskAnalysisTest, AnalyzeDefault) { std::string tree_input = "tests/input/fta/correct_tree_input.xml"; - ASSERT_NO_THROW(ProcessInputFiles({tree_input})); - ASSERT_NO_THROW(analysis->Analyze()); + REQUIRE_NOTHROW(ProcessInputFiles({tree_input})); + REQUIRE_NOTHROW(analysis->Analyze()); std::set> mcs = {{"PumpOne", "PumpTwo"}, {"PumpOne", "ValveTwo"}, {"PumpTwo", "ValveOne"}, {"ValveOne", "ValveTwo"}}; - EXPECT_EQ(mcs, products()); + CHECK(products() == mcs); PrintProducts(); // Quick visual verification. } TEST_P(RiskAnalysisTest, AnalyzeNonCoherentDefault) { std::string tree_input = "tests/input/fta/correct_non_coherent.xml"; - ASSERT_NO_THROW(ProcessInputFiles({tree_input})); - ASSERT_NO_THROW(analysis->Analyze()); + REQUIRE_NOTHROW(ProcessInputFiles({tree_input})); + REQUIRE_NOTHROW(analysis->Analyze()); if (settings.prime_implicants()) { std::set> pi = {{"not PumpOne", "ValveOne"}, {"PumpOne", "PumpTwo"}, {"PumpOne", "ValveTwo"}, {"PumpTwo", "ValveOne"}, {"ValveOne", "ValveTwo"}}; - EXPECT_EQ(5, products().size()); - EXPECT_EQ(pi, products()); + CHECK(products().size() == 5); + CHECK(products() == pi); } else { std::set> mcs = { {"PumpOne", "PumpTwo"}, {"PumpOne", "ValveTwo"}, {"ValveOne"}}; - EXPECT_EQ(mcs, products()); + CHECK(products() == mcs); } } @@ -222,19 +222,19 @@ std::set mcs_4 = {"ValveOne", "ValveTwo"}; std::set> mcs = {mcs_1, mcs_2, mcs_3, mcs_4}; settings.probability_analysis(true); - ASSERT_NO_THROW(ProcessInputFiles({with_prob})); - ASSERT_NO_THROW(analysis->Analyze()); + REQUIRE_NOTHROW(ProcessInputFiles({with_prob})); + REQUIRE_NOTHROW(analysis->Analyze()); - EXPECT_EQ(mcs, products()); + CHECK(products() == mcs); if (settings.approximation() == Approximation::kRareEvent) { - EXPECT_DOUBLE_EQ(1, p_total()); + CHECK(p_total() == Approx(1)); } else { - EXPECT_DOUBLE_EQ(0.646, p_total()); + CHECK(p_total() == Approx(0.646)); } - EXPECT_DOUBLE_EQ(0.42, product_probability().at(mcs_1)); - EXPECT_DOUBLE_EQ(0.3, product_probability().at(mcs_2)); - EXPECT_DOUBLE_EQ(0.28, product_probability().at(mcs_3)); - EXPECT_DOUBLE_EQ(0.2, product_probability().at(mcs_4)); + CHECK(product_probability().at(mcs_1) == Approx(0.42)); + CHECK(product_probability().at(mcs_2) == Approx(0.3)); + CHECK(product_probability().at(mcs_3) == Approx(0.28)); + CHECK(product_probability().at(mcs_4) == Approx(0.2)); } // Test for exact probability calculation @@ -242,9 +242,9 @@ TEST_P(RiskAnalysisTest, EnforceExactProbability) { std::string with_prob = "tests/input/fta/correct_tree_input_with_probs.xml"; settings.probability_analysis(true).approximation("none"); - ASSERT_NO_THROW(ProcessInputFiles({with_prob})); - ASSERT_NO_THROW(analysis->Analyze()); - EXPECT_DOUBLE_EQ(0.646, p_total()); + REQUIRE_NOTHROW(ProcessInputFiles({with_prob})); + REQUIRE_NOTHROW(analysis->Analyze()); + CHECK(p_total() == Approx(0.646)); } TEST_P(RiskAnalysisTest, AnalyzeNestedFormula) { @@ -253,16 +253,16 @@ {"PumpOne", "ValveTwo"}, {"PumpTwo", "ValveOne"}, {"ValveOne", "ValveTwo"}}; - ASSERT_NO_THROW(ProcessInputFiles({nested_input})); - ASSERT_NO_THROW(analysis->Analyze()); - EXPECT_EQ(mcs, products()); + REQUIRE_NOTHROW(ProcessInputFiles({nested_input})); + REQUIRE_NOTHROW(analysis->Analyze()); + CHECK(products() == mcs); } TEST_F(RiskAnalysisTest, ImportanceDefault) { std::string with_prob = "tests/input/fta/correct_tree_input_with_probs.xml"; settings.importance_analysis(true); - ASSERT_NO_THROW(ProcessInputFiles({with_prob})); - ASSERT_NO_THROW(analysis->Analyze()); + REQUIRE_NOTHROW(ProcessInputFiles({with_prob})); + REQUIRE_NOTHROW(analysis->Analyze()); TestImportance({{"PumpOne", {2, 0.51, 0.4737, 0.7895, 1.316, 1.9}}, {"PumpTwo", {2, 0.38, 0.4118, 0.8235, 1.176, 1.7}}, {"ValveOne", {2, 0.34, 0.2105, 0.5263, 1.316, 1.267}}, @@ -272,9 +272,9 @@ TEST_F(RiskAnalysisTest, ImportanceNeg) { std::string tree_input = "tests/input/fta/importance_neg_test.xml"; settings.prime_implicants(true).importance_analysis(true); - ASSERT_NO_THROW(ProcessInputFiles({tree_input})); - ASSERT_NO_THROW(analysis->Analyze()); - EXPECT_NEAR(0.04459, p_total(), 1e-3); + REQUIRE_NOTHROW(ProcessInputFiles({tree_input})); + REQUIRE_NOTHROW(analysis->Analyze()); + CHECK(p_total() == Approx(0.04459)); // Check importance values with negative event. TestImportance({{"PumpOne", {3, 0.0765, 0.1029, 0.1568, 2.613, 1.115}}, {"PumpTwo", {2, 0.057, 0.08948, 0.1532, 2.189, 1.098}}, @@ -285,24 +285,24 @@ TEST_P(RiskAnalysisTest, ImportanceSingleEvent) { std::string tree_input = "tests/input/core/null_a.xml"; settings.importance_analysis(true); - ASSERT_NO_THROW(ProcessInputFiles({tree_input})); - ASSERT_NO_THROW(analysis->Analyze()); + REQUIRE_NOTHROW(ProcessInputFiles({tree_input})); + REQUIRE_NOTHROW(analysis->Analyze()); TestImportance({{"OnlyChild", {1, 1, 1, 1, 2, 0}}}); } TEST_P(RiskAnalysisTest, ImportanceZeroProbability) { std::string tree_input = "tests/input/core/zero_prob.xml"; settings.importance_analysis(true); - ASSERT_NO_THROW(ProcessInputFiles({tree_input})); - ASSERT_NO_THROW(analysis->Analyze()); + REQUIRE_NOTHROW(ProcessInputFiles({tree_input})); + REQUIRE_NOTHROW(analysis->Analyze()); TestImportance({{"A", {1, 1, 0, 0, 0, 0}}}); } TEST_P(RiskAnalysisTest, ImportanceOneProbability) { std::string tree_input = "tests/input/core/one_prob.xml"; settings.importance_analysis(true); - ASSERT_NO_THROW(ProcessInputFiles({tree_input})); - ASSERT_NO_THROW(analysis->Analyze()); + REQUIRE_NOTHROW(ProcessInputFiles({tree_input})); + REQUIRE_NOTHROW(analysis->Analyze()); TestImportance({{"A", {1, 1, 1, 1, 1, 0}}}); } @@ -311,9 +311,9 @@ std::string with_prob = "tests/input/fta/importance_test.xml"; // Probability calculations with the rare event approximation. settings.approximation("rare-event").importance_analysis(true); - ASSERT_NO_THROW(ProcessInputFiles({with_prob})); - ASSERT_NO_THROW(analysis->Analyze()); - EXPECT_DOUBLE_EQ(0.012, p_total()); // Adjusted probability. + REQUIRE_NOTHROW(ProcessInputFiles({with_prob})); + REQUIRE_NOTHROW(analysis->Analyze()); + CHECK(p_total() == Approx(0.012)); // Adjusted probability. TestImportance({{"PumpOne", {2, 0.12, 0.6, 0.624, 10.4, 2.5}}, {"PumpTwo", {2, 0.1, 0.5833, 0.6125, 8.75, 2.4}}, {"ValveOne", {2, 0.12, 0.4, 0.424, 10.6, 1.667}}, @@ -325,9 +325,9 @@ std::string with_prob = "tests/input/fta/correct_tree_input_with_probs.xml"; // Probability calculations with the MCUB approximation. settings.approximation("mcub").importance_analysis(true); - ASSERT_NO_THROW(ProcessInputFiles({with_prob})); - ASSERT_NO_THROW(analysis->Analyze()); - EXPECT_DOUBLE_EQ(0.766144, p_total()); + REQUIRE_NOTHROW(ProcessInputFiles({with_prob})); + REQUIRE_NOTHROW(analysis->Analyze()); + CHECK(p_total() == Approx(0.766144)); } // Apply the minimal cut set upper bound approximation for non-coherent tree. @@ -336,9 +336,9 @@ std::string with_prob = "tests/input/core/a_and_not_b.xml"; // Probability calculations with the MCUB approximation. settings.approximation("mcub").probability_analysis(true); - ASSERT_NO_THROW(ProcessInputFiles({with_prob})); - ASSERT_NO_THROW(analysis->Analyze()); - EXPECT_NEAR(0.10, p_total(), 1e-5); + REQUIRE_NOTHROW(ProcessInputFiles({with_prob})); + REQUIRE_NOTHROW(analysis->Analyze()); + CHECK(p_total() == Approx(0.10)); } // Test Monte Carlo Analysis @@ -346,8 +346,8 @@ TEST_P(RiskAnalysisTest, AnalyzeMC) { settings.uncertainty_analysis(true); std::string tree_input = "tests/input/fta/correct_tree_input_with_probs.xml"; - ASSERT_NO_THROW(ProcessInputFiles({tree_input})); - ASSERT_NO_THROW(analysis->Analyze()); + REQUIRE_NOTHROW(ProcessInputFiles({tree_input})); + REQUIRE_NOTHROW(analysis->Analyze()); } TEST_P(RiskAnalysisTest, AnalyzeProbabilityOverTime) { @@ -355,25 +355,25 @@ settings.probability_analysis(true).time_step(24).mission_time(120); std::vector curve = {0, 2.399e-4, 4.7989e-4, 7.197e-4, 9.595e-4, 1.199e-3}; - ASSERT_NO_THROW(ProcessInputFiles({tree_input})); - ASSERT_NO_THROW(analysis->Analyze()); - ASSERT_FALSE(analysis->results().empty()); - ASSERT_TRUE(analysis->results().front().probability_analysis); + REQUIRE_NOTHROW(ProcessInputFiles({tree_input})); + REQUIRE_NOTHROW(analysis->Analyze()); + REQUIRE_FALSE(analysis->results().empty()); + REQUIRE(analysis->results().front().probability_analysis); auto it = curve.begin(); double time = 0; for (const std::pair& p_vs_time : analysis->results().front().probability_analysis->p_time()) { - ASSERT_NE(curve.end(), it); + REQUIRE_FALSE(it == curve.end()); if (time >= settings.mission_time()) { - EXPECT_EQ(settings.mission_time(), p_vs_time.second); + CHECK(p_vs_time.second == settings.mission_time()); } else { - EXPECT_EQ(time, p_vs_time.second); + CHECK(p_vs_time.second == time); } - EXPECT_NEAR(*it, p_vs_time.first, *it * 0.001); + CHECK(p_vs_time.first == Approx(*it).epsilon(1e-3)); time += settings.time_step(); ++it; } - ASSERT_TRUE(time); + REQUIRE(time); } TEST_P(RiskAnalysisTest, AnalyzeSil) { @@ -382,23 +382,24 @@ double pfd_fractions[] = {1.142e-4, 1.0275e-3, 1.02796e-2, 0.1033, 0.88527, 0}; double pfh_fractions[] = {2.74e-7, 2.466e-6, 2.466e-5, 2.466e-4, 0.999726, 0}; - ASSERT_NO_THROW(ProcessInputFiles({tree_input})); - ASSERT_NO_THROW(analysis->Analyze()); - ASSERT_FALSE(analysis->results().empty()); - ASSERT_TRUE(analysis->results().front().probability_analysis); + REQUIRE_NOTHROW(ProcessInputFiles({tree_input})); + REQUIRE_NOTHROW(analysis->Analyze()); + REQUIRE_FALSE(analysis->results().empty()); + REQUIRE(analysis->results().front().probability_analysis); const auto& prob_an = *analysis->results().front().probability_analysis; - EXPECT_NEAR(0.04255, prob_an.sil().pfd_avg, 0.00001); - EXPECT_NEAR(9.77e-6, prob_an.sil().pfh_avg, 1e-8); + CHECK(prob_an.sil().pfd_avg == Approx(0.04255).epsilon(1e-3)); + CHECK(prob_an.sil().pfh_avg == Approx(9.77e-6).epsilon(1e-3)); auto compare_fractions = [](const auto& sil_fractions, const auto& result, const char* type) { auto it = std::begin(sil_fractions); for (const std::pair& result_bucket : result) { - ASSERT_NE(std::end(sil_fractions), it); - EXPECT_NEAR(*it, result_bucket.second, *it * 0.001) - << "The " << type << " bucket for " << result_bucket.first; + CAPTURE(type); + INFO("bucket: " + std::to_string(result_bucket.first)); + REQUIRE_FALSE(it == std::end(sil_fractions)); + CHECK(result_bucket.second == Approx(*it).epsilon(1e-3)); ++it; } - ASSERT_EQ(std::end(sil_fractions), it); + REQUIRE(it == std::end(sil_fractions)); }; compare_fractions(pfd_fractions, prob_an.sil().pfd_fractions, "PFD"); compare_fractions(pfh_fractions, prob_an.sil().pfh_fractions, "PFH"); @@ -407,41 +408,42 @@ TEST_P(RiskAnalysisTest, AnalyzeEventTree) { const char* tree_input = "input/EventTrees/bcd.xml"; settings.probability_analysis(true); - ASSERT_NO_THROW(ProcessInputFiles({tree_input})); - ASSERT_NO_THROW(analysis->Analyze()); - EXPECT_EQ(1, analysis->event_tree_results().size()); + REQUIRE_NOTHROW(ProcessInputFiles({tree_input})); + REQUIRE_NOTHROW(analysis->Analyze()); + CHECK(analysis->event_tree_results().size() == 1); const auto& results = sequences(); - ASSERT_EQ(2, results.size()); + REQUIRE(results.size() == 2); std::map expected = {{"Success", 0.594}, {"Failure", 0.406}}; for (const auto& result : expected) { - ASSERT_TRUE(results.count(result.first)) << result.first; - EXPECT_DOUBLE_EQ(result.second, results.at(result.first)) << result.first; + INFO("state: " + result.first); + REQUIRE(results.count(result.first)); + CHECK(results.at(result.first) == Approx(result.second)); } } TEST_P(RiskAnalysisTest, AnalyzeTestEventDefault) { const char* tree_input = "tests/input/eta/test_event_default.xml"; settings.probability_analysis(true); - ASSERT_NO_THROW(ProcessInputFiles({tree_input})); - ASSERT_NO_THROW(analysis->Analyze()); - EXPECT_EQ(1, analysis->event_tree_results().size()); + REQUIRE_NOTHROW(ProcessInputFiles({tree_input})); + REQUIRE_NOTHROW(analysis->Analyze()); + CHECK(analysis->event_tree_results().size() == 1); const auto& results = sequences(); - ASSERT_EQ(1, results.size()); - EXPECT_EQ("S", results.begin()->first); - EXPECT_DOUBLE_EQ(0.5, results.begin()->second); + REQUIRE(results.size() == 1); + CHECK(results.begin()->first == "S"); + CHECK(results.begin()->second == Approx(0.5)); } TEST_P(RiskAnalysisTest, AnalyzeTestInitatingEvent) { const char* tree_input = "tests/input/eta/test_initiating_event.xml"; settings.probability_analysis(true); - ASSERT_NO_THROW(ProcessInputFiles({tree_input})); - ASSERT_NO_THROW(analysis->Analyze()); - EXPECT_EQ(1, analysis->event_tree_results().size()); + REQUIRE_NOTHROW(ProcessInputFiles({tree_input})); + REQUIRE_NOTHROW(analysis->Analyze()); + CHECK(analysis->event_tree_results().size() == 1); const auto& results = sequences(); - ASSERT_EQ(1, results.size()); - EXPECT_EQ("S", results.begin()->first); - EXPECT_DOUBLE_EQ(0.5, results.begin()->second); + REQUIRE(results.size() == 1); + CHECK(results.begin()->first == "S"); + CHECK(results.begin()->second == Approx(0.5)); } TEST_P(RiskAnalysisTest, AnalyzeTestFunctionalEvent) { @@ -449,13 +451,15 @@ "tests/input/eta/test_functional_event_link.xml"}; settings.probability_analysis(true); for (auto input : tree_input) { - ASSERT_NO_THROW(ProcessInputFiles({input})); - ASSERT_NO_THROW(analysis->Analyze()) << input; - EXPECT_EQ(1, analysis->event_tree_results().size()) << input; + REQUIRE_NOTHROW(ProcessInputFiles({input})); + CAPTURE(input); + REQUIRE_NOTHROW(analysis->Analyze()); + CHECK(analysis->event_tree_results().size() == 1); const auto& results = sequences(); - ASSERT_EQ(1, results.size()) << input; - EXPECT_EQ("S", results.begin()->first) << input; - EXPECT_DOUBLE_EQ(0.5, results.begin()->second) << input; + CAPTURE(input); + REQUIRE(results.size() == 1); + CHECK(results.begin()->first == "S"); + CHECK(results.begin()->second == Approx(0.5)); } } @@ -466,9 +470,9 @@ std::string tree_input = "tests/input/fta/correct_tree_input.xml"; // Messing up the output file. std::string output = "abracadabra.cadabraabra/output.txt"; - ASSERT_NO_THROW(ProcessInputFiles({tree_input})); - ASSERT_NO_THROW(analysis->Analyze()); - EXPECT_THROW(Reporter().Report(*analysis, output), IOError); + REQUIRE_NOTHROW(ProcessInputFiles({tree_input})); + REQUIRE_NOTHROW(analysis->Analyze()); + CHECK_THROWS_AS(Reporter().Report(*analysis, output), IOError); } TEST_F(RiskAnalysisTest, ReportEmpty) { @@ -580,57 +584,55 @@ // NAND and NOR as a child cases. TEST_P(RiskAnalysisTest, ChildNandNorGates) { std::string tree_input = "tests/input/fta/children_nand_nor.xml"; - ASSERT_NO_THROW(ProcessInputFiles({tree_input})); - ASSERT_NO_THROW(analysis->Analyze()); + REQUIRE_NOTHROW(ProcessInputFiles({tree_input})); + REQUIRE_NOTHROW(analysis->Analyze()); if (settings.prime_implicants()) { std::set> pi = { {"not PumpOne", "not PumpTwo", "not ValveOne"}, {"not PumpOne", "not ValveTwo", "not ValveOne"}}; - EXPECT_EQ(pi, products()); + CHECK(products() == pi); } else { - EXPECT_EQ(kUnity, products()); + CHECK(products() == kUnity); } } // Simple test for several house event propagation. TEST_P(RiskAnalysisTest, ManyHouseEvents) { std::string tree_input = "tests/input/fta/constant_propagation.xml"; - ASSERT_NO_THROW(ProcessInputFiles({tree_input})); - ASSERT_NO_THROW(analysis->Analyze()); + REQUIRE_NOTHROW(ProcessInputFiles({tree_input})); + REQUIRE_NOTHROW(analysis->Analyze()); std::set> mcs = {{"A", "B"}}; - EXPECT_EQ(mcs, products()); + CHECK(products() == mcs); } // Simple test for several constant gate propagation. TEST_P(RiskAnalysisTest, ConstantGates) { std::string tree_input = "tests/input/fta/constant_gates.xml"; - ASSERT_NO_THROW(ProcessInputFiles({tree_input})); - ASSERT_NO_THROW(analysis->Analyze()); - EXPECT_EQ(kUnity, products()); + REQUIRE_NOTHROW(ProcessInputFiles({tree_input})); + REQUIRE_NOTHROW(analysis->Analyze()); + CHECK(products() == kUnity); } // Mixed roles with undefined event types TEST_F(RiskAnalysisTest, UndefinedEventsMixedRoles) { std::string tree_input = "tests/input/fta/ambiguous_events_with_roles.xml"; - ASSERT_NO_THROW(ProcessInputFiles({tree_input})); - ASSERT_NO_THROW(analysis->Analyze()); + REQUIRE_NOTHROW(ProcessInputFiles({tree_input})); + REQUIRE_NOTHROW(analysis->Analyze()); std::set> mcs = { {"C", "Ambiguous.Private.A", "Ambiguous.Private.B"}, {"G", "Ambiguous.Private.A", "Ambiguous.Private.B"}}; - EXPECT_EQ(mcs, products()); + CHECK(products() == mcs); } // Extern function call check. TEST_P(RiskAnalysisTest, ExternFunctionProbability) { std::string tree_input = "tests/input/model/extern_full_check.xml"; settings.probability_analysis(true); - ASSERT_NO_THROW(ProcessInputFiles({tree_input}, true)); - ASSERT_NO_THROW(analysis->Analyze()); + REQUIRE_NOTHROW(ProcessInputFiles({tree_input}, true)); + REQUIRE_NOTHROW(analysis->Analyze()); std::set> mcs = {{"e1"}}; - EXPECT_EQ(mcs, products()); - EXPECT_DOUBLE_EQ(0.1, p_total()); + CHECK(products() == mcs); + CHECK(p_total() == Approx(0.1)); } -} // namespace test -} // namespace core -} // namespace scram +} // namespace scram::core::test diff -Nru scram-0.16.1/tests/risk_analysis_tests.h scram-0.16.2/tests/risk_analysis_tests.h --- scram-0.16.1/tests/risk_analysis_tests.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/risk_analysis_tests.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,31 +15,50 @@ * along with this program. If not, see . */ -#ifndef SCRAM_TESTS_RISK_ANALYSIS_TESTS_H_ -#define SCRAM_TESTS_RISK_ANALYSIS_TESTS_H_ +#pragma once #include "risk_analysis.h" #include #include -#include +#include #include -namespace scram { -namespace core { -namespace test { +/// Transitional macros from GoogleTest. +#define TEST_F(Fixture, Name) \ + TEST_CASE_METHOD(Fixture, #Fixture "." #Name, "[risk]") +/// Parametrized tests by the by analysis algorithms. +#define TEST_P(Fixture, Name) \ + TEST_CASE_METHOD(Fixture, #Fixture "." #Name, "[risk][bdd][pi][mocus][zbdd]") +#define ASSERT_NO_THROW REQUIRE_NOTHROW +#define EXPECT_NEAR(expected, value, delta) \ + CHECK((value) == Approx(expected).margin(delta)) +#define EXPECT_EQ(expected, value) CHECK((value) == (expected)) +#define EXPECT_DOUBLE_EQ(expected, value) CHECK((value) == Approx(expected)) +#define ASSERT_EQ(expected, value) REQUIRE((value) == (expected)) +#define ASSERT_DOUBLE_EQ(expected, value) REQUIRE((value) == Approx(expected)) +#define EXPECT_TRUE CHECK +#define ASSERT_TRUE REQUIRE + +int main(int argc, char* argv[]); ///< Sets the parameter. + +namespace scram::core::test { + +class RiskAnalysisTest { + friend int ::main(int argc, char* argv[]); ///< Sets the parameter. + static const char* parameter_; ///< Algorithm parameter. -class RiskAnalysisTest : public ::testing::TestWithParam { - protected: + public: using ImportanceContainer = std::vector>; static const std::set> kUnity; ///< Special unity set. - void SetUp() override; + RiskAnalysisTest(); + protected: // Parsing multiple input files. void ProcessInputFiles(const std::vector& input_files, bool allow_extern = false); @@ -95,12 +114,12 @@ } void TestImportance(const ImportanceContainer& expected) { -#define IMP_EQ(field) \ - EXPECT_NEAR(test.field, result.field, (1e-3 * result.field)) << entry.first +#define IMP_EQ(field) CHECK(result.field == Approx(test.field).epsilon(1e-3)) for (const auto& entry : expected) { + INFO("event: " + entry.first); const ImportanceFactors& result = importance(entry.first); const ImportanceFactors& test = entry.second; - EXPECT_EQ(test.occurrence, result.occurrence) << entry.first; + CHECK(result.occurrence == test.occurrence); IMP_EQ(mif); IMP_EQ(cif); IMP_EQ(dif); @@ -137,14 +156,16 @@ /// Complements are communicated with "not" prefix. std::set Convert(const Product& product); + /// @todo Provide parametrized tests. + /// @{ + bool HasParam() { return parameter_; } + const char* GetParam() { return parameter_; } + /// @} + struct Result { std::map, double> product_probability; std::set> products; } result_; }; -} // namespace test -} // namespace core -} // namespace scram - -#endif // SCRAM_TESTS_RISK_ANALYSIS_TESTS_H_ +} // namespace scram::core::test diff -Nru scram-0.16.1/tests/scram_unit_test_driver.cc.in scram-0.16.2/tests/scram_unit_test_driver.cc.in --- scram-0.16.1/tests/scram_unit_test_driver.cc.in 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/scram_unit_test_driver.cc.in 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2015, 2017 Olzhas Rakhimov + * Copyright (C) 2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,29 +15,44 @@ * along with this program. If not, see . */ +#define CATCH_CONFIG_RUNNER + #include -#include +#include #include "risk_analysis_tests.h" -namespace scram { -namespace core { -namespace test { - -INSTANTIATE_TEST_CASE_P(BDD, RiskAnalysisTest, ::testing::Values("bdd")); -INSTANTIATE_TEST_CASE_P(PI, RiskAnalysisTest, ::testing::Values("pi")); -INSTANTIATE_TEST_CASE_P(ZBDD, RiskAnalysisTest, ::testing::Values("zbdd")); -INSTANTIATE_TEST_CASE_P(MOCUS, RiskAnalysisTest, ::testing::Values("mocus")); - -} // namespace test -} // namespace core -} // namespace scram - +/// @todo Provide proper parametrized tests. int main(int argc, char* argv[]) { boost::system::error_code ret; boost::filesystem::current_path("@CMAKE_SOURCE_DIR@", ret); assert(ret == 0); - ::testing::FLAGS_gtest_death_test_style = "threadsafe"; - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); + auto announce = [] { + Catch::cout() << "#################### Running with: " + << scram::core::test::RiskAnalysisTest::parameter_ + << " ####################" << std::endl; + }; + + Catch::Session session; + + // Workaround for parametrized tests. + scram::core::test::RiskAnalysisTest::parameter_ = "bdd"; + announce(); + bool code = session.run(argc, argv) > 0; // Catch abuses exit codes. + std::vector extra_args(argv, argv + argc); + extra_args.push_back(const_cast("[pi]")); + scram::core::test::RiskAnalysisTest::parameter_ = "pi"; + announce(); + code |= session.run(extra_args.size(), extra_args.data()) > 0; + + extra_args.back() = const_cast("[mocus]"); + scram::core::test::RiskAnalysisTest::parameter_ = "mocus"; + announce(); + code |= session.run(extra_args.size(), extra_args.data()) > 0; + + extra_args.back() = const_cast("[zbdd]"); + scram::core::test::RiskAnalysisTest::parameter_ = "zbdd"; + announce(); + code |= session.run(extra_args.size(), extra_args.data()) > 0; + return code; } diff -Nru scram-0.16.1/tests/serialization_tests.cc scram-0.16.2/tests/serialization_tests.cc --- scram-0.16.1/tests/serialization_tests.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/serialization_tests.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,7 +17,7 @@ #include "serialization.h" -#include +#include #include "utility.h" @@ -26,12 +26,12 @@ #include "settings.h" #include "xml.h" -namespace scram { -namespace mef { -namespace test { +namespace scram::mef::test { -TEST(SerializationTest, InputOutput) { - static xml::Validator validator(Env::install_dir() + "/share/scram/gui.rng"); +static int i = 0; + +TEST_CASE("SerializationTest.InputOutput", "[mef::serialization]") { + xml::Validator validator(env::install_dir() + "/share/scram/gui.rng"); std::vector> inputs = { {"tests/input/fta/correct_tree_input.xml"}, @@ -43,18 +43,18 @@ {"tests/input/fta/correct_formulas.xml"}, {"input/Theatre/theatre.xml"}, {"input/Baobab/baobab2.xml", "input/Baobab/baobab2-basic-events.xml"}}; + + std::shared_ptr model; for (const auto& input : inputs) { - std::shared_ptr model; - ASSERT_NO_THROW(model = mef::Initializer(input, core::Settings{}).model()); + INFO("inputs: " + + Catch::StringMaker>::convert(input)) + REQUIRE_NOTHROW(model = mef::Initializer(input, core::Settings{}).model()); fs::path temp_file = utility::GenerateFilePath(); - ASSERT_NO_THROW(Serialize(*model, temp_file.string())) - << input.front() << " => " << temp_file; - ASSERT_NO_THROW(xml::Document(temp_file.string(), &validator)) - << input.front() << " => " << temp_file; + INFO("temp file: " + temp_file.string()); + REQUIRE_NOTHROW(Serialize(*model, temp_file.string())); + REQUIRE_NOTHROW(xml::Document(temp_file.string(), &validator)); fs::remove(temp_file); } } -} // namespace test -} // namespace mef -} // namespace scram +} // namespace scram::mef::test diff -Nru scram-0.16.1/tests/settings_tests.cc scram-0.16.2/tests/settings_tests.cc --- scram-0.16.1/tests/settings_tests.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/settings_tests.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 Olzhas Rakhimov + * Copyright (C) 2014-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,113 +17,109 @@ #include "settings.h" -#include +#include #include "error.h" -namespace scram { -namespace core { -namespace test { +namespace scram::core::test { -TEST(SettingsTest, IncorrectSetup) { +TEST_CASE("SettingsTest IncorrectSetup", "[settings]") { Settings s; // Incorrect algorithm. - EXPECT_THROW(s.algorithm("the-best"), SettingsError); + CHECK_THROWS_AS(s.algorithm("the-best"), SettingsError); // Incorrect approximation argument. - EXPECT_THROW(s.approximation("approx"), SettingsError); + CHECK_THROWS_AS(s.approximation("approx"), SettingsError); // Incorrect limit order for products. - EXPECT_THROW(s.limit_order(-1), SettingsError); + CHECK_THROWS_AS(s.limit_order(-1), SettingsError); // Incorrect cut-off probability. - EXPECT_THROW(s.cut_off(-1), SettingsError); - EXPECT_THROW(s.cut_off(10), SettingsError); + CHECK_THROWS_AS(s.cut_off(-1), SettingsError); + CHECK_THROWS_AS(s.cut_off(10), SettingsError); // Incorrect number of trials. - EXPECT_THROW(s.num_trials(-10), SettingsError); - EXPECT_THROW(s.num_trials(0), SettingsError); + CHECK_THROWS_AS(s.num_trials(-10), SettingsError); + CHECK_THROWS_AS(s.num_trials(0), SettingsError); // Incorrect number of quantiles. - EXPECT_THROW(s.num_quantiles(-10), SettingsError); - EXPECT_THROW(s.num_quantiles(0), SettingsError); + CHECK_THROWS_AS(s.num_quantiles(-10), SettingsError); + CHECK_THROWS_AS(s.num_quantiles(0), SettingsError); // Incorrect number of bins. - EXPECT_THROW(s.num_bins(-10), SettingsError); - EXPECT_THROW(s.num_bins(0), SettingsError); + CHECK_THROWS_AS(s.num_bins(-10), SettingsError); + CHECK_THROWS_AS(s.num_bins(0), SettingsError); // Incorrect seed. - EXPECT_THROW(s.seed(-1), SettingsError); + CHECK_THROWS_AS(s.seed(-1), SettingsError); // Incorrect mission time. - EXPECT_THROW(s.mission_time(-10), SettingsError); + CHECK_THROWS_AS(s.mission_time(-10), SettingsError); // Incorrect time step. - EXPECT_THROW(s.time_step(-1), SettingsError); + CHECK_THROWS_AS(s.time_step(-1), SettingsError); // The time step is not set for the SIL calculations. - EXPECT_THROW(s.safety_integrity_levels(true), SettingsError); + CHECK_THROWS_AS(s.safety_integrity_levels(true), SettingsError); // Disable time step while the SIL is requested. - EXPECT_NO_THROW(s.time_step(1)); - EXPECT_NO_THROW(s.safety_integrity_levels(true)); - EXPECT_THROW(s.time_step(0), SettingsError); + CHECK_NOTHROW(s.time_step(1)); + CHECK_NOTHROW(s.safety_integrity_levels(true)); + CHECK_THROWS_AS(s.time_step(0), SettingsError); } -TEST(SettingsTest, CorrectSetup) { +TEST_CASE("SettingsTest CorrectSetup", "[settings]") { Settings s; // Correct algorithm. - EXPECT_NO_THROW(s.algorithm("mocus")); - EXPECT_NO_THROW(s.algorithm("bdd")); - EXPECT_NO_THROW(s.algorithm("zbdd")); + CHECK_NOTHROW(s.algorithm("mocus")); + CHECK_NOTHROW(s.algorithm("bdd")); + CHECK_NOTHROW(s.algorithm("zbdd")); // Correct approximation argument. - EXPECT_NO_THROW(s.approximation("rare-event")); - EXPECT_NO_THROW(s.approximation("mcub")); + CHECK_NOTHROW(s.approximation("rare-event")); + CHECK_NOTHROW(s.approximation("mcub")); // Correct limit order for products. - EXPECT_NO_THROW(s.limit_order(1)); - EXPECT_NO_THROW(s.limit_order(32)); - EXPECT_NO_THROW(s.limit_order(1e9)); + CHECK_NOTHROW(s.limit_order(1)); + CHECK_NOTHROW(s.limit_order(32)); + CHECK_NOTHROW(s.limit_order(1e9)); // Correct cut-off probability. - EXPECT_NO_THROW(s.cut_off(1)); - EXPECT_NO_THROW(s.cut_off(0)); - EXPECT_NO_THROW(s.cut_off(0.5)); + CHECK_NOTHROW(s.cut_off(1)); + CHECK_NOTHROW(s.cut_off(0)); + CHECK_NOTHROW(s.cut_off(0.5)); // Correct number of trials. - EXPECT_NO_THROW(s.num_trials(1)); - EXPECT_NO_THROW(s.num_trials(1e6)); + CHECK_NOTHROW(s.num_trials(1)); + CHECK_NOTHROW(s.num_trials(1e6)); // Correct number of quantiles. - EXPECT_NO_THROW(s.num_quantiles(1)); - EXPECT_NO_THROW(s.num_quantiles(10)); + CHECK_NOTHROW(s.num_quantiles(1)); + CHECK_NOTHROW(s.num_quantiles(10)); // Correct number of bins. - EXPECT_NO_THROW(s.num_bins(1)); - EXPECT_NO_THROW(s.num_bins(10)); + CHECK_NOTHROW(s.num_bins(1)); + CHECK_NOTHROW(s.num_bins(10)); // Correct seed. - EXPECT_NO_THROW(s.seed(1)); + CHECK_NOTHROW(s.seed(1)); // Correct mission time. - EXPECT_NO_THROW(s.mission_time(0)); - EXPECT_NO_THROW(s.mission_time(10)); - EXPECT_NO_THROW(s.mission_time(1e6)); + CHECK_NOTHROW(s.mission_time(0)); + CHECK_NOTHROW(s.mission_time(10)); + CHECK_NOTHROW(s.mission_time(1e6)); // Correct time step. - EXPECT_NO_THROW(s.time_step(0)); - EXPECT_NO_THROW(s.time_step(10)); - EXPECT_NO_THROW(s.time_step(1e6)); + CHECK_NOTHROW(s.time_step(0)); + CHECK_NOTHROW(s.time_step(10)); + CHECK_NOTHROW(s.time_step(1e6)); // Correct request for the SIL. - EXPECT_NO_THROW(s.safety_integrity_levels(true)); - EXPECT_NO_THROW(s.safety_integrity_levels(false)); + CHECK_NOTHROW(s.safety_integrity_levels(true)); + CHECK_NOTHROW(s.safety_integrity_levels(false)); } -TEST(SettingsTest, SetupForPrimeImplicants) { +TEST_CASE("SettingsTest SetupForPrimeImplicants", "[settings]") { Settings s; // Incorrect request for prime implicants. - EXPECT_NO_THROW(s.algorithm("mocus")); - EXPECT_THROW(s.prime_implicants(true), SettingsError); + CHECK_NOTHROW(s.algorithm("mocus")); + CHECK_THROWS_AS(s.prime_implicants(true), SettingsError); // Correct request for prime implicants. - ASSERT_NO_THROW(s.algorithm("bdd")); - ASSERT_NO_THROW(s.prime_implicants(true)); + REQUIRE_NOTHROW(s.algorithm("bdd")); + REQUIRE_NOTHROW(s.prime_implicants(true)); // Prime implicants with quantitative approximations. - EXPECT_NO_THROW(s.approximation("none")); - EXPECT_THROW(s.approximation("rare-event"), SettingsError); - EXPECT_THROW(s.approximation("mcub"), SettingsError); + CHECK_NOTHROW(s.approximation("none")); + CHECK_THROWS_AS(s.approximation("rare-event"), SettingsError); + CHECK_THROWS_AS(s.approximation("mcub"), SettingsError); } -} // namespace test -} // namespace core -} // namespace scram +} // namespace scram::core::test diff -Nru scram-0.16.1/tests/test_scram_call.py scram-0.16.2/tests/test_scram_call.py --- scram-0.16.1/tests/test_scram_call.py 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/test_scram_call.py 2018-01-12 11:42:47.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2014-2017 Olzhas Rakhimov +# Copyright (C) 2014-2018 Olzhas Rakhimov # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -17,124 +17,113 @@ import os from subprocess import call -from nose.tools import assert_equal, assert_not_equal +import pytest def test_empty_call(): """Tests a command-line call without any arguments.""" cmd = ["scram"] - yield assert_equal, 1, call(cmd) + assert call(cmd) == 1 -def test_info_calls(): +def test_info_help_calls(): """Tests general information calls about SCRAM.""" - # Test help cmd = ["scram", "--help"] - yield assert_equal, 0, call(cmd) + assert call(cmd) == 0 - # Test version information + +def test_info_version_calls(): + """Test version information.""" cmd = ["scram", "--version"] - yield assert_equal, 0, call(cmd) + assert call(cmd) == 0 -def test_fta_no_prob(): +def test_fta_no_prob(tmpdir): """Tests calls for fault tree analysis without probability information.""" fta_no_prob = "./input/fta/correct_tree_input.xml" # Test calculation calls cmd = ["scram", fta_no_prob] - yield assert_equal, 0, call(cmd) - out_temp = "./output_temp.xml" + assert call(cmd) == 0 + out_temp = str(tmpdir / "output_temp.xml") cmd.append("-o") cmd.append(out_temp) - yield assert_equal, 0, call(cmd) # report into an output file + assert call(cmd) == 0 # report into an output file if os.path.isfile(out_temp): os.remove(out_temp) -def test_fta_calls(): +@pytest.mark.parametrize( + 'cmd, status', + [ + (["--validate"], True), + # Test the incorrect limit order + (["-l", "-1"], False), + # Invalid argument type for an option + (["-l", "string_for_int"], 1), + # Test the limit order no minimal cut sets. + # This was an issue #17. This should not throw an error anymore. + (["-l", "1"], True), + # Test the incorrect cut-off probability + (["--cut-off", "-1"], False), + (["--cut-off", "10"], False), + # Test conflicting algorithms + (["--zbdd", "--bdd"], False), + # Test the application of the rare event and MCUB at the same time + (["--rare-event", "--mcub"], False), + # Test the rare event approximation + (["--rare-event"], True), + # Test the MCUB approximation + (["--mcub"], True), + # Test the uncertainty + (["--uncertainty", "true", "--num-bins", "20", "--num-quantiles", "20"], + True), + # Test calls for prime implicants + (["--prime-implicants", "--mocus"], False), + (["--prime-implicants", "--rare-event"], False), + (["--prime-implicants", "--mcub"], False) + ]) +def test_fta_calls(cmd, status): """Tests calls for full fault tree analysis.""" fta_input = "./input/fta/correct_tree_input_with_probs.xml" + ret = call(["scram", fta_input] + cmd) + if not isinstance(status, bool): + assert ret == status + elif status: + assert ret == 0 + else: + assert ret != 0 - # Test the validation a fta tree file - cmd = ["scram", "--validate", fta_input] - yield assert_equal, 0, call(cmd) - - # Test the incorrect limit order - cmd = ["scram", fta_input, "-l", "-1"] - yield assert_not_equal, 0, call(cmd) - - # Invalid argument type for an option - cmd = ["scram", fta_input, "-l", "string_for_int"] - yield assert_equal, 1, call(cmd) - - # Test the limit order no minimal cut sets. - # This was an issue #17. This should not throw an error anymore. - cmd = ["scram", fta_input, "-l", "1"] - yield assert_equal, 0, call(cmd) - - # Test the incorrect cut-off probability - cmd = ["scram", fta_input, "--cut-off", "-1"] - yield assert_not_equal, 0, call(cmd) - cmd = ["scram", fta_input, "--cut-off", "10"] - yield assert_not_equal, 0, call(cmd) - - # Test conflicting algorithms - cmd = ["scram", fta_input, "--zbdd", "--bdd"] - yield assert_not_equal, 0, call(cmd) - - # Test the application of the rare event and MCUB at the same time - cmd = ["scram", fta_input, "--rare-event", "--mcub"] - yield assert_not_equal, 0, call(cmd) - - # Test the rare event approximation - cmd = ["scram", fta_input, "--rare-event"] - yield assert_equal, 0, call(cmd) - - # Test the MCUB approximation - cmd = ["scram", fta_input, "--mcub"] - yield assert_equal, 0, call(cmd) - - # Test the uncertainty - cmd = [ - "scram", fta_input, "--uncertainty", "true", "--num-bins", "20", - "--num-quantiles", "20" - ] - yield assert_equal, 0, call(cmd) - # Test calls for prime implicants - cmd = ["scram", fta_input, "--prime-implicants", "--mocus"] - yield assert_not_equal, 0, call(cmd) - cmd = ["scram", fta_input, "--prime-implicants", "--rare-event"] - yield assert_not_equal, 0, call(cmd) - cmd = ["scram", fta_input, "--prime-implicants", "--mcub"] - yield assert_not_equal, 0, call(cmd) - - -def test_config_file(): +def test_config_file_output(tmpdir): """Tests calls with configuration files.""" # Test with a configuration file config_file = "./input/fta/full_configuration.xml" - out_temp = "./output_temp.xml" + out_temp = str(tmpdir / "output_temp.xml") cmd = ["scram", "--config-file", config_file, "-o", out_temp] - yield assert_equal, 0, call(cmd) + assert call(cmd) == 0 if os.path.isfile(out_temp): os.remove(out_temp) - # Test the clash of files from configuration and command-line + +def test_config_file_clash(): + """Test the clash of files from configuration and command-line.""" config_file = "./input/fta/full_configuration.xml" cmd = [ "scram", "--config-file", config_file, "input/fta/correct_tree_input_with_probs.xml" ] - yield assert_not_equal, 0, call(cmd) + assert call(cmd) != 0 -def test_logging(): +@pytest.mark.parametrize('level,status', + [(-1, False), (0, True), (1, True), (2, True), + (3, True), (4, True), (5, True), (6, True), (7, True), + (8, False), (10, False), (100, False), (1e6, False)]) +def test_logging(level, status): """Tests invokation with logging.""" fta_input = "./input/fta/correct_tree_input_with_probs.xml" - cmd = ["scram", fta_input, "--verbosity", "-1"] - yield assert_not_equal, 0, call(cmd) - cmd = ["scram", fta_input, "--verbosity", "8"] - yield assert_not_equal, 0, call(cmd) - cmd = ["scram", fta_input, "--verbosity", "7"] - yield assert_equal, 0, call(cmd) + ret = call(["scram", fta_input, "--verbosity", str(level)]) + if status: + assert ret == 0 + else: + assert ret != 0 diff -Nru scram-0.16.1/tests/utility.h scram-0.16.2/tests/utility.h --- scram-0.16.1/tests/utility.h 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/utility.h 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Olzhas Rakhimov + * Copyright (C) 2017-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,7 @@ /// @file /// Test helper functions. -#ifndef SCRAM_TESTS_UTILITY_H_ -#define SCRAM_TESTS_UTILITY_H_ +#pragma once #include @@ -27,8 +26,7 @@ namespace fs = boost::filesystem; -namespace scram { -namespace utility { +namespace scram::utility { /// Generate unique file path for temporary files. inline fs::path GenerateFilePath(const std::string& prefix = "scram_test") { @@ -36,7 +34,4 @@ return fs::temp_directory_path() / unique_name; } -} // namespace utility -} // namespace scram - -#endif // SCRAM_TESTS_UTILITY_H_ +} // namespace scram::utility diff -Nru scram-0.16.1/tests/xml_stream_tests.cc scram-0.16.2/tests/xml_stream_tests.cc --- scram-0.16.1/tests/xml_stream_tests.cc 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/tests/xml_stream_tests.cc 2018-01-12 11:42:47.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2017 Olzhas Rakhimov + * Copyright (C) 2016-2018 Olzhas Rakhimov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,96 +17,97 @@ #include "xml_stream.h" -#include +#include -namespace scram { -namespace xml { -namespace test { +namespace scram::xml::test { /// This fixture provides document stream for tests. -class XmlStreamTest : public ::testing::Test { +class XmlStreamTest { public: + XmlStreamTest() : xml_stream_(stderr) {} ~XmlStreamTest() noexcept {} protected: - XmlStreamTest() : xml_stream_(stderr) {} Stream xml_stream_; ///< The stream to add elements into per test case. }; -TEST_F(XmlStreamTest, ElementConstructor) { - EXPECT_THROW(xml_stream_.root(""), StreamError); - EXPECT_NO_THROW(xml_stream_.root("element")); +TEST_CASE_METHOD(XmlStreamTest, "xml::StreamElement ctor", "[xml_stream]") { + CHECK_THROWS_AS(xml_stream_.root(""), StreamError); + CHECK_NOTHROW(xml_stream_.root("element")); } -TEST_F(XmlStreamTest, StreamConstructor) { - EXPECT_NO_THROW(xml_stream_.root("root")); - EXPECT_THROW(xml_stream_.root("root"), StreamError); +TEST_CASE_METHOD(XmlStreamTest, "xml::Stream ctor", "[xml_stream]") { + CHECK_NOTHROW(xml_stream_.root("root")); + CHECK_THROWS_AS(xml_stream_.root("root"), StreamError); } -TEST_F(XmlStreamTest, SetAttribute) { +TEST_CASE_METHOD(XmlStreamTest, "xml::StreamElement SetAttribute", + "[xml_stream]") { StreamElement el = xml_stream_.root("element"); - EXPECT_THROW(el.SetAttribute("", "value"), StreamError); - EXPECT_NO_THROW(el.SetAttribute("attr1", "value")); - EXPECT_NO_THROW(el.SetAttribute("attr2", "")); - EXPECT_NO_THROW(el.SetAttribute("attr3", 7)); + CHECK_THROWS_AS(el.SetAttribute("", "value"), StreamError); + CHECK_NOTHROW(el.SetAttribute("attr1", "value")); + CHECK_NOTHROW(el.SetAttribute("attr2", "")); + CHECK_NOTHROW(el.SetAttribute("attr3", 7)); } -TEST_F(XmlStreamTest, AddText) { +TEST_CASE_METHOD(XmlStreamTest, "xml::StreamElement AddText", "[xml_stream]") { StreamElement el = xml_stream_.root("element"); - EXPECT_NO_THROW(el.AddText("text")); - EXPECT_NO_THROW(el.AddText(7)); + CHECK_NOTHROW(el.AddText("text")); + CHECK_NOTHROW(el.AddText(7)); } -TEST_F(XmlStreamTest, AddChild) { +TEST_CASE_METHOD(XmlStreamTest, "xml::StreamElement AddChild", "[xml_stream]") { StreamElement el = xml_stream_.root("element"); - EXPECT_THROW(el.AddChild(""), StreamError); - EXPECT_NO_THROW(el.AddChild("child")); + CHECK_THROWS_AS(el.AddChild(""), StreamError); + CHECK_NOTHROW(el.AddChild("child")); } -TEST_F(XmlStreamTest, StateAfterSetAttribute) { +TEST_CASE_METHOD(XmlStreamTest, "xml::StreamElement StateAfterSetAttribute", + "[xml_stream]") { StreamElement root = xml_stream_.root("root"); { StreamElement el = root.AddChild("element"); - EXPECT_NO_THROW(el.SetAttribute("attr", "value")); - EXPECT_NO_THROW(el.AddText("text")); + CHECK_NOTHROW(el.SetAttribute("attr", "value")); + CHECK_NOTHROW(el.AddText("text")); } { StreamElement el = root.AddChild("element"); - EXPECT_NO_THROW(el.SetAttribute("attr", "value")); - EXPECT_NO_THROW(el.AddChild("child")); + CHECK_NOTHROW(el.SetAttribute("attr", "value")); + CHECK_NOTHROW(el.AddChild("child")); } } -TEST_F(XmlStreamTest, StateAfterAddText) { +TEST_CASE_METHOD(XmlStreamTest, "xml::StreamElement StateAfterAddText", + "[xml_stream]") { StreamElement el = xml_stream_.root("element"); - EXPECT_NO_THROW(el.AddText("text")); // Locks on text. - EXPECT_THROW(el.SetAttribute("attr", "value"), StreamError); - EXPECT_THROW(el.AddChild("another_child"), StreamError); - EXPECT_NO_THROW(el.AddText(" and continuation...")); + CHECK_NOTHROW(el.AddText("text")); // Locks on text. + CHECK_THROWS_AS(el.SetAttribute("attr", "value"), StreamError); + CHECK_THROWS_AS(el.AddChild("another_child"), StreamError); + CHECK_NOTHROW(el.AddText(" and continuation...")); } -TEST_F(XmlStreamTest, StateAfterAddChild) { +TEST_CASE_METHOD(XmlStreamTest, "xml::StreamElement StateAfterAddChild", + "[xml_stream]") { StreamElement el = xml_stream_.root("element"); - EXPECT_NO_THROW(el.AddChild("child")); // Locks on elements. - EXPECT_THROW(el.SetAttribute("attr", "value"), StreamError); - EXPECT_THROW(el.AddText("text"), StreamError); - EXPECT_NO_THROW(el.AddChild("another_child")); + CHECK_NOTHROW(el.AddChild("child")); // Locks on elements. + CHECK_THROWS_AS(el.SetAttribute("attr", "value"), StreamError); + CHECK_THROWS_AS(el.AddText("text"), StreamError); + CHECK_NOTHROW(el.AddChild("another_child")); } -TEST_F(XmlStreamTest, InactiveParent) { +TEST_CASE_METHOD(XmlStreamTest, "xml::StreamElement InactiveParent", + "[xml_stream]") { StreamElement el = xml_stream_.root("element"); { StreamElement child = el.AddChild("child"); // Make the parent inactive. - EXPECT_THROW(el.SetAttribute("attr", "value"), StreamError); - EXPECT_THROW(el.AddText("text"), StreamError); - EXPECT_THROW(el.AddChild("another_child"), StreamError); + CHECK_THROWS_AS(el.SetAttribute("attr", "value"), StreamError); + CHECK_THROWS_AS(el.AddText("text"), StreamError); + CHECK_THROWS_AS(el.AddChild("another_child"), StreamError); // Child must be active without problems. - EXPECT_NO_THROW(child.SetAttribute("sub_attr", "value")); - EXPECT_NO_THROW(child.AddChild("sub_child")); + CHECK_NOTHROW(child.SetAttribute("sub_attr", "value")); + CHECK_NOTHROW(child.AddChild("sub_child")); } // Lock is off at the scope exit. - EXPECT_NO_THROW(el.AddChild("another_child")); + CHECK_NOTHROW(el.AddChild("another_child")); } -} // namespace test -} // namespace xml -} // namespace scram +} // namespace scram::xml::test diff -Nru scram-0.16.1/.travis/doxygen.conf scram-0.16.2/.travis/doxygen.conf --- scram-0.16.1/.travis/doxygen.conf 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/.travis/doxygen.conf 2018-01-12 11:42:47.000000000 +0000 @@ -1935,7 +1935,7 @@ # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -PREDEFINED = +PREDEFINED = DOXYGEN_SHOULD_SKIP_THIS # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The diff -Nru scram-0.16.1/.travis/install.sh scram-0.16.2/.travis/install.sh --- scram-0.16.1/.travis/install.sh 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/.travis/install.sh 2018-01-12 11:42:47.000000000 +0000 @@ -10,7 +10,7 @@ brew install qt5 brew install ccache # brew install python --universal - sudo pip2 install nose + sudo pip2 install pytest fi [[ "${TRAVIS_OS_NAME}" == "linux" ]] || exit 0 @@ -31,7 +31,7 @@ exit 0 # Compilation dependencies are not required. fi -pip install --user nose # Testing main() requires nosetests! +pip install --user pytest # Testing main() requires pytest! if [[ "${CONFIG}" == "Coverage" ]]; then pip install --user -r requirements-dev.txt diff -Nru scram-0.16.1/.travis/lint.sh scram-0.16.2/.travis/lint.sh --- scram-0.16.1/.travis/lint.sh 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/.travis/lint.sh 2018-01-12 11:42:47.000000000 +0000 @@ -15,7 +15,7 @@ cat doc_errors.txt >&2 exit 1 fi -ls src/**/*.{cc{,.in},h} | xargs -n 1 grep -q '^/// @file$' # Missing file doc. +ls src/**/*.{cc,h} | xargs -n 1 grep -q '^/// @file$' # Missing file doc. ls gui/*.{cpp,h} | xargs -n 1 grep -q '^/// @file$' # Missing file doc. # Lizard function complexity printout for C++ and Python @@ -26,8 +26,6 @@ # C++ linting cpplint --repository=../ --quiet --recursive src/* 2> style.txt \ || echo "TODO: Fix the C++ code" -cpplint --repository=../ --quiet --filter=-build/include_what_you_use \ - tests/* 2>> style.txt || echo "TODO: Fix the C++ code" # Clean false positives and noise sed -i '/Found C system header after C\+\+/d' style.txt @@ -52,5 +50,6 @@ if [[ -s ts_warnings.txt ]]; then echo "Qt Lupdate warnings:" >&2 cat ts_warnings.txt >&2 - exit 1 + echo "lupdate C++17 issues" + # exit 1 fi diff -Nru scram-0.16.1/.travis/run_tests.sh scram-0.16.2/.travis/run_tests.sh --- scram-0.16.1/.travis/run_tests.sh 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/.travis/run_tests.sh 2018-01-12 11:42:47.000000000 +0000 @@ -9,7 +9,7 @@ which scram-gui scram_tests -nosetests -w ./tests/ +(cd tests && python -m pytest test_scram_call.py) (cd build && ctest --verbose) ./scripts/fault_tree_generator.py -b 200 -a 5 @@ -23,7 +23,8 @@ kill $! if [[ "${CONFIG}" == "Coverage" ]]; then - nosetests --with-coverage -w scripts test/ + (cd scripts && python -m pytest --cov=. --cov-config ../.coveragerc test/) + mv scripts/.coverage ./ fi LD_LIBRARY_PATH=${PWD}/build/lib/scram/:${LD_LIBRARY_PATH} \ diff -Nru scram-0.16.1/.travis/script.sh scram-0.16.2/.travis/script.sh --- scram-0.16.1/.travis/script.sh 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/.travis/script.sh 2018-01-12 11:42:47.000000000 +0000 @@ -49,7 +49,6 @@ valgrind --tool=memcheck --leak-check=full --show-leak-kinds=definite \ --errors-for-leak-kinds=definite --error-exitcode=127 \ --track-fds=yes \ - scram_tests \ - --gtest_filter=-*Death*:*Baobab*:*IncorrectInclude*:*LabelsAndAttributes* \ + scram_tests ~*Baobab* ~*IncorrectInclude* ~*LabelsAndAttributes* ~[.perf] \ || [[ $? -eq 0 || $? -eq 1 ]] fi diff -Nru scram-0.16.1/.travis.yml scram-0.16.2/.travis.yml --- scram-0.16.1/.travis.yml 2018-01-04 10:06:34.000000000 +0000 +++ scram-0.16.2/.travis.yml 2018-01-12 11:42:47.000000000 +0000 @@ -17,14 +17,14 @@ compiler: - gcc - - clang + # - clang # Wait till Clang 6 or patched 5 to work w/ libstdc++. env: global: - PATH=$HOME/.local/bin:$PATH:$PWD/install/bin - QT_QPA_FONTDIR=/usr/share/fonts - QT_QPA_PLATFORM=offscreen - - GCC_VERSION=4.9 + - GCC_VERSION=7 matrix: - CONFIG=Debug - CONFIG=Release @@ -32,26 +32,25 @@ addons: apt: packages: - - gcc-4.9 - - g++-4.9 - - libboost-program-options1.58-dev - - libboost-math1.58-dev - - libboost-random1.58-dev - - libboost-filesystem1.58-dev - - libboost-date-time1.58-dev + - gcc-7 + - g++-7 + - ccache + - libboost-program-options1.61-dev + - libboost-math1.61-dev + - libboost-random1.61-dev + - libboost-filesystem1.61-dev - libxml2-dev - libgoogle-perftools-dev - - qtbase5-dev - - qtbase5-dev-tools - - qttools5-dev - - qttools5-dev-tools - - libqt5svg5-dev - - libqt5opengl5-dev + - qt59base + - qt59tools + - qt59svg - fontconfig - lcov sources: &Sources - ubuntu-toolchain-r-test - - sourceline: "ppa:kzemek/boost" + - sourceline: "ppa:rakhimov/boost" + - sourceline: "ppa:zerebubuth/ccache" + - sourceline: "ppa:beineri/opt-qt593-trusty" jobs: include: @@ -62,27 +61,29 @@ addons: apt: packages: - - qttools5-dev-tools - - stage: test - os: osx # OS X builds are slow and limited. - compiler: clang - env: CONFIG=Release + - qt59tools + sources: *Sources + # - stage: test + # os: osx # OS X builds are slow and limited. + # osx_image: xcode9.2 # C++17 not yet fully supported!!! + # compiler: clang + # env: CONFIG=Release - stage: test compiler: gcc env: CONFIG=Coverage - stage: test compiler: gcc env: CONFIG=Memcheck + before_script: mkdir build install addons: apt: packages: - - gcc-4.9 - - g++-4.9 - - libboost-program-options1.58-dev - - libboost-math1.58-dev - - libboost-random1.58-dev - - libboost-filesystem1.58-dev - - libboost-date-time1.58-dev + - gcc-7 + - g++-7 + - libboost-program-options1.61-dev + - libboost-math1.61-dev + - libboost-random1.61-dev + - libboost-filesystem1.61-dev - libxml2-dev - valgrind sources: *Sources @@ -102,6 +103,7 @@ before_script: - mkdir build install + - source /opt/qt59/bin/qt59-env.sh script: - .travis/script.sh