diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 265a6a1..7b4d2d4 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -1,11 +1,9 @@ name: CMake -on: [push] -#on: -# push: -# branches: [ master ] -# pull_request: -# branches: [ master ] +on: + pull_request: + branches: [ master ] + workflow_dispatch: env: # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) @@ -26,19 +24,20 @@ jobs: curl http://download.opensuse.org/repositories/science:/dlr/xUbuntu_18.04/Release.key | sudo apt-key add - echo "deb http://download.opensuse.org/repositories/science:/dlr/xUbuntu_18.04/ /" | sudo tee -a /etc/apt/sources.list sudo apt-get update -qq - sudo apt-get install -y libboost-all-dev libtixi3-dev cmake cmake-data + sudo apt-get install -y libtixi3-dev cmake cmake-data - name: Configure CMake # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type - run: cmake -B ${{github.workspace}}/build -DBoost_USE_STATIC_LIBS=OFF -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} + run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} - name: Build + working-directory: ${{github.workspace}}/build # Build your program with the given configuration - run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} + run: make VERBOSE=1 - name: Test working-directory: ${{github.workspace}}/build # Execute tests defined by the CMake configuration. # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail - run: ./tests \ No newline at end of file + run: ./tests diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index fb3641a..0000000 --- a/.travis.yml +++ /dev/null @@ -1,25 +0,0 @@ -dist: trusty -language: cpp -sudo: required - -addons: - apt: - packages: libboost-all-dev - sources: - - sourceline: 'ppa:mhier/libboost-latest' - packages: - - boost1.85 - -before_install: - - curl http://download.opensuse.org/repositories/science:/dlr/xUbuntu_14.04/Release.key | sudo apt-key add - - - echo "deb http://download.opensuse.org/repositories/science:/dlr/xUbuntu_14.04/ /" | sudo tee -a /etc/apt/sources.list - - sudo apt-get update -qq - - sudo apt-get install -y --force-yes libtixi3-dev - -script: - - mkdir build - - cd build - - cmake -DBoost_USE_STATIC_LIBS=OFF .. - - make -j4 - - ./tests - \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index fe0b232..d2ddcd7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,15 +1,14 @@ # CPACSGen cmake project # author: Bernhard Manfred Gruber -cmake_minimum_required(VERSION 3.2) +cmake_minimum_required(VERSION 3.11.0) -set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) project(CPACSGen) # cache variables -set(BOOST_ROOT "" CACHE PATH "Boost installation prefix") set(TIXI_PATH "" CACHE PATH "Tixi installation prefix") set(TIGL_PATH "" CACHE PATH "Tigl installation prefix") @@ -22,12 +21,6 @@ if (SYSTEM_RHEL7) endif() endif() -# find boost -set(Boost_USE_STATIC_LIBS ON CACHE BOOL "Find static or dynamic libs. Static libs require lib prefix.") -find_package (Boost REQUIRED COMPONENTS system filesystem date_time regex unit_test_framework) -mark_as_advanced(CLEAR BOOST_ROOT) # find module for boost marks these variables as advanced -mark_as_advanced(CLEAR Boost_USE_STATIC_LIBS) - # find tixi set(CMAKE_PREFIX_PATH "${TIXI_PATH};${CMAKE_PREFIX_PATH}") find_package(tixi3 3.0.3 REQUIRED) @@ -42,9 +35,6 @@ target_compile_definitions(lib${PROJECT_NAME} PUBLIC -DCPACS_GEN ) -target_include_directories(lib${PROJECT_NAME} PUBLIC - ${Boost_INCLUDE_DIRS} -) # driver file(GLOB DRIVER_INPUTS src/driver/*.cpp *src/driver/*.h *.md) @@ -53,32 +43,33 @@ source_group(" " FILES ${DRIVER_INPUTS}) target_link_libraries(${PROJECT_NAME} lib${PROJECT_NAME} - ${Boost_LIBRARIES} ) # tests +message(STATUS "Build gtest Testsuite") + +enable_testing() +option(gtest_force_shared_crt "" ON) +mark_as_advanced(gtest_force_shared_crt gtest_build_tests gtest_build_samples gtest_disable_pthreads) + +set(BUILD_GMOCK OFF) +set(INSTALL_GTEST OFF) +list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) +message(STATUS "Download and configure the TIGL gtest Testsuite") +include(AddGoogleTest) +message(STATUS "Download and configure the TIGL gtest Testsuite - Success") + set(DATA_DIR ${CMAKE_SOURCE_DIR}/test/data) configure_file(test/paths.h.in ${CMAKE_BINARY_DIR}/test/paths.h) file(GLOB TEST_INPUTS test/*.cpp test/*.h) list(APPEND TEST_INPUTS ${CMAKE_BINARY_DIR}/test/paths.h) add_executable(tests ${TEST_INPUTS}) -source_group(" " FILES ${TEST_INPUTS}) - -if(NOT Boost_USE_STATIC_LIBS) - target_compile_definitions(tests PUBLIC - -DBOOST_TEST_DYN_LINK - ) -endif() - +target_link_libraries(tests PRIVATE gtest gtest_main libCPACSGen) target_include_directories(tests PUBLIC ${CMAKE_BINARY_DIR}/test ) - -target_link_libraries(tests - lib${PROJECT_NAME} - ${Boost_LIBRARIES} -) +add_test(NAME tests COMMAND tests) # generate target if(TIGL_PATH) diff --git a/README.md b/README.md index c0e45eb..7e6a1ce 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,8 @@ https://github.com/RISCSoftware/cpacs_tigl_gen The following components are required to build and run CPACSGen * A working copy of CPACSGen * CMake -* C\++11/C++14 compliant compiler (VS2017 is currently used and tested) +* C\++17 compliant compiler (VS2017 is currently used and tested) * TIXI library (https://github.com/DLR-SC/tixi) -* Boost libraries (v1.55 or higher) * A working copy of TiGL with CPACSGen input files (https://github.com/DLR-SC/tigl) ## Input files @@ -42,9 +41,8 @@ For each subdirectory, CPACSGen runs an additional pass, putting the generated f 1. Clone the CPACSGen repository from Github 2. Clone the TiGL repository Github 3. Use CMake to configure CPACSGen - 1. Set BOOST_ROOT - 2. Set TIXI_PATH - 3. Set TIGL_PATH to the directory of your TiGL clone + 1. Set TIXI_PATH, if the TiXI package is not already installed in the current conda environment + 2. Set TIGL_PATH to the directory of your TiGL clone 4. Build CPACSGen 5. Build target generate executes CPACSGen.exe $\{TIGL_DIR}/cpacs_gen_input $\{CPACSGEN_DIR}/src $\{TIGL_DIR}/src/generated @@ -107,7 +105,3 @@ The classes generated by CPACSGen depend upon the following helper files, which Wrappers over TIXI functions providing a C++ friendly interface (references, std::string, exceptions, ...). Is used by the ReadCPACS and WriteCPACS implementation. -* UniquePtr.hpp - Contains tigl\::unique_ptr\ which defaults to std\::unique_ptr\ if C++11 is available, otherwise provides a custom type based on std\::auto_ptr\. - Furthermore, the generated classes may require boost::optional\, which is part of TiGL, and some internal TiGL files. - diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index c2c2ca5..0000000 --- a/appveyor.yml +++ /dev/null @@ -1,17 +0,0 @@ -image: Visual Studio 2017 -environment: - VCPKG_DEFAULT_TRIPLET: x64-windows - -install: - - call C:\\Miniconda35-x64\\Scripts\\activate.bat - - conda install --yes -c dlr-sc tixi3 - -build_script: -- ps: | - mkdir build - pushd build - cmake -DBOOST_ROOT=C:\Libraries\boost_1_67_0 -G "Visual Studio 15 2017 Win64" .. - cmake --build . --config "Release" - -test_script: - - Release\tests diff --git a/cmake/AddGoogleTest.cmake b/cmake/AddGoogleTest.cmake new file mode 100644 index 0000000..9dfea91 --- /dev/null +++ b/cmake/AddGoogleTest.cmake @@ -0,0 +1,69 @@ +# +# +# Downloads GTest and provides a helper macro to add tests. Add make check, as well, which +# gives output on failed tests without having to set an environment variable. +# +# +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) + +include(FetchContent) +FetchContent_Declare(googletest + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG v1.17.0) +FetchContent_GetProperties(googletest) +if(NOT googletest_POPULATED) + FetchContent_Populate(googletest) + set(CMAKE_SUPPRESS_DEVELOPER_WARNINGS 1 CACHE BOOL "") + add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR} EXCLUDE_FROM_ALL) + unset(CMAKE_SUPPRESS_DEVELOPER_WARNINGS) +endif() + + +if(CMAKE_CONFIGURATION_TYPES) + add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} + --force-new-ctest-process --output-on-failure + --build-config "$") +else() + add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} + --force-new-ctest-process --output-on-failure) +endif() +set_target_properties(check PROPERTIES FOLDER "Scripts") + +#include_directories(${gtest_SOURCE_DIR}/include) + +# More modern way to do the last line, less messy but needs newish CMake: +# target_include_directories(gtest INTERFACE ${gtest_SOURCE_DIR}/include) + + +if(GOOGLE_TEST_INDIVIDUAL) + include(GoogleTest) +endif() + +# Target must already exist +macro(add_gtest TESTNAME) + target_link_libraries(${TESTNAME} PUBLIC gtest gtest_main) + + if(GOOGLE_TEST_INDIVIDUAL) + gtest_discover_tests(${TESTNAME} + TEST_PREFIX "${TESTNAME}." + PROPERTIES FOLDER "Tests") + else() + add_test(${TESTNAME} ${TESTNAME}) + set_target_properties(${TESTNAME} PROPERTIES FOLDER "Tests") + endif() + +endmacro() + +mark_as_advanced( +gmock_build_tests +gtest_build_samples +gtest_build_tests +gtest_disable_pthreads +gtest_force_shared_crt +gtest_hide_internal_symbols +BUILD_GMOCK +BUILD_GTEST +) + +set_target_properties(gtest gtest_main + PROPERTIES FOLDER "Extern") diff --git a/src/driver/main.cpp b/src/driver/main.cpp index 0ada4d2..11ee56e 100644 --- a/src/driver/main.cpp +++ b/src/driver/main.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include @@ -9,12 +9,11 @@ #include "../lib/Filesystem.h" #include "../lib/NotImplementedException.h" -namespace fs = boost::filesystem; +namespace fs = std::filesystem; namespace tigl { const auto runtimeFiles = { "TixiHelper.h", - "UniquePtr.h", }; void processDirectory(const std::string& inputDirectory, const std::string& runtimeDirectory, const std::string& outputDirectory, const std::string& typeSystemGraphVisFile, Filesystem& fs, const std::string& ns = "") { diff --git a/src/lib/CodeGen.cpp b/src/lib/CodeGen.cpp index f2413ca..1fbceb7 100644 --- a/src/lib/CodeGen.cpp +++ b/src/lib/CodeGen.cpp @@ -1,5 +1,3 @@ -#include -#include #include #include @@ -8,6 +6,9 @@ #include #include #include +#include +#include +#include #include "SchemaParser.h" #include "Tables.h" @@ -32,9 +33,9 @@ namespace tigl { } namespace { + auto customReplacedType(const std::string& type, const Tables& tables) -> const std::string& { - const auto p = tables.m_customTypes.find(type); - return p ? *p : type; + return tables.m_customTypes.find(type).value_or(type); } auto capitalizeFirstLetter(std::string str) -> std::string { @@ -200,7 +201,7 @@ namespace tigl { return typeName; case Cardinality::Vector: { - if (vectorInnerTypeIsUniquePtr(field)) + if (vectorInnerTypeIsCPACSClass(field)) return "std::vector>"; else return "std::vector<" + typeName + ">"; @@ -220,16 +221,44 @@ namespace tigl { return customReplacedType(field); } - auto vectorInnerTypeIsUniquePtr(const Field& field) const -> bool { + auto vectorInnerClass(const Field& field) const -> Class const& + { + if (field.cardinality() != Cardinality::Vector){ + throw std::logic_error("Requested vector inner type for non-vector type"); + } + auto const it = m_types.classes.find(field.typeName); + if(vectorInnerTypeIsCPACSClass(field) && it != std::end(m_types.classes)) { + return it->second; + } else { + throw std::logic_error("VectorInnerType is not a CPACS class"); + } + } + + auto vectorInnerTypeIsCPACSClass(const Field& field) const -> bool { if (field.cardinality() != Cardinality::Vector) throw std::logic_error("Requested vector inner type for non-vector type"); return m_types.classes.find(field.typeName) != std::end(m_types.classes); } + std::string trimString(const std::string& s) const{ + auto start = std::find_if_not(s.begin(), s.end(), [](unsigned char c){ return std::isspace(c); }); + auto end = std::find_if_not(s.rbegin(), s.rend(), [](unsigned char c){ return std::isspace(c); }).base(); + + return (start < end ? std::string(start, end) : ""); + } + void writeDocumentation(IndentingStreamWrapper& hpp, const std::string& documentation) const { if (!documentation.empty()) { std::vector lines; - boost::algorithm::split(lines, documentation, boost::is_any_of("\n")); + std::istringstream stream(documentation); + std::string line; + + while (std::getline(stream, line, '\n')) { + lines.push_back(trimString(line)); + } + if (documentation.back() == '\n') { + lines.push_back(""); + } for (const auto& line : lines) hpp << "/// " << line; } @@ -264,9 +293,18 @@ namespace tigl { hpp << "TIGL_EXPORT virtual " << getterSetterType(f) << "& Get" << capitalizeFirstLetter(f.name()) << "();"; hpp << EmptyLine; hpp << "TIGL_EXPORT virtual size_t Get" << capitalizeFirstLetter(f.cpacsName) << "Count() const;"; + if(vectorInnerTypeIsCPACSClass(f) && hasUidField(vectorInnerClass(f))){ + hpp << "TIGL_EXPORT virtual size_t Get" << capitalizeFirstLetter(f.cpacsName) << "Index(const std::string& UID) const;"; + } + hpp << EmptyLine; hpp << "TIGL_EXPORT virtual const " << vectorInnerType(f) << "& Get" << capitalizeFirstLetter(f.cpacsName) << "(size_t index) const;"; hpp << "TIGL_EXPORT virtual " << vectorInnerType(f) << "& Get" << capitalizeFirstLetter(f.cpacsName) << "(size_t index);"; - } // generate special accessors for uid reference vectors + if(vectorInnerTypeIsCPACSClass(f) && hasUidField(vectorInnerClass(f))){ + hpp << EmptyLine; + hpp << "TIGL_EXPORT virtual const " << vectorInnerType(f) << "& Get" << capitalizeFirstLetter(f.cpacsName) << "(const std::string& UID) const;"; + hpp << "TIGL_EXPORT virtual " << vectorInnerType(f) << "& Get" << capitalizeFirstLetter(f.cpacsName) << "(const std::string& UID);"; + } + } // generate special accessors for uid reference vectors else if (f.cardinality() == Cardinality::Vector && f.xmlTypeName == c_uidRefType) { hpp << "TIGL_EXPORT virtual void AddTo" << capitalizeFirstLetter(f.name()) << "(const " << vectorInnerType(f) << "& value);"; hpp << "TIGL_EXPORT virtual bool RemoveFrom" << capitalizeFirstLetter(f.name()) << "(const " << vectorInnerType(f) << "& value);"; @@ -386,6 +424,40 @@ namespace tigl { cpp << "}"; cpp << EmptyLine; + // Getter for index by UID + if(vectorInnerTypeIsCPACSClass(f) && hasUidField(vectorInnerClass(f))){ + cpp << "size_t " << className << "::Get" << capitalizeFirstLetter(f.cpacsName) << "Index(const std::string& UID) const"; + cpp << "{"; + { + Scope s(cpp); + cpp << "for (size_t i=0; i < Get" << capitalizeFirstLetter(f.cpacsName) << "Count(); i++) {"; + { + Scope s(cpp); + if(vectorInnerTypeIsCPACSClass(f) && hasUidField(vectorInnerClass(f)) && !hasMandatoryUidField(vectorInnerClass(f))) { + cpp << "const boost::optional tmpUID(*" << f.fieldName() << "[i]->GetUID());"; + cpp << "if (tmpUID == UID) {"; + { + Scope s(cpp); + cpp << "return i+1;"; + } + cpp << "}"; + } else { + cpp << "const std::string tmpUID(" << f.fieldName() << "[i]->GetUID());"; + cpp << "if (tmpUID == UID) {"; + { + Scope s(cpp); + cpp << "return i+1;"; + } + cpp << "}"; + } + } + cpp << "}"; + cpp << "throw CTiglError(\"Invalid UID in " << className << "::Get" << capitalizeFirstLetter(f.cpacsName) << "Index\", TIGL_UID_ERROR);"; + } + cpp << "}"; + cpp << EmptyLine; + } + //Getters for elements in vector type by index; for (auto isConst : { false, true }) { if(isConst){ @@ -396,14 +468,15 @@ namespace tigl { cpp << "{"; { Scope s(cpp); - cpp << "index--;"; - cpp << "if (index < 0 || index >= Get" << capitalizeFirstLetter(f.cpacsName) << "Count()) {"; + cpp << "if (index < 1 || index > Get" << capitalizeFirstLetter(f.cpacsName) << "Count()) {"; { Scope s(cpp); cpp << "throw CTiglError(\"Invalid index in " << getterSetterType(f) << "::Get" << capitalizeFirstLetter(f.cpacsName) << "\", TIGL_INDEX_ERROR);"; } cpp << "}"; - if (vectorInnerTypeIsUniquePtr(f)) { + cpp << "index--;"; + // CPACS classes are stored in smart pointers and we need to derefence + if (vectorInnerTypeIsCPACSClass(f)) { cpp << "return *" << f.fieldName() << "[index];"; } else { cpp << "return " << f.fieldName() << "[index];"; @@ -413,6 +486,38 @@ namespace tigl { cpp << EmptyLine; } + //Getters for elements in vector type by uid; + if(vectorInnerTypeIsCPACSClass(f) && hasUidField(vectorInnerClass(f))){ + for (auto isConst : { false, true }) { + if(isConst){ + cpp << "const " << vectorInnerType(f) << "& " << className << "::Get" << capitalizeFirstLetter(f.cpacsName) << "(const std::string& UID) const"; + } else { + cpp << vectorInnerType(f) << "& " << className << "::Get" << capitalizeFirstLetter(f.cpacsName) << "(const std::string& UID)"; + } + cpp << "{"; + { + Scope s(cpp); + cpp << "for (auto& elem : " << f.fieldName() <<" ) {"; + { + Scope s(cpp); + cpp << "if (elem->GetUID() == UID)"; + { + Scope s(cpp); + if (vectorInnerTypeIsCPACSClass(f)) { + cpp << "return *elem;"; + } else { + cpp << "return elem;"; + } + + } + cpp << "}"; + cpp << "throw CTiglError(\"Invalid UID in " << className << "::Get" << capitalizeFirstLetter(f.cpacsName) << ". \\\"\"+ UID + \"\\\" not found in CPACS file!\" , TIGL_UID_ERROR);"; + } + } + cpp << "}"; + cpp << EmptyLine; + } + } }// generate special accessors for uid reference vectors else if (f.cardinality() == Cardinality::Vector && f.xmlTypeName == c_uidRefType) { @@ -706,7 +811,13 @@ namespace tigl { arguments.push_back(parentPointerThis(parentClass)); if (requiresUidManager(c)) arguments.push_back("m_uidMgr"); - return boost::join(arguments, ", "); + std::ostringstream oss; + for (size_t i = 0; i < arguments.size(); ++i) { + if (i != 0) + oss << ", "; + oss << arguments[i]; + } + return oss.str(); } void writeReadAttributeOrElementImplementation(IndentingStreamWrapper& cpp, const Class& c, const Field& f) const { @@ -1087,6 +1198,12 @@ namespace tigl { throw std::logic_error("elements inside choice can only be optional or vector"); } + static auto unique (std::vector& v) { + std::sort(std::begin(v), std::end(v)); + const auto it = std::unique(std::begin(v), std::end(v)); + v.erase(it, std::end(v)); + } + void writeChoiceValidatorImplementation(IndentingStreamWrapper& cpp, const Class& c) const { if (!c.choices.empty()) { cpp << "bool " << c.name << "::ValidateChoices() const"; @@ -1096,7 +1213,7 @@ namespace tigl { - struct RecursiveColletor : public boost::static_visitor<> { + struct RecursiveColletor { void operator()(const ChoiceElement& ce) { indices.push_back(ce.index); } @@ -1108,13 +1225,21 @@ namespace tigl { void operator()(const ChoiceElements& ces) { for (const auto& ce : ces) - ce.apply_visitor(*this); + std::visit(*this, ce); + } + + void operator()(const std::shared_ptr& c) { + if (c) (*this)(*c); + } + + void operator()(const std::variant>& v) { + std::visit(*this, v); } std::vector indices; }; - struct ChoiceWriter : public boost::static_visitor<> { + struct ChoiceWriter { ChoiceWriter(IndentingStreamWrapper& cpp, const Class& c) : cpp(cpp), c(c) {} @@ -1126,11 +1251,17 @@ namespace tigl { cpp << "true // " << f.fieldName() << " is optional in choice"; } + void operator()(const std::shared_ptr& chPtr) { + if (chPtr) { + (*this)(*chPtr); + } + } + void operator()(const Choice& ch) { cpp << "("; { Scope s(cpp); - boost::optional additionalScope; + std::optional additionalScope; if (ch.minOccurs == 0) { cpp << "// all uninitialized is valid since choice is optional!"; @@ -1142,11 +1273,6 @@ namespace tigl { parentCollector(ch); auto& allIndices = parentCollector.indices; - auto unique = [](std::vector& v) { - std::sort(std::begin(v), std::end(v)); - const auto it = std::unique(std::begin(v), std::end(v)); - v.erase(it, std::end(v)); - }; unique(allIndices); for (const auto& i : allIndices) { @@ -1176,7 +1302,11 @@ namespace tigl { cpp << ")"; } - void operator()(const ChoiceElements& ces, boost::optional parentChoice = {}) { + void operator()(const std::variant>& variant) { + std::visit(*this, variant); + } + + void operator()(const ChoiceElements& ces, std::optional> parentChoice = std::nullopt) { cpp << "("; { Scope s(cpp); @@ -1184,7 +1314,7 @@ namespace tigl { if (parentChoice) cpp << "// mandatory elements of this choice must be there"; for (const auto& ce : ces) { - ce.apply_visitor(*this); + std::visit(*this, ce); if (&ce != &ces.back()) cpp << "&&"; } @@ -1204,11 +1334,6 @@ namespace tigl { childCollector(ces); auto& childIndices = childCollector.indices; - auto unique = [](std::vector& v) { - std::sort(std::begin(v), std::end(v)); - const auto it = std::unique(std::begin(v), std::end(v)); - v.erase(it, std::end(v)); - }; unique(allIndices); unique(childIndices); @@ -1308,7 +1433,7 @@ namespace tigl { cpp << "{"; { Scope s(cpp); - cpp << f.fieldName() << ".push_back(make_unique<" << customReplacedType(f) << ">(" << ctorArgumentList(itC->second, c) << "));"; + cpp << f.fieldName() << ".push_back(std::make_unique<" << customReplacedType(f) << ">(" << ctorArgumentList(itC->second, c) << "));"; cpp << "return *" << f.fieldName() << ".back();"; } cpp << "}"; @@ -1451,7 +1576,7 @@ namespace tigl { if (vectorHeader) { deps.hppIncludes.push_back(""); if (makeUnique) { - deps.hppIncludes.push_back("\"UniquePtr.h\""); + deps.hppIncludes.push_back(""); } } if (optionalHeader) { @@ -1509,11 +1634,11 @@ namespace tigl { switch (f.cardinality()) { case Cardinality::Optional: case Cardinality::Mandatory: - deps.hppIncludes.push_back("<" + *p + ".h>"); + deps.hppIncludes.push_back("<" + p->get() + ".h>"); break; case Cardinality::Vector: deps.hppCustomForwards.push_back(*p); - deps.cppIncludes.push_back("<" + *p + ".h>"); + deps.cppIncludes.push_back("<" + p->get() + ".h>"); break; } } @@ -1526,8 +1651,8 @@ namespace tigl { for (const auto& dep : c.deps.parents) { const auto p = m_tables.m_customTypes.find(dep->name); if (p) { - deps.hppCustomForwards.push_back(*p); - deps.cppIncludes.push_back("\"" + *p + ".h\""); + deps.hppCustomForwards.push_back(p->get()); + deps.cppIncludes.push_back("\"" + p->get() + ".h\""); } else { deps.hppForwards.push_back(dep->name); deps.cppIncludes.push_back("\"" + dep->name + ".h\""); @@ -1548,7 +1673,16 @@ namespace tigl { return s[0] == '<'; }); // sort these groups individually - auto icmp = [](const std::string& a, const std::string& b) { return boost::ilexicographical_compare(a, b); }; + // ignore the (potential) capitalization + auto icmp = [](const std::string& a, const std::string& b) { + return std::lexicographical_compare( + a.begin(), a.end(), + b.begin(), b.end(), + [](unsigned char ac, unsigned char bc) { + return std::tolower(ac) < std::tolower(bc); + } + ); + }; std::sort(std::begin(includes), mid, icmp); std::sort(mid, std::end(includes), icmp); const auto& newMid = includes.erase(std::unique(std::begin(includes), mid), mid); @@ -1603,7 +1737,7 @@ namespace tigl { auto parentPointerThis(const Class& c) const -> std::string { const auto cust = m_tables.m_customTypes.find(c.name); if (cust) - return "reinterpret_cast<" + *cust + "*>(this)"; + return "reinterpret_cast<" + cust->get() + "*>(this)"; else return "this"; } @@ -1766,11 +1900,11 @@ namespace tigl { { Scope s(hpp); - boost::optional ops; + std::optional ops; if (!m_namespace.empty()) { hpp << "namespace " << m_namespace; hpp << "{"; - ops = boost::in_place(std::ref(hpp)); + ops.emplace(std::ref(hpp)); } // forward declarations @@ -1860,7 +1994,7 @@ namespace tigl { hpp << "};"; if (!m_namespace.empty()) { - ops = boost::none; + ops = std::nullopt; hpp << "}"; } } @@ -1874,7 +2008,7 @@ namespace tigl { std::vector exportedTypes; const auto& customName = m_tables.m_customTypes.find(c.name); if (customName) { - hpp << "// " << c.name << " is customized, use type " << *customName << " directly"; + hpp << "// " << c.name << " is customized, use type " << customName->get() << " directly"; if (includes.hppForwards.size() > 0) hpp << EmptyLine; } else @@ -1886,18 +2020,18 @@ namespace tigl { if (!exportedTypes.empty()) { hpp << "// Aliases in tigl namespace"; - boost::optional ops; + std::optional ops; if (!m_namespace.empty()) { hpp << "namespace " << m_namespace; hpp << "{"; - ops = boost::in_place(std::ref(hpp)); + ops.emplace(std::ref(hpp)); } for (const auto& name : exportedTypes) hpp << "using C" << name << " = " << generatedNs << "::" << name << ";"; if (!m_namespace.empty()) { - ops = boost::none; + ops = std::nullopt; hpp << "}"; } } @@ -1939,11 +2073,11 @@ namespace tigl { { Scope s(cpp); - boost::optional ops; + std::optional ops; if (!m_namespace.empty()) { cpp << "namespace " << m_namespace; cpp << "{"; - ops = boost::in_place(std::ref(cpp)); + ops.emplace(std::ref(cpp)); } // ctor @@ -1975,7 +2109,7 @@ namespace tigl { writeUidRefObjectFunctionImplementations(cpp, c); if (!m_namespace.empty()) { - ops = boost::none; + ops = std::nullopt; cpp << "}"; } } @@ -2036,11 +2170,11 @@ namespace tigl { { Scope s(hpp); - boost::optional ops; + std::optional ops; if (!m_namespace.empty()) { hpp << "namespace " << m_namespace; hpp << "{"; - ops = boost::in_place(std::ref(hpp)); + ops.emplace(std::ref(hpp)); } // meta information from schema @@ -2102,7 +2236,7 @@ namespace tigl { hpp << "}"; if (!m_namespace.empty()) { - ops = boost::none; + ops = std::nullopt; hpp << "}"; } } @@ -2114,19 +2248,19 @@ namespace tigl { const auto& customName = m_tables.m_customTypes.find(e.name); if (customName) { - hpp << "// " << e.name << " is customized, use type " << *customName << " directly"; + hpp << "// " << e.name << " is customized, use type " << customName->get() << " directly"; } else { hpp << "// Aliases in tigl namespace"; - boost::optional ops; + std::optional ops; if (!m_namespace.empty()) { hpp << "namespace " << m_namespace; hpp << "{"; - ops = boost::in_place(std::ref(hpp)); + ops.emplace(std::ref(hpp)); } hpp << "using E" << e.name << " = " << generatedNs << "::" << e.name << ";"; if (!m_namespace.empty()) { - ops = boost::none; + ops = std::nullopt; hpp << "}"; } } diff --git a/src/lib/Filesystem.cpp b/src/lib/Filesystem.cpp index cae3933..4fca62a 100644 --- a/src/lib/Filesystem.cpp +++ b/src/lib/Filesystem.cpp @@ -5,7 +5,7 @@ #include namespace tigl { - auto readFile(const boost::filesystem::path& filename) -> std::string { + auto readFile(const std::filesystem::path& filename) -> std::string { std::ifstream existingFile(filename.string()); if (!existingFile) return{}; @@ -20,10 +20,10 @@ namespace tigl { return content; } - File::File(boost::filesystem::path filename) + File::File(std::filesystem::path filename) : m_stream(new std::ostringstream), m_filename(std::move(filename)) {} - auto File::path() const -> const boost::filesystem::path& + auto File::path() const -> const std::filesystem::path& { return m_filename; } @@ -37,7 +37,7 @@ namespace tigl { const auto& newContent = file.m_stream->str(); // check if a file already exists - if (boost::filesystem::exists(file.m_filename)) { + if (std::filesystem::exists(file.m_filename)) { // read existing file to string and compare const auto& content = readFile(file.m_filename); @@ -60,19 +60,19 @@ namespace tigl { } } - auto Filesystem::newFile(boost::filesystem::path filename) -> File& { + auto Filesystem::newFile(std::filesystem::path filename) -> File& { m_files.emplace_back(std::move(filename)); return m_files.back(); } - void Filesystem::removeIfExists(const boost::filesystem::path& path) { - if (boost::filesystem::exists(path)) { - boost::filesystem::remove(path); + void Filesystem::removeIfExists(const std::filesystem::path& path) { + if (std::filesystem::exists(path)) { + std::filesystem::remove(path); deleted++; } } - void Filesystem::mergeFilesInto(boost::filesystem::path filename) { + void Filesystem::mergeFilesInto(std::filesystem::path filename) { File f(std::move(filename)); sortFiles(); for (auto& file : m_files) { diff --git a/src/lib/Filesystem.h b/src/lib/Filesystem.h index 26f8723..90cbd92 100644 --- a/src/lib/Filesystem.h +++ b/src/lib/Filesystem.h @@ -1,43 +1,42 @@ #pragma once -#include -#include +#include #include #include #include #include namespace tigl { - auto readFile(const boost::filesystem::path& filename) -> std::string; + auto readFile(const std::filesystem::path& filename) -> std::string; class Filesystem; class File { public: - File(boost::filesystem::path filename); + File(std::filesystem::path filename); File(const File&) = delete; File& operator=(const File&) = delete; File(File&&) = default; File& operator=(File&&) = default; - auto path() const -> const boost::filesystem::path&; + auto path() const -> const std::filesystem::path&; auto stream() -> std::ostream&; private: friend class Filesystem; std::unique_ptr m_stream; // workaround for GCC < 5.0, where stringstream is not moveable .. - boost::filesystem::path m_filename; + std::filesystem::path m_filename; }; class Filesystem { public: Filesystem() = default; - auto newFile(boost::filesystem::path filename) -> File&; - void removeIfExists(const boost::filesystem::path& path); + auto newFile(std::filesystem::path filename) -> File&; + void removeIfExists(const std::filesystem::path& path); - void mergeFilesInto(boost::filesystem::path filename); + void mergeFilesInto(std::filesystem::path filename); void flushToDisk(); diff --git a/src/lib/SchemaParser.cpp b/src/lib/SchemaParser.cpp index 31737ca..33b045d 100644 --- a/src/lib/SchemaParser.cpp +++ b/src/lib/SchemaParser.cpp @@ -1,5 +1,5 @@ -#include -#include +#include +#include #include @@ -256,9 +256,11 @@ namespace tigl { const auto childXPath = (name == "#text") ? xpath + "/text()[" + std::to_string(++childIndex[name]) + "]" : xpath; auto text = document.textElement(childXPath); - static boost::regex r("^\\s*"); - text = boost::regex_replace(text, r, ""); // clear leading whitespace on each line - boost::trim_right(text); // clear trailing whitespace after last line + static std::regex r("^\\s*"); + text = std::regex_replace(text, r, ""); // clear leading whitespace on each line + // clear trailing whitespace after last line + text.erase(std::find_if_not(text.rbegin(), text.rend(), [](unsigned char ch) { return std::isspace(ch); }).base(), + text.end()); if (!result.empty() && result.back() != '\n') result += ' '; result += text; diff --git a/src/lib/Tables.cpp b/src/lib/Tables.cpp index eac0212..e82e6a3 100644 --- a/src/lib/Tables.cpp +++ b/src/lib/Tables.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "Tables.h" @@ -75,15 +76,15 @@ namespace tigl { } bool MappingTable::contains(const std::string& key) const { - return find(key).is_initialized(); + return find(key).has_value(); } - boost::optional MappingTable::find(const std::string& key) const { + std::optional> MappingTable::find(const std::string& key) const { const auto it = m_map.find(key); if (it != std::end(m_map)) return it->second; else - return {}; + return std::nullopt; } void MappingTable::substituteIfExists(const std::string& key, std::string& value) const { diff --git a/src/lib/Tables.h b/src/lib/Tables.h index beb766b..be91025 100644 --- a/src/lib/Tables.h +++ b/src/lib/Tables.h @@ -1,9 +1,9 @@ #pragma once -#include #include #include #include +#include namespace tigl { class Table { @@ -25,7 +25,7 @@ namespace tigl { MappingTable(const std::string& filename); bool contains(const std::string& key) const; - boost::optional find(const std::string& key) const; + std::optional> find(const std::string& key) const; void substituteIfExists(const std::string& key, std::string& value) const; private: diff --git a/src/lib/TypeSystem.cpp b/src/lib/TypeSystem.cpp index fb9c160..9f678e5 100644 --- a/src/lib/TypeSystem.cpp +++ b/src/lib/TypeSystem.cpp @@ -1,11 +1,14 @@ #include "TypeSystem.h" -#include -#include #include #include #include +#include +#include +#include +#include +#include #include "NotImplementedException.h" #include "Tables.h" @@ -76,9 +79,9 @@ namespace tigl { } // elements - struct ContentVisitor : public boost::static_visitor<> { + struct ContentVisitor { ContentVisitor(const xsd::SchemaTypes& types, std::vector& members, ChoiceElements& choiceItems, std::size_t attributeCount, const Tables& tables, std::vector choiceIndices = {}) - : types(types), members(members), choiceItems(choiceItems), attributeCount(attributeCount), tables(tables), choiceIndices(choiceIndices) {} + : types(types), members(members), choiceItems(choiceItems), attributeCount(attributeCount), tables(tables), choiceIndices(std::move(choiceIndices)) {} void emitField(Field f) const { if (!choiceIndices.empty()) { @@ -87,7 +90,14 @@ namespace tigl { f.minOccurs = 0; // give custom name - f.namePostfix = "_choice" + boost::join(choiceIndices | boost::adaptors::transformed([](std::size_t i) { return std::to_string(i); }), "_"); + std::ostringstream oss; + oss << "_choice"; + for (std::size_t i = 0; i < choiceIndices.size(); ++i) { + oss << choiceIndices[i]; + if (i + 1 < choiceIndices.size()) + oss << "_"; + } + f.namePostfix = oss.str(); choiceItems.push_back(ChoiceElement{ members.size(), minBefore == 0 }); } @@ -118,15 +128,14 @@ namespace tigl { Choice choice; choice.minOccurs = c.minOccurs; - for (const auto& v : c.elements | boost::adaptors::indexed(1)) { - // collect members of one choice + for (std::size_t idx = 0; idx < c.elements.size(); ++idx) { auto indices = choiceIndices; - indices.push_back(v.index()); + indices.push_back(idx + 1); // Index starting at 1 ChoiceElements subChoiceItems; - v.value().visit(ContentVisitor(types, members, subChoiceItems, attributeCount, tables, indices)); + c.elements[idx].visit(ContentVisitor(types, members, subChoiceItems, attributeCount, tables, indices)); choice.options.push_back(std::move(subChoiceItems)); } - choiceItems.push_back(std::move(choice)); + choiceItems.push_back(std::make_shared(std::move(choice))); // consistency check, two types with the same name but different types or cardinality are problematic for (std::size_t i = countBefore; i < members.size(); i++) { diff --git a/src/lib/TypeSystem.h b/src/lib/TypeSystem.h index d578fa2..1fa91ed 100644 --- a/src/lib/TypeSystem.h +++ b/src/lib/TypeSystem.h @@ -1,13 +1,14 @@ #pragma once -#include - #include #include #include #include #include #include +#include +#include +#include #include "Variant.hpp" #include "SchemaParser.h" @@ -100,7 +101,7 @@ namespace tigl { }; struct Choice; - using ChoiceElements = std::vector>>; + using ChoiceElements = std::vector>>; struct Choice { unsigned int minOccurs; diff --git a/src/lib/Variant.hpp b/src/lib/Variant.hpp index 24c12a0..5803220 100644 --- a/src/lib/Variant.hpp +++ b/src/lib/Variant.hpp @@ -1,7 +1,7 @@ #pragma once -#include -#include +#include +#include namespace tigl { template @@ -42,7 +42,7 @@ namespace tigl { void visit(Visitor func) { if (m_data) { VisitorWrapper visitor(func); - m_data->apply_visitor(visitor); + std::visit(visitor, *m_data); } } @@ -50,33 +50,33 @@ namespace tigl { void visit(Visitor func) const { if (m_data) { VisitorWrapper visitor(func); - m_data->apply_visitor(visitor); + std::visit(visitor, *m_data); } } template bool is() const { if (m_data) - return m_data->type() == typeid(T); + return std::holds_alternative(*m_data); return false; } template T& as() { - return boost::get(*m_data); + return std::get(*m_data); } template const T& as() const { - return boost::get(*m_data); + return std::get(*m_data); } private: // adapts a visitor for boost template - struct VisitorWrapper : public boost::static_visitor<> { - VisitorWrapper(Func func) - : m_func(func) {} + struct VisitorWrapper { + explicit VisitorWrapper(Func func) + : m_func(std::move(func)) {} template void operator()(T&& arg) { @@ -87,6 +87,6 @@ namespace tigl { Func m_func; }; - boost::optional> m_data; + std::optional> m_data; }; } diff --git a/src/lib/runtime/TixiHelper.h b/src/lib/runtime/TixiHelper.h index 49c1567..2f3faa0 100644 --- a/src/lib/runtime/TixiHelper.h +++ b/src/lib/runtime/TixiHelper.h @@ -19,16 +19,18 @@ #include -#ifndef BOOST_DATE_TIME_NO_LIB - #define BOOST_DATE_TIME_NO_LIB -#endif -#include +#include #include #include #include +#include +#include +#include +#include +#include -#include "UniquePtr.h" +#include #ifndef CPACS_GEN #include "CTiglLogging.h" #endif @@ -38,7 +40,13 @@ namespace tixi { inline std::time_t TixiGetTimeTElement(const TixiDocumentHandle& tixiHandle, const std::string& xpath) { - return boost::posix_time::to_time_t(boost::posix_time::from_iso_extended_string(TixiGetTextElement(tixiHandle, xpath))); + std::string datetimeStr = TixiGetTextElement(tixiHandle, xpath); + + std::tm tm = {}; + std::istringstream ss(datetimeStr); + ss >> std::get_time(&tm, "%Y-%m-%dT%H:%M:%S"); + + return std::mktime(&tm); } template<> @@ -47,9 +55,16 @@ namespace tixi return TixiGetTimeTElement(tixiHandle, xpath); } + inline std::string to_iso_extended_string(std::time_t value) + { + std::ostringstream oss; + oss << std::put_time(std::gmtime(&value), "%Y-%m-%dT%H:%M:%S"); + return oss.str(); + } + inline void TixiSaveElement(const TixiDocumentHandle& tixiHandle, const std::string& xpath, std::time_t value) { - TixiSaveElement(tixiHandle, xpath, boost::posix_time::to_iso_extended_string(boost::posix_time::from_time_t(value))); + TixiSaveElement(tixiHandle, xpath, to_iso_extended_string(value)); } constexpr auto xsdUnbounded = std::numeric_limits::max(); @@ -108,23 +123,11 @@ namespace tixi template void TixiReadElements(const TixiDocumentHandle& tixiHandle, const std::string& xpath, std::vector>& children, unsigned int minOccurs, unsigned int maxOccurs, ChildCtorArgs&&... args) { - // TODO(bgruber): enable when support for g++ < 4.9.0 is dropped - //TixiReadElementsInternal(tixiHandle, xpath, children, minOccurs, maxOccurs, [&](const std::string& childXPath) { - // auto child = tigl::make_unique(std::forward(args)...); - // child->ReadCPACS(tixiHandle, childXPath); - // return child; - //}); - struct Reader { - std::unique_ptr operator()(const std::string& childXPath, ChildCtorArgs&&... args) const - { - auto child = tigl::make_unique(std::forward(args)...); - child->ReadCPACS(tixiHandle, childXPath); - return child; - } - - const TixiDocumentHandle& tixiHandle; - }; - TixiReadElementsInternal(tixiHandle, xpath, children, minOccurs, maxOccurs, Reader{tixiHandle}, std::forward(args)...); + TixiReadElementsInternal(tixiHandle, xpath, children, minOccurs, maxOccurs, [&](const std::string& childXPath) { + auto child = std::make_unique(std::forward(args)...); + child->ReadCPACS(tixiHandle, childXPath); + return child; + }); } template diff --git a/src/lib/runtime/UniquePtr.h b/src/lib/runtime/UniquePtr.h deleted file mode 100644 index d0f5ccd..0000000 --- a/src/lib/runtime/UniquePtr.h +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 2016 RISC Software GmbH -// -// This file is part of the CPACSGen runtime. -// Do not edit, all changes are lost when files are re-deployed. -// -// Licensed under the Apache License, Version 2.0 (the "License") -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include - -namespace tigl -{ - template - using unique_ptr [[deprecated]] = std::unique_ptr; - - template - auto make_unique(Args&&... args) -> std::unique_ptr - { - return std::unique_ptr(new T(std::forward(args)...)); - } -} diff --git a/test/data/all/CustomTypes.txt b/test/data/all/CustomTypes.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/all/ParentPointer.txt b/test/data/all/ParentPointer.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/all/PruneList.txt b/test/data/all/PruneList.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/all/TypeSubstitution.txt b/test/data/all/TypeSubstitution.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/basetypewithparent/CustomTypes.txt b/test/data/basetypewithparent/CustomTypes.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/basetypewithparent/PruneList.txt b/test/data/basetypewithparent/PruneList.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/basetypewithparent/TypeSubstitution.txt b/test/data/basetypewithparent/TypeSubstitution.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/cdata/CustomTypes.txt b/test/data/cdata/CustomTypes.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/cdata/ParentPointer.txt b/test/data/cdata/ParentPointer.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/cdata/PruneList.txt b/test/data/cdata/PruneList.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/cdata/TypeSubstitution.txt b/test/data/cdata/TypeSubstitution.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/cdata/ref.cpp b/test/data/cdata/ref.cpp index 52a7ecb..fcfbc99 100644 --- a/test/data/cdata/ref.cpp +++ b/test/data/cdata/ref.cpp @@ -34,6 +34,7 @@ namespace generated /// This XML-Schema document ( XSD ) serves two purposes: (1) it defines the CPACS data structure used in the XML file (e.g., aircraft.xml) and /// (2) it provides the corresponding documentation (see picture below). An XML processor (e.g., TiXI https://github.com/DLR-SC/tixi or /// XML tools in Eclipse) parses the XSD and XML files and validates whether the data set defined by the user (or tool) conforms to the given structure defined by the schema. + /// @see basicPrinciple /// This documentation explains the elements defined in CPACS and its corresponding data types . /// Data types can either be simple types (string, double, boolean, etc.) or complex types (definition of attributes and sub-elements to build a hierarchical /// structure). In addition, the sequence of the elements and their occurrence is documented. diff --git a/test/data/cdata/schema.xsd b/test/data/cdata/schema.xsd index 1a8699e..a87c989 100644 --- a/test/data/cdata/schema.xsd +++ b/test/data/cdata/schema.xsd @@ -16,7 +16,7 @@ (2) it provides the corresponding documentation (see picture below). An XML processor (e.g., TiXIhttps://github.com/DLR-SC/tixi or XML tools in Eclipse) parses the XSD and XML files and validates whether the data set defined by the user (or tool) conforms to the given structure defined by the schema. - + This documentation explains the elements defined in CPACS and its corresponding data types. Data types can either be simple types (string, double, boolean, etc.) or diff --git a/test/data/choice/CustomTypes.txt b/test/data/choice/CustomTypes.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/choice/ParentPointer.txt b/test/data/choice/ParentPointer.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/choice/PruneList.txt b/test/data/choice/PruneList.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/choice/TypeSubstitution.txt b/test/data/choice/TypeSubstitution.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/collapsedifferentenums/CustomTypes.txt b/test/data/collapsedifferentenums/CustomTypes.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/collapsedifferentenums/ParentPointer.txt b/test/data/collapsedifferentenums/ParentPointer.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/collapsedifferentenums/PruneList.txt b/test/data/collapsedifferentenums/PruneList.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/collapsedifferentenums/TypeSubstitution.txt b/test/data/collapsedifferentenums/TypeSubstitution.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/complextypewithsimplecontent/CustomTypes.txt b/test/data/complextypewithsimplecontent/CustomTypes.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/complextypewithsimplecontent/ParentPointer.txt b/test/data/complextypewithsimplecontent/ParentPointer.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/complextypewithsimplecontent/PruneList.txt b/test/data/complextypewithsimplecontent/PruneList.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/custombasetype/ParentPointer.txt b/test/data/custombasetype/ParentPointer.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/custombasetype/PruneList.txt b/test/data/custombasetype/PruneList.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/custombasetype/TypeSubstitution.txt b/test/data/custombasetype/TypeSubstitution.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/documentation/CustomTypes.txt b/test/data/documentation/CustomTypes.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/documentation/ParentPointer.txt b/test/data/documentation/ParentPointer.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/documentation/PruneList.txt b/test/data/documentation/PruneList.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/documentation/TypeSubstitution.txt b/test/data/documentation/TypeSubstitution.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/optionalchoice/CustomTypes.txt b/test/data/optionalchoice/CustomTypes.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/optionalchoice/ParentPointer.txt b/test/data/optionalchoice/ParentPointer.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/optionalchoice/PruneList.txt b/test/data/optionalchoice/PruneList.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/optionalchoice/TypeSubstitution.txt b/test/data/optionalchoice/TypeSubstitution.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/sequence/CustomTypes.txt b/test/data/sequence/CustomTypes.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/sequence/ParentPointer.txt b/test/data/sequence/ParentPointer.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/sequence/PruneList.txt b/test/data/sequence/PruneList.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/sequence/TypeSubstitution.txt b/test/data/sequence/TypeSubstitution.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/sequence/ref.cpp b/test/data/sequence/ref.cpp index 4efcaba..e5aeaa5 100644 --- a/test/data/sequence/ref.cpp +++ b/test/data/sequence/ref.cpp @@ -59,6 +59,7 @@ namespace generated TIGL_EXPORT virtual std::vector& GetEs(); TIGL_EXPORT virtual size_t GetECount() const; + TIGL_EXPORT virtual const int& GetE(size_t index) const; TIGL_EXPORT virtual int& GetE(size_t index); @@ -69,6 +70,7 @@ namespace generated TIGL_EXPORT virtual std::vector& GetGs(); TIGL_EXPORT virtual size_t GetGCount() const; + TIGL_EXPORT virtual const int& GetG(size_t index) const; TIGL_EXPORT virtual int& GetG(size_t index); @@ -79,6 +81,7 @@ namespace generated TIGL_EXPORT virtual std::vector& GetIs(); TIGL_EXPORT virtual size_t GetICount() const; + TIGL_EXPORT virtual const int& GetI(size_t index) const; TIGL_EXPORT virtual int& GetI(size_t index); @@ -325,19 +328,19 @@ namespace generated int& CPACSRoot::GetE(size_t index) { - index--; - if (index < 0 || index >= GetECount()) { + if (index < 1 || index > GetECount()) { throw CTiglError("Invalid index in std::vector::GetE", TIGL_INDEX_ERROR); } + index--; return m_es[index]; } const int& CPACSRoot::GetE(size_t index) const { - index--; - if (index < 0 || index >= GetECount()) { + if (index < 1 || index > GetECount()) { throw CTiglError("Invalid index in std::vector::GetE", TIGL_INDEX_ERROR); } + index--; return m_es[index]; } @@ -369,19 +372,19 @@ namespace generated int& CPACSRoot::GetG(size_t index) { - index--; - if (index < 0 || index >= GetGCount()) { + if (index < 1 || index > GetGCount()) { throw CTiglError("Invalid index in std::vector::GetG", TIGL_INDEX_ERROR); } + index--; return m_gs[index]; } const int& CPACSRoot::GetG(size_t index) const { - index--; - if (index < 0 || index >= GetGCount()) { + if (index < 1 || index > GetGCount()) { throw CTiglError("Invalid index in std::vector::GetG", TIGL_INDEX_ERROR); } + index--; return m_gs[index]; } @@ -413,19 +416,19 @@ namespace generated int& CPACSRoot::GetI(size_t index) { - index--; - if (index < 0 || index >= GetICount()) { + if (index < 1 || index > GetICount()) { throw CTiglError("Invalid index in std::vector::GetI", TIGL_INDEX_ERROR); } + index--; return m_is[index]; } const int& CPACSRoot::GetI(size_t index) const { - index--; - if (index < 0 || index >= GetICount()) { + if (index < 1 || index > GetICount()) { throw CTiglError("Invalid index in std::vector::GetI", TIGL_INDEX_ERROR); } + index--; return m_is[index]; } diff --git a/test/data/simplebasetypewithparent/CustomTypes.txt b/test/data/simplebasetypewithparent/CustomTypes.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/simplebasetypewithparent/PruneList.txt b/test/data/simplebasetypewithparent/PruneList.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/simplebasetypewithparent/TypeSubstitution.txt b/test/data/simplebasetypewithparent/TypeSubstitution.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/uidinbasetype/CustomTypes.txt b/test/data/uidinbasetype/CustomTypes.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/uidinbasetype/ParentPointer.txt b/test/data/uidinbasetype/ParentPointer.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/uidinbasetype/PruneList.txt b/test/data/uidinbasetype/PruneList.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/uidinbasetype/TypeSubstitution.txt b/test/data/uidinbasetype/TypeSubstitution.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/uidreferencevector/CustomTypes.txt b/test/data/uidreferencevector/CustomTypes.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/uidreferencevector/ParentPointer.txt b/test/data/uidreferencevector/ParentPointer.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/data/uidreferencevector/PruneList.txt b/test/data/uidreferencevector/PruneList.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/main.cpp b/test/main.cpp index eae08d4..beb214c 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -1,5 +1,4 @@ -#define BOOST_TEST_MODULE CPACSGenTests -#include +#include #include "../src/lib/SchemaParser.h" #include "../src/lib/TypeSystem.h" @@ -8,6 +7,9 @@ #include "../src/lib/Filesystem.h" #include "utils.h" +#include +#include +#include void runTest() { const auto testDir = ::testDir(); @@ -27,60 +29,61 @@ void runTest() { const auto ref = readTextFile(refFile); const auto result = readTextFile(resultFile); + if (ref != result) - BOOST_TEST_ERROR("ref and result mismatch. please diff files in filesystem"); + ADD_FAILURE() << "ref and result mismatch. please diff files in filesystem"; else - boost::filesystem::remove(resultFile); + std::filesystem::remove(resultFile); } -BOOST_AUTO_TEST_CASE(sequence) { +TEST(CPACSGenTests, sequence) { runTest(); } -BOOST_AUTO_TEST_CASE(all) { +TEST(CPACSGenTests, all) { runTest(); } -BOOST_AUTO_TEST_CASE(choice) { +TEST(CPACSGenTests, choice) { runTest(); } -BOOST_AUTO_TEST_CASE(documentation) { +TEST(CPACSGenTests, documentation) { runTest(); } -BOOST_AUTO_TEST_CASE(uidinbasetype) { +TEST(CPACSGenTests, uidinbasetype) { runTest(); } -BOOST_AUTO_TEST_CASE(custombasetype) { +TEST(CPACSGenTests, custombasetype) { runTest(); } -BOOST_AUTO_TEST_CASE(basetypewithparent) { +TEST(CPACSGenTests, basetypewithparent) { runTest(); } -BOOST_AUTO_TEST_CASE(uidreferencevector) { +TEST(CPACSGenTests, uidreferencevector) { runTest(); } -BOOST_AUTO_TEST_CASE(cdata) { +TEST(CPACSGenTests, cdata) { runTest(); } -BOOST_AUTO_TEST_CASE(simplebasetypewithparent) { +TEST(CPACSGenTests, simplebasetypewithparent) { runTest(); } -BOOST_AUTO_TEST_CASE(complextypewithsimplecontent) { +TEST(CPACSGenTests, complextypewithsimplecontent) { runTest(); } -BOOST_AUTO_TEST_CASE(collapsedifferentenums) { +TEST(CPACSGenTests, collapsedifferentenums) { runTest(); } -BOOST_AUTO_TEST_CASE(optionalchoice) { +TEST(CPACSGenTests, optionalchoice) { runTest(); -} +} \ No newline at end of file diff --git a/test/utils.cpp b/test/utils.cpp index 5699d74..fb11f0c 100644 --- a/test/utils.cpp +++ b/test/utils.cpp @@ -1,7 +1,8 @@ #include "utils.h" #include +#include -auto readTextFile(const boost::filesystem::path& path) -> std::string { +auto readTextFile(const std::filesystem::path& path) -> std::string { std::ifstream f(path.string()); if (!f) throw std::ios::failure("Failed to open file " + path.string() + " for reading"); @@ -17,9 +18,9 @@ auto readTextFile(const boost::filesystem::path& path) -> std::string { } auto testName() -> std::string { - return boost::unit_test::framework::current_test_case().p_name.get(); + return ::testing::UnitTest::GetInstance()->current_test_info()->name(); } -auto testDir() -> boost::filesystem::path { - return boost::filesystem::path{ c_dataDir } / testName(); +auto testDir() -> std::filesystem::path { + return std::filesystem::path{ c_dataDir } / testName(); } diff --git a/test/utils.h b/test/utils.h index 3436941..bd6d981 100644 --- a/test/utils.h +++ b/test/utils.h @@ -1,12 +1,11 @@ #pragma once -#include -#include +#include #include "paths.h" -auto readTextFile(const boost::filesystem::path& path) -> std::string; +auto readTextFile(const std::filesystem::path& path) -> std::string; auto testName() -> std::string; -auto testDir() -> boost::filesystem::path; +auto testDir() -> std::filesystem::path;