From f825eeae7a6b1bd55068346063b346bdb623f701 Mon Sep 17 00:00:00 2001 From: Benjamin Morgan Date: Wed, 10 Jan 2024 10:11:10 +0100 Subject: [PATCH 1/7] fable: Add example stress test with generated code --- fable/examples/stress/CMakeLists.txt | 34 +++++++++ fable/examples/stress/Makefile | 29 ++++++++ fable/examples/stress/README.md | 2 + fable/examples/stress/conanfile.txt | 15 ++++ fable/examples/stress/gen.py | 104 +++++++++++++++++++++++++++ fable/examples/stress/src/main.cpp | 48 +++++++++++++ 6 files changed, 232 insertions(+) create mode 100644 fable/examples/stress/CMakeLists.txt create mode 100644 fable/examples/stress/Makefile create mode 100644 fable/examples/stress/README.md create mode 100644 fable/examples/stress/conanfile.txt create mode 100755 fable/examples/stress/gen.py create mode 100644 fable/examples/stress/src/main.cpp diff --git a/fable/examples/stress/CMakeLists.txt b/fable/examples/stress/CMakeLists.txt new file mode 100644 index 000000000..0233ff7db --- /dev/null +++ b/fable/examples/stress/CMakeLists.txt @@ -0,0 +1,34 @@ +cmake_minimum_required(VERSION 3.15 FATAL_ERROR) + +project(fable_stress_test LANGUAGES CXX) + +set(LARGE_STRUCT_SIZE 1000 CACHE NUMBER "Number of members of Large struct") + +find_package(CLI11 REQUIRED) +find_package(fable REQUIRED) +find_package(fmt REQUIRED) + +# Executable --------------------------------------------------------- +add_custom_command( + OUTPUT large_struct.hxx + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/gen.py ${LARGE_STRUCT_SIZE} ${CMAKE_CURRENT_BINARY_DIR}/large_struct.hxx + VERBATIM +) +add_executable(stress + src/main.cpp + large_struct.hxx +) +target_include_directories(stress + PRIVATE + ${CMAKE_CURRENT_BINARY_DIR} +) +set_target_properties(stress PROPERTIES + CXX_STANDARD 17 + CXX_STANDARD_REQUIRED ON +) +target_link_libraries(stress + PRIVATE + fable::fable + fmt::fmt + CLI11::CLI11 +) diff --git a/fable/examples/stress/Makefile b/fable/examples/stress/Makefile new file mode 100644 index 000000000..65017b2e0 --- /dev/null +++ b/fable/examples/stress/Makefile @@ -0,0 +1,29 @@ +# This is a minimal Makefile to show how this example project +# can be built with Conan and CMake. + +# All generated and compiled output is in this directory. +BUILD_DIR := build + +# The build type must be synchronized between Conan (host build type) +# and CMake, otherwise you will get strange and unhelpful errors. +BUILD_TYPE := Release +CMAKE_BUILD_TYPE := $(shell echo ${BUILD_TYPE} | tr '[:upper:]' '[:lower:]') + +# This is the output that Conan generates when using +# `CMakeToolchain` generator AND the `cmake_layout` layout. +TOOLCHAIN_FILE := ${BUILD_DIR}/${BUILD_TYPE}/generators/conan_toolchain.cmake + +# How many variables should the "Large" struct have? +LARGE_STRUCT_SIZE := 1000 + +.PHONY: all clean +all: ${TOOLCHAIN_FILE} + cmake --build --preset=${CMAKE_BUILD_TYPE} + +${TOOLCHAIN_FILE}: + conan install . --build=missing --install-folder=${BUILD_DIR} -s:h build_type=${BUILD_TYPE} + cmake --preset=${CMAKE_BUILD_TYPE} -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DLARGE_STRUCT_SIZE=${LARGE_STRUCT_SIZE} + +clean: + -rm -r ${BUILD_DIR} + -rm CMakeUserPresets.json diff --git a/fable/examples/stress/README.md b/fable/examples/stress/README.md new file mode 100644 index 000000000..264d66e7c --- /dev/null +++ b/fable/examples/stress/README.md @@ -0,0 +1,2 @@ +This example project stresses the compiler by forcing it to compile +an extremely large struct. diff --git a/fable/examples/stress/conanfile.txt b/fable/examples/stress/conanfile.txt new file mode 100644 index 000000000..6a9e895a6 --- /dev/null +++ b/fable/examples/stress/conanfile.txt @@ -0,0 +1,15 @@ +# This is a minimal conanfile.txt to show how this example project +# can be built with Conan and CMake. + +[requires] +cli11/2.3.2 +fable/[>=0.20.0, include_prerelease=True]@cloe/develop +fmt/9.1.0 +boost/[>=1.65.1] + +[generators] +CMakeDeps +CMakeToolchain + +[layout] +cmake_layout diff --git a/fable/examples/stress/gen.py b/fable/examples/stress/gen.py new file mode 100755 index 000000000..5b9755762 --- /dev/null +++ b/fable/examples/stress/gen.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python3 + +import random +import string +import argparse + +SIMPLE_TYPES = [ + "bool", + "uint8_t", + "uint16_t", + "uint32_t", + "uint64_t", + "int8_t", + "int16_t", + "int32_t", + "int64_t", + "std::string", +] + +COMPLEX_TYPES = [ + "std::vector", + "std::map", + "boost::optional", + # "std::array", # not supported yet +] + +ALL_TYPES = SIMPLE_TYPES + COMPLEX_TYPES + +def generate_random_type(): + def _tvector(): + inner = random.choice(SIMPLE_TYPES) + return f"std::vector<{inner}>" + + def _tmap(): + inner = random.choice(SIMPLE_TYPES) + return f"std::map" + + def _toptional(): + inner = random.choice(SIMPLE_TYPES) + return f"boost::optional<{inner}>" + + def _tarray(): + inner = random.choice(SIMPLE_TYPES) + length = random.randint(2, 24) + return f"std::array<{inner}, {length}>" + + mapper = { + "std::vector": _tvector, + "std::map": _tmap, + "boost::optional": _toptional, + } + + result = random.choice(ALL_TYPES) + if result in COMPLEX_TYPES: + return mapper[result]() + return result + +def generate_random_word(): + letters = string.ascii_letters + return ''.join(random.choice(letters) for _ in range(20)) + +TEMPLATE = string.Template(""" +#pragma once + +struct Large : public fable::Confable { + $variable_lines + + CONFABLE_SCHEMA(Large) { + using namespace fable; + return Schema{ + $schema_lines + }; + } +}; +""") + +def generate(count) -> str: + variable_lines = [] + schema_lines = [] + for i in range(count): + random_word = generate_random_word() + variable_lines.append(f"{generate_random_type()} v{i};") + schema_lines.append('{{"{0}", make_schema(&v{1}, "")}},'.format(random_word, i)) + result = TEMPLATE.substitute({ + "variable_lines": "\n ".join(variable_lines), + "schema_lines": "\n ".join(schema_lines), + }) + return result + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("count", default=10, type=int) + parser.add_argument("output", default="-", type=str) + args = parser.parse_args() + + result = generate(args.count) + if args.output == "-": + print(result) + else: + with open(args.output, "w") as file: + file.write(result) + +if __name__ == "__main__": + main() diff --git a/fable/examples/stress/src/main.cpp b/fable/examples/stress/src/main.cpp new file mode 100644 index 000000000..8c13895f9 --- /dev/null +++ b/fable/examples/stress/src/main.cpp @@ -0,0 +1,48 @@ +/* + * Copyright 2021 Robert Bosch GmbH + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * \file fable/examples/stress/src/main.cpp + * + * In this example application, we will stress-test the compilation. + * We will be re-using types from the contacts example. + */ + +#include // for std::{cout, cerr} +#include // for std::string<> +#include // for std::vector<> + +#include // for fmt::format +#include // for CLI::App +#include // for boost::optional<> + +#include // for fable::{Confable, CONFABLE_SCHEMA} +#include // for fable::{Schema, String} +#include // for fable::{read_conf} + +#include "large_struct.hxx" + +int main(int argc, char** argv) { + // Parse command line arguments: + CLI::App app("Fable Stress Test Example"); + std::string filename; + CLI11_PARSE(app, argc, argv); + + Large large; + std::cout << large.schema().to_json().dump(2) << std::endl; +} From 184a14278bd0d6e960abee67294b4e913464b875 Mon Sep 17 00:00:00 2001 From: Martin Henselmeyer Date: Fri, 15 Dec 2023 09:40:54 +0100 Subject: [PATCH 2/7] fable: Fix excessive compilation duration BREAKING CHANGES: - Removed all make_schema() functions that do not fall into one of the two signatures: make_schema(T*, std::string&&) make_schema(T*, P&&, std::string&&) So far, only the two forms above have been used, and the others aren't strictly required and don't contribute to readability. --- fable/include/fable/make_schema.hpp | 103 ++++++++++++++++++++++++ fable/include/fable/schema.hpp | 25 +----- fable/include/fable/schema/array.hpp | 14 ++-- fable/include/fable/schema/boolean.hpp | 2 +- fable/include/fable/schema/confable.hpp | 2 +- fable/include/fable/schema/const.hpp | 10 +-- fable/include/fable/schema/duration.hpp | 2 +- fable/include/fable/schema/enum.hpp | 2 +- fable/include/fable/schema/ignore.hpp | 4 - fable/include/fable/schema/json.hpp | 5 -- fable/include/fable/schema/magic.hpp | 12 +-- fable/include/fable/schema/map.hpp | 14 ++-- fable/include/fable/schema/number.hpp | 2 +- fable/include/fable/schema/optional.hpp | 10 +-- fable/include/fable/schema/passthru.hpp | 12 +-- fable/include/fable/schema/path.hpp | 2 +- fable/include/fable/schema/string.hpp | 2 +- fable/include/fable/schema/struct.hpp | 20 ----- fable/include/fable/schema/variant.hpp | 10 --- 19 files changed, 148 insertions(+), 105 deletions(-) create mode 100644 fable/include/fable/make_schema.hpp diff --git a/fable/include/fable/make_schema.hpp b/fable/include/fable/make_schema.hpp new file mode 100644 index 000000000..46a8ec486 --- /dev/null +++ b/fable/include/fable/make_schema.hpp @@ -0,0 +1,103 @@ +/* + * Copyright 2023 Robert Bosch GmbH + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * \file fable/make_schema.hpp + * + * This file provides a facade for the make_schema function which implements + * a short-cut for the compiler which reduces the excessive resource + * consumption of the actual implementation. + */ + +#pragma once + +#include // for string + +#include // for Array<> +#include // for Boolean +#include // for FromConfable +#include // for Const<> +#include // for Duration<> +#include // for Enum<> +#include // for Ignore +#include // for Interface, Box +#include // for FromJson<> +#include // for Map<> +#include // for Number<> +#include // for Optional<> +#include // for Passthru +#include // for Path +#include // for String +#include // for Struct +#include // for Variant + +// It is important that this include comes after all the other ones, +// so that it has access to ALL the previous definitions. +#include // for make_prototype, ... + +namespace fable::schema { +namespace details { + +/** + * Implements the make_schema function for one datatype + */ +template +struct make_schema_wrapper1 { + static auto make_schema(T* ptr, std::string&& desc) { + return ::fable::schema::make_schema_impl(ptr, std::move(desc)); + } +}; + +/** + */ +template +struct make_schema_wrapper2 { + static auto make_schema(T* ptr, P proto, std::string&& desc) { + return ::fable::schema::make_schema_impl(ptr, std::move(proto), std::move(desc)); + } +}; + +} // namespace details + +/** + * Returns the schema for a given datum and its description + * + * \param ptr Pointer to the datum + * \param desc Textual description of the datum + * \return Schema for the datum + */ +template +auto make_schema(T* ptr, std::string&& desc) { + return details::make_schema_wrapper1::make_schema(ptr, std::move(desc)); +} + +/** + * Returns the schema for a given datum and its description + * + * \param ptr Pointer to the datum + * \param proto Prototype of the data-value + * \param desc Textual description of the datum + * \return Schema for the datum + * \note Those types which have a prototype, namely string & path + * do not matter for the compile-time reduction + */ +template +auto make_schema(T* ptr, P proto, std::string&& desc) { + return details::make_schema_wrapper2::make_schema(ptr, std::move(proto), std::move(desc)); +} + +} // namespace fable::schema diff --git a/fable/include/fable/schema.hpp b/fable/include/fable/schema.hpp index 86cab04ca..49c6b680d 100644 --- a/fable/include/fable/schema.hpp +++ b/fable/include/fable/schema.hpp @@ -122,29 +122,7 @@ #include // for move #include // for vector<> -#include // for optional<> - -#include // for Array<> -#include // for Boolean -#include // for FromConfable -#include // for Const<> -#include // for Duration<> -#include // for Enum<> -#include // for Ignore -#include // for Interface, Box -#include // for FromJson<> -#include // for Map<> -#include // for Number<> -#include // for Optional<> -#include // for Passthru -#include // for Path -#include // for String -#include // for Struct -#include // for Variant - -// It is important that this include comes after all the other ones, -// so that it has access to ALL the previous definitions. -#include // for make_prototype, ... +#include // for make_schema namespace fable { @@ -153,6 +131,7 @@ using schema::make_const_schema; using schema::make_const_str; using schema::make_prototype; using schema::make_schema; +using schema::make_schema_impl; /** * Define the automatically deduced schema class of a given type. diff --git a/fable/include/fable/schema/array.hpp b/fable/include/fable/schema/array.hpp index cfb7ed800..370686f09 100644 --- a/fable/include/fable/schema/array.hpp +++ b/fable/include/fable/schema/array.hpp @@ -40,13 +40,13 @@ template class Array : public Base> { public: // Types and Constructors using Type = std::vector; - using PrototypeSchema = P; + using PrototypeSchema = std::remove_cv_t>; Array(Type* ptr, std::string&& desc); - Array(Type* ptr, const PrototypeSchema& prototype) - : Base>(JsonType::array), prototype_(prototype), ptr_(ptr) {} - Array(Type* ptr, const PrototypeSchema& prototype, std::string&& desc) - : Base>(JsonType::array, std::move(desc)), prototype_(prototype), ptr_(ptr) {} + Array(Type* ptr, PrototypeSchema prototype) + : Base>(JsonType::array), prototype_(std::move(prototype)), ptr_(ptr) {} + Array(Type* ptr, PrototypeSchema prototype, std::string&& desc) + : Base>(JsonType::array, std::move(desc)), prototype_(std::move(prototype)), ptr_(ptr) {} #if 0 // This is defined in: fable/schema/magic.hpp @@ -174,8 +174,8 @@ class Array : public Base> { }; template -Array make_schema(std::vector* ptr, const P& prototype, std::string&& desc) { - return Array(ptr, prototype, std::move(desc)); +Array make_schema_impl(std::vector* ptr, P&& prototype, std::string&& desc) { + return Array(ptr, std::forward

(prototype), std::move(desc)); } } // namespace schema diff --git a/fable/include/fable/schema/boolean.hpp b/fable/include/fable/schema/boolean.hpp index ed3d695a3..1756d7f62 100644 --- a/fable/include/fable/schema/boolean.hpp +++ b/fable/include/fable/schema/boolean.hpp @@ -51,7 +51,7 @@ class Boolean : public Base { Type* ptr_{nullptr}; }; -inline Boolean make_schema(bool* ptr, std::string&& desc) { return Boolean(ptr, std::move(desc)); } +inline Boolean make_schema_impl(bool* ptr, std::string&& desc) { return Boolean(ptr, std::move(desc)); } } // namespace schema } // namespace fable diff --git a/fable/include/fable/schema/confable.hpp b/fable/include/fable/schema/confable.hpp index 06bd0e835..1bf846d52 100644 --- a/fable/include/fable/schema/confable.hpp +++ b/fable/include/fable/schema/confable.hpp @@ -104,7 +104,7 @@ class FromConfable : public Base> { }; template -FromConfable make_schema(T* ptr, std::string&& desc) { +FromConfable make_schema_impl(T* ptr, std::string&& desc) { assert(ptr != nullptr); return FromConfable(ptr, std::move(desc)); } diff --git a/fable/include/fable/schema/const.hpp b/fable/include/fable/schema/const.hpp index d4abdaf8b..666e0dcd7 100644 --- a/fable/include/fable/schema/const.hpp +++ b/fable/include/fable/schema/const.hpp @@ -37,12 +37,12 @@ template class Const : public Base> { public: // Types and Constructors using Type = T; - using PrototypeSchema = P; + using PrototypeSchema = std::remove_cv_t>; Const(const Type& constant, std::string&& desc); - Const(const Type& constant, const PrototypeSchema& prototype, std::string&& desc) + Const(const Type& constant, PrototypeSchema prototype, std::string&& desc) : Base>(prototype.type(), std::move(desc)) - , prototype_(prototype) + , prototype_(std::move(prototype)) , constant_(constant) { prototype_.reset_ptr(); } @@ -89,8 +89,8 @@ class Const : public Base> { }; template -Const make_const_schema(const T& constant, const P& prototype, std::string&& desc) { - return Const(constant, prototype, std::move(desc)); +Const make_const_schema(const T& constant, P&& prototype, std::string&& desc) { + return Const(constant, std::forward

(prototype), std::move(desc)); } inline Const make_const_str(const std::string& constant, std::string&& desc) { diff --git a/fable/include/fable/schema/duration.hpp b/fable/include/fable/schema/duration.hpp index edaf6cb66..a7acc0c6a 100644 --- a/fable/include/fable/schema/duration.hpp +++ b/fable/include/fable/schema/duration.hpp @@ -187,7 +187,7 @@ class Duration : public Base> { }; template -inline Duration make_schema(std::chrono::duration* ptr, +inline Duration make_schema_impl(std::chrono::duration* ptr, std::string&& desc) { return Duration(ptr, std::move(desc)); } diff --git a/fable/include/fable/schema/enum.hpp b/fable/include/fable/schema/enum.hpp index 91a7c1158..6eb11ea7c 100644 --- a/fable/include/fable/schema/enum.hpp +++ b/fable/include/fable/schema/enum.hpp @@ -103,7 +103,7 @@ class Enum : public Base> { }; template ::value, int> = 0> -inline Enum make_schema(T* ptr, std::string&& desc) { +inline Enum make_schema_impl(T* ptr, std::string&& desc) { return Enum(ptr, std::move(desc)); } diff --git a/fable/include/fable/schema/ignore.hpp b/fable/include/fable/schema/ignore.hpp index 4973345ca..b62c1c48b 100644 --- a/fable/include/fable/schema/ignore.hpp +++ b/fable/include/fable/schema/ignore.hpp @@ -60,9 +60,5 @@ class Ignore : public Base { void reset_ptr() override {} }; -inline Ignore make_schema(std::string&& desc, JsonType t = JsonType::object) { - return Ignore(std::move(desc), t); -} - } // namespace schema } // namespace fable diff --git a/fable/include/fable/schema/json.hpp b/fable/include/fable/schema/json.hpp index 09ae6cfd3..883f9fb5d 100644 --- a/fable/include/fable/schema/json.hpp +++ b/fable/include/fable/schema/json.hpp @@ -79,10 +79,5 @@ class FromJson : public Base> { Type* ptr_{nullptr}; }; -template -inline FromJson make_schema(T* ptr, JsonType t, std::string&& desc) { - return FromJson(ptr, t, std::move(desc)); -} - } // namespace schema } // namespace fable diff --git a/fable/include/fable/schema/magic.hpp b/fable/include/fable/schema/magic.hpp index 4e69e1b77..a5ef24fe3 100644 --- a/fable/include/fable/schema/magic.hpp +++ b/fable/include/fable/schema/magic.hpp @@ -21,10 +21,10 @@ * \see fable/schema_test.cpp * * This file defines the `make_prototype` functions that can automatically - * derive the prototype via the `make_schema` functions. It also contains the + * derive the prototype via the `make_schema_impl` functions. It also contains the * definitions of constructors that make use of these functions. * - * Unfortunately, all `make_schema` functions need to already be defined at the + * Unfortunately, all `make_schema_impl` functions need to already be defined at the * point of definition of these constructors, which is why they have to be in * this file in the first place. * @@ -58,7 +58,7 @@ Array::Array(std::vector* ptr, std::string&& desc) : Array(ptr, make_prototype(), std::move(desc)) {} template -Array())> make_schema(std::vector* ptr, std::string&& desc) { +Array())> make_schema_impl(std::vector* ptr, std::string&& desc) { return Array())>(ptr, std::move(desc)); } @@ -76,7 +76,7 @@ Map::Map(std::map* ptr, std::string&& desc) : Map(ptr, make_prototype(), std::move(desc)) {} template -Map())> make_schema(std::map* ptr, +Map())> make_schema_impl(std::map* ptr, std::string&& desc) { return Map())>(ptr, std::move(desc)); } @@ -86,7 +86,7 @@ Optional::Optional(boost::optional* ptr, std::string&& desc) : Optional(ptr, make_prototype(), std::move(desc)) {} template -Optional())> make_schema(boost::optional* ptr, +Optional())> make_schema_impl(boost::optional* ptr, std::string&& desc) { return Optional())>(ptr, std::move(desc)); } @@ -98,7 +98,7 @@ auto make_prototype(std::string&& desc) { template ::value, int>> auto make_prototype(std::string&& desc) { - return make_schema(static_cast(nullptr), std::move(desc)); + return make_schema_impl(static_cast(nullptr), std::move(desc)); } } // namespace schema diff --git a/fable/include/fable/schema/map.hpp b/fable/include/fable/schema/map.hpp index 3d52a3418..127722560 100644 --- a/fable/include/fable/schema/map.hpp +++ b/fable/include/fable/schema/map.hpp @@ -50,15 +50,15 @@ template class Map : public Base> { public: // Types and Constructors using Type = std::map; - using PrototypeSchema = P; + using PrototypeSchema = std::remove_cv_t>; Map(Type* ptr, std::string&& desc); - Map(Type* ptr, const PrototypeSchema& prototype) - : Base>(JsonType::object), prototype_(prototype), ptr_(ptr) { + Map(Type* ptr, PrototypeSchema prototype) + : Base>(JsonType::object), prototype_(std::move(prototype)), ptr_(ptr) { prototype_.reset_ptr(); } - Map(Type* ptr, const PrototypeSchema& prototype, std::string&& desc) - : Base>(JsonType::object, std::move(desc)), prototype_(prototype), ptr_(ptr) { + Map(Type* ptr, PrototypeSchema prototype, std::string&& desc) + : Base>(JsonType::object, std::move(desc)), prototype_(std::move(prototype)), ptr_(ptr) { prototype_.reset_ptr(); } @@ -189,8 +189,8 @@ class Map : public Base> { }; template -Map make_schema(std::map* ptr, const P& prototype, std::string&& desc) { - return Map(ptr, prototype, std::move(desc)); +Map make_schema_impl(std::map* ptr, P&& prototype, std::string&& desc) { + return Map(ptr, std::forward

(prototype), std::move(desc)); } } // namespace schema diff --git a/fable/include/fable/schema/number.hpp b/fable/include/fable/schema/number.hpp index 305ed5492..068a50bce 100644 --- a/fable/include/fable/schema/number.hpp +++ b/fable/include/fable/schema/number.hpp @@ -104,7 +104,7 @@ class Number : public Base> { template ::value && !std::is_enum::value, int> = 0> -inline Number make_schema(T* ptr, std::string&& desc) { +inline Number make_schema_impl(T* ptr, std::string&& desc) { return Number(ptr, std::move(desc)); } diff --git a/fable/include/fable/schema/optional.hpp b/fable/include/fable/schema/optional.hpp index ae67180db..fa111e4b4 100644 --- a/fable/include/fable/schema/optional.hpp +++ b/fable/include/fable/schema/optional.hpp @@ -39,11 +39,11 @@ template class Optional : public Base> { public: // Types and Constructors using Type = boost::optional; - using PrototypeSchema = P; + using PrototypeSchema = std::remove_cv_t>; Optional(Type* ptr, std::string&& desc); - Optional(Type* ptr, const PrototypeSchema& prototype, std::string&& desc) - : Base>(prototype.type(), std::move(desc)), prototype_(prototype), ptr_(ptr) { + Optional(Type* ptr, PrototypeSchema prototype, std::string&& desc) + : Base>(prototype.type(), std::move(desc)), prototype_(std::move(prototype)), ptr_(ptr) { prototype_.reset_ptr(); } @@ -113,8 +113,8 @@ class Optional : public Base> { }; template -Optional make_schema(boost::optional* ptr, const P& prototype, std::string&& desc) { - return Optional(ptr, prototype, std::move(desc)); +Optional make_schema_impl(boost::optional* ptr, P&& prototype, std::string&& desc) { + return Optional(ptr, std::forward

(prototype), std::move(desc)); } } // namespace schema diff --git a/fable/include/fable/schema/passthru.hpp b/fable/include/fable/schema/passthru.hpp index 78ef45244..d514b8066 100644 --- a/fable/include/fable/schema/passthru.hpp +++ b/fable/include/fable/schema/passthru.hpp @@ -46,12 +46,12 @@ template class Passthru : public Base> { public: // Types and Constructors using Type = Conf; - using PrototypeSchema = P; + using PrototypeSchema = std::remove_cv_t>; Passthru(Type* ptr, std::string&& desc) : Passthru(ptr, PrototypeSchema(nullptr, ""), std::move(desc)) {} - Passthru(Type* ptr, const PrototypeSchema& prototype, std::string&& desc) - : Base>(prototype.type(), std::move(desc)), prototype_(prototype), ptr_(ptr) { + Passthru(Type* ptr, PrototypeSchema prototype, std::string&& desc) + : Base>(prototype.type(), std::move(desc)), prototype_(std::move(prototype)), ptr_(ptr) { prototype_.reset_ptr(); } @@ -92,13 +92,13 @@ class Passthru : public Base> { Type* ptr_{nullptr}; }; -inline Passthru make_schema(Conf* ptr, std::string&& desc) { +inline Passthru make_schema_impl(Conf* ptr, std::string&& desc) { return Passthru(ptr, Ignore(), std::move(desc)); } template -Passthru

make_schema(Conf* ptr, const P& prototype, std::string&& desc) { - return Passthru

(ptr, prototype, std::move(desc)); +Passthru

make_schema_impl(Conf* ptr, P&& prototype, std::string&& desc) { + return Passthru

(ptr, std::forward

(prototype), std::move(desc)); } } // namespace schema diff --git a/fable/include/fable/schema/path.hpp b/fable/include/fable/schema/path.hpp index b17536747..abbbcf76a 100644 --- a/fable/include/fable/schema/path.hpp +++ b/fable/include/fable/schema/path.hpp @@ -213,7 +213,7 @@ class Path : public Base { Type* ptr_{nullptr}; }; -inline Path make_schema(boost::filesystem::path* ptr, std::string&& desc) { +inline Path make_schema_impl(boost::filesystem::path* ptr, std::string&& desc) { return Path(ptr, std::move(desc)); } diff --git a/fable/include/fable/schema/string.hpp b/fable/include/fable/schema/string.hpp index 5d3ba12a0..54bea643e 100644 --- a/fable/include/fable/schema/string.hpp +++ b/fable/include/fable/schema/string.hpp @@ -261,7 +261,7 @@ class String : public Base { Type* ptr_{nullptr}; }; -inline String make_schema(std::string* ptr, std::string&& desc) { +inline String make_schema_impl(std::string* ptr, std::string&& desc) { return String(ptr, std::move(desc)); } diff --git a/fable/include/fable/schema/struct.hpp b/fable/include/fable/schema/struct.hpp index efa95ac2e..dae7f046a 100644 --- a/fable/include/fable/schema/struct.hpp +++ b/fable/include/fable/schema/struct.hpp @@ -217,25 +217,5 @@ class Struct : public Base { bool additional_properties_{false}; }; -template > -inline Struct make_schema(T&& props) { - return Struct(std::forward(props)); -} - -template > -inline Struct make_schema(std::string&& desc, T&& props) { - return Struct(std::move(desc), std::forward(props)); -} - -template > -inline Struct make_schema(std::string&& desc, const Box& base, T&& props) { - return Struct(std::move(desc), base, std::forward(props)); -} - -template > -inline Struct make_schema(std::string&& desc, const Struct& base, T&& props) { - return Struct(std::move(desc), base, std::forward(props)); -} - } // namespace schema } // namespace fable diff --git a/fable/include/fable/schema/variant.hpp b/fable/include/fable/schema/variant.hpp index f424102ae..05176f9a1 100644 --- a/fable/include/fable/schema/variant.hpp +++ b/fable/include/fable/schema/variant.hpp @@ -125,15 +125,5 @@ class Variant : public Interface { bool unique_match_{false}; }; -inline Variant make_schema(std::initializer_list vec) { return Variant(vec); } -inline Variant make_schema(std::string&& desc, std::initializer_list vec) { - return Variant(std::move(desc), std::vector(vec)); -} - -inline Variant make_schema(std::vector&& vec) { return Variant(std::move(vec)); } -inline Variant make_schema(std::string&& desc, std::vector&& vec) { - return Variant(std::move(desc), std::move(vec)); -} - } // namespace schema } // namespace fable From 1318e8fff6e81d922f298c5ac149c8c5e4bff6b5 Mon Sep 17 00:00:00 2001 From: Benjamin Morgan Date: Wed, 10 Jan 2024 20:22:53 +0100 Subject: [PATCH 3/7] fixup! fable: Add example stress test with generated code --- fable/examples/stress/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fable/examples/stress/Makefile b/fable/examples/stress/Makefile index 65017b2e0..24d3172d0 100644 --- a/fable/examples/stress/Makefile +++ b/fable/examples/stress/Makefile @@ -16,12 +16,14 @@ TOOLCHAIN_FILE := ${BUILD_DIR}/${BUILD_TYPE}/generators/conan_toolchain.cmake # How many variables should the "Large" struct have? LARGE_STRUCT_SIZE := 1000 +FABLE_VERSION := $(shell make --quiet -C ../.. info-fqn) + .PHONY: all clean all: ${TOOLCHAIN_FILE} cmake --build --preset=${CMAKE_BUILD_TYPE} ${TOOLCHAIN_FILE}: - conan install . --build=missing --install-folder=${BUILD_DIR} -s:h build_type=${BUILD_TYPE} + conan install . --build=missing --install-folder=${BUILD_DIR} -s:h build_type=${BUILD_TYPE} --require-override ${FABLE_VERSION} cmake --preset=${CMAKE_BUILD_TYPE} -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DLARGE_STRUCT_SIZE=${LARGE_STRUCT_SIZE} clean: From aa8828de2a73ae7d7083667483ac19b451aa3370 Mon Sep 17 00:00:00 2001 From: Benjamin Morgan Date: Wed, 10 Jan 2024 20:23:44 +0100 Subject: [PATCH 4/7] fixup! fable: Fix excessive compilation duration --- fable/CMakeLists.txt | 1 + fable/include/fable/make_schema.hpp | 20 ++++++++++++++++++++ fable/src/fable/make_schema.cpp | 27 +++++++++++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 fable/src/fable/make_schema.cpp diff --git a/fable/CMakeLists.txt b/fable/CMakeLists.txt index 1fb9ab765..890339bd4 100644 --- a/fable/CMakeLists.txt +++ b/fable/CMakeLists.txt @@ -24,6 +24,7 @@ add_library(${target} src/fable/confable.cpp src/fable/json.cpp src/fable/schema.cpp + src/fable/make_schema.cpp src/fable/schema/boolean.cpp src/fable/schema/number.cpp src/fable/schema/struct.cpp diff --git a/fable/include/fable/make_schema.hpp b/fable/include/fable/make_schema.hpp index 46a8ec486..0eb21e78c 100644 --- a/fable/include/fable/make_schema.hpp +++ b/fable/include/fable/make_schema.hpp @@ -100,4 +100,24 @@ auto make_schema(T* ptr, P proto, std::string&& desc) { return details::make_schema_wrapper2::make_schema(ptr, std::move(proto), std::move(desc)); } +// Pre-Instantiate above templates for relevant datatypes + +#define FABLE_TYPES() \ + FABLE_TYPES_X(bool) \ + FABLE_TYPES_X(int8_t) \ + FABLE_TYPES_X(uint8_t) \ + FABLE_TYPES_X(int16_t) \ + FABLE_TYPES_X(uint16_t) \ + FABLE_TYPES_X(int32_t) \ + FABLE_TYPES_X(uint32_t) \ + FABLE_TYPES_X(int64_t) \ + FABLE_TYPES_X(uint64_t) \ + FABLE_TYPES_X(float) \ + FABLE_TYPES_X(double) + +#define FABLE_TYPES_X(TYPE) \ + extern template struct ::fable::schema::details::make_schema_wrapper1; + +FABLE_TYPES() + } // namespace fable::schema diff --git a/fable/src/fable/make_schema.cpp b/fable/src/fable/make_schema.cpp new file mode 100644 index 000000000..ae53778e1 --- /dev/null +++ b/fable/src/fable/make_schema.cpp @@ -0,0 +1,27 @@ +/* + * Copyright 2023 Robert Bosch GmbH + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +namespace fable::schema { + +#define extern +FABLE_TYPES() +#undef extern + +} From 4138aff83510745f9269f3fe0a1f8330a91b975f Mon Sep 17 00:00:00 2001 From: Benjamin Morgan Date: Tue, 20 Feb 2024 12:38:55 +0100 Subject: [PATCH 5/7] fixup! fable: Add example stress test with generated code --- fable/CMakeLists.txt | 1 - fable/include/fable/make_schema.hpp | 123 ----------------------- fable/include/fable/schema.hpp | 23 ++++- fable/include/fable/schema/array.hpp | 6 +- fable/include/fable/schema/boolean.hpp | 3 +- fable/include/fable/schema/confable.hpp | 6 +- fable/include/fable/schema/const.hpp | 15 ++- fable/include/fable/schema/duration.hpp | 7 +- fable/include/fable/schema/enum.hpp | 6 +- fable/include/fable/schema/interface.hpp | 8 +- fable/include/fable/schema/magic.hpp | 43 ++++---- fable/include/fable/schema/map.hpp | 6 +- fable/include/fable/schema/number.hpp | 7 +- fable/include/fable/schema/optional.hpp | 6 +- fable/include/fable/schema/passthru.hpp | 11 +- fable/include/fable/schema/path.hpp | 5 +- fable/include/fable/schema/string.hpp | 5 +- fable/src/fable/make_schema.cpp | 27 ----- 18 files changed, 87 insertions(+), 221 deletions(-) delete mode 100644 fable/include/fable/make_schema.hpp delete mode 100644 fable/src/fable/make_schema.cpp diff --git a/fable/CMakeLists.txt b/fable/CMakeLists.txt index 890339bd4..1fb9ab765 100644 --- a/fable/CMakeLists.txt +++ b/fable/CMakeLists.txt @@ -24,7 +24,6 @@ add_library(${target} src/fable/confable.cpp src/fable/json.cpp src/fable/schema.cpp - src/fable/make_schema.cpp src/fable/schema/boolean.cpp src/fable/schema/number.cpp src/fable/schema/struct.cpp diff --git a/fable/include/fable/make_schema.hpp b/fable/include/fable/make_schema.hpp deleted file mode 100644 index 0eb21e78c..000000000 --- a/fable/include/fable/make_schema.hpp +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2023 Robert Bosch GmbH - * - * 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. - * - * SPDX-License-Identifier: Apache-2.0 - */ -/** - * \file fable/make_schema.hpp - * - * This file provides a facade for the make_schema function which implements - * a short-cut for the compiler which reduces the excessive resource - * consumption of the actual implementation. - */ - -#pragma once - -#include // for string - -#include // for Array<> -#include // for Boolean -#include // for FromConfable -#include // for Const<> -#include // for Duration<> -#include // for Enum<> -#include // for Ignore -#include // for Interface, Box -#include // for FromJson<> -#include // for Map<> -#include // for Number<> -#include // for Optional<> -#include // for Passthru -#include // for Path -#include // for String -#include // for Struct -#include // for Variant - -// It is important that this include comes after all the other ones, -// so that it has access to ALL the previous definitions. -#include // for make_prototype, ... - -namespace fable::schema { -namespace details { - -/** - * Implements the make_schema function for one datatype - */ -template -struct make_schema_wrapper1 { - static auto make_schema(T* ptr, std::string&& desc) { - return ::fable::schema::make_schema_impl(ptr, std::move(desc)); - } -}; - -/** - */ -template -struct make_schema_wrapper2 { - static auto make_schema(T* ptr, P proto, std::string&& desc) { - return ::fable::schema::make_schema_impl(ptr, std::move(proto), std::move(desc)); - } -}; - -} // namespace details - -/** - * Returns the schema for a given datum and its description - * - * \param ptr Pointer to the datum - * \param desc Textual description of the datum - * \return Schema for the datum - */ -template -auto make_schema(T* ptr, std::string&& desc) { - return details::make_schema_wrapper1::make_schema(ptr, std::move(desc)); -} - -/** - * Returns the schema for a given datum and its description - * - * \param ptr Pointer to the datum - * \param proto Prototype of the data-value - * \param desc Textual description of the datum - * \return Schema for the datum - * \note Those types which have a prototype, namely string & path - * do not matter for the compile-time reduction - */ -template -auto make_schema(T* ptr, P proto, std::string&& desc) { - return details::make_schema_wrapper2::make_schema(ptr, std::move(proto), std::move(desc)); -} - -// Pre-Instantiate above templates for relevant datatypes - -#define FABLE_TYPES() \ - FABLE_TYPES_X(bool) \ - FABLE_TYPES_X(int8_t) \ - FABLE_TYPES_X(uint8_t) \ - FABLE_TYPES_X(int16_t) \ - FABLE_TYPES_X(uint16_t) \ - FABLE_TYPES_X(int32_t) \ - FABLE_TYPES_X(uint32_t) \ - FABLE_TYPES_X(int64_t) \ - FABLE_TYPES_X(uint64_t) \ - FABLE_TYPES_X(float) \ - FABLE_TYPES_X(double) - -#define FABLE_TYPES_X(TYPE) \ - extern template struct ::fable::schema::details::make_schema_wrapper1; - -FABLE_TYPES() - -} // namespace fable::schema diff --git a/fable/include/fable/schema.hpp b/fable/include/fable/schema.hpp index 49c6b680d..44ea867da 100644 --- a/fable/include/fable/schema.hpp +++ b/fable/include/fable/schema.hpp @@ -122,7 +122,27 @@ #include // for move #include // for vector<> -#include // for make_schema +#include // for Array<> +#include // for Boolean +#include // for FromConfable +#include // for Const<> +#include // for Duration<> +#include // for Enum<> +#include // for Ignore +#include // for Interface, Box +#include // for FromJson<> +#include // for Map<> +#include // for Number<> +#include // for Optional<> +#include // for Passthru +#include // for Path +#include // for String +#include // for Struct +#include // for Variant + +// It is important that this include comes after all the other ones, +// so that it has access to ALL the previous definitions. +#include // for make_prototype, ... namespace fable { @@ -131,7 +151,6 @@ using schema::make_const_schema; using schema::make_const_str; using schema::make_prototype; using schema::make_schema; -using schema::make_schema_impl; /** * Define the automatically deduced schema class of a given type. diff --git a/fable/include/fable/schema/array.hpp b/fable/include/fable/schema/array.hpp index 370686f09..c6a4e6621 100644 --- a/fable/include/fable/schema/array.hpp +++ b/fable/include/fable/schema/array.hpp @@ -173,9 +173,9 @@ class Array : public Base> { Type* ptr_{nullptr}; }; -template -Array make_schema_impl(std::vector* ptr, P&& prototype, std::string&& desc) { - return Array(ptr, std::forward

(prototype), std::move(desc)); +template +Array make_schema(std::vector* ptr, P&& prototype, S&& desc) { + return Array(ptr, std::forward

(prototype), std::forward(desc)); } } // namespace schema diff --git a/fable/include/fable/schema/boolean.hpp b/fable/include/fable/schema/boolean.hpp index 1756d7f62..c07a90eec 100644 --- a/fable/include/fable/schema/boolean.hpp +++ b/fable/include/fable/schema/boolean.hpp @@ -51,7 +51,8 @@ class Boolean : public Base { Type* ptr_{nullptr}; }; -inline Boolean make_schema_impl(bool* ptr, std::string&& desc) { return Boolean(ptr, std::move(desc)); } +template +inline Boolean make_schema(bool* ptr, S&& desc) { return Boolean(ptr, std::forward(desc)); } } // namespace schema } // namespace fable diff --git a/fable/include/fable/schema/confable.hpp b/fable/include/fable/schema/confable.hpp index 1bf846d52..c82f361d0 100644 --- a/fable/include/fable/schema/confable.hpp +++ b/fable/include/fable/schema/confable.hpp @@ -103,10 +103,10 @@ class FromConfable : public Base> { Type* ptr_{nullptr}; }; -template -FromConfable make_schema_impl(T* ptr, std::string&& desc) { +template +FromConfable make_schema(T* ptr, S&& desc) { assert(ptr != nullptr); - return FromConfable(ptr, std::move(desc)); + return FromConfable(ptr, std::forward(desc)); } } // namespace schema diff --git a/fable/include/fable/schema/const.hpp b/fable/include/fable/schema/const.hpp index 666e0dcd7..54b1ddd65 100644 --- a/fable/include/fable/schema/const.hpp +++ b/fable/include/fable/schema/const.hpp @@ -88,17 +88,14 @@ class Const : public Base> { const Type constant_; }; -template -Const make_const_schema(const T& constant, P&& prototype, std::string&& desc) { - return Const(constant, std::forward

(prototype), std::move(desc)); -} - -inline Const make_const_str(const std::string& constant, std::string&& desc) { - return Const(constant, std::move(desc)); +template +Const make_const_schema(const T& constant, P&& prototype, S&& desc) { + return Const(constant, std::forward

(prototype), std::forward(desc)); } -inline Const make_const_str(const char* constant, std::string&& desc) { - return Const(constant, std::move(desc)); +template +inline Const make_const_str(S1&& constant, S2&& desc) { + return Const(std::forward(constant), std::forward(desc)); } } // namespace schema diff --git a/fable/include/fable/schema/duration.hpp b/fable/include/fable/schema/duration.hpp index a7acc0c6a..8dc14270e 100644 --- a/fable/include/fable/schema/duration.hpp +++ b/fable/include/fable/schema/duration.hpp @@ -186,10 +186,9 @@ class Duration : public Base> { Type* ptr_{nullptr}; }; -template -inline Duration make_schema_impl(std::chrono::duration* ptr, - std::string&& desc) { - return Duration(ptr, std::move(desc)); +template +inline Duration make_schema(std::chrono::duration* ptr, S&& desc) { + return Duration(ptr, std::forward(desc)); } } // namespace schema diff --git a/fable/include/fable/schema/enum.hpp b/fable/include/fable/schema/enum.hpp index 6eb11ea7c..14691c6fc 100644 --- a/fable/include/fable/schema/enum.hpp +++ b/fable/include/fable/schema/enum.hpp @@ -102,9 +102,9 @@ class Enum : public Base> { Type* ptr_{nullptr}; }; -template ::value, int> = 0> -inline Enum make_schema_impl(T* ptr, std::string&& desc) { - return Enum(ptr, std::move(desc)); +template , int> = 0> +inline Enum make_schema(T* ptr, S&& desc) { + return Enum(ptr, std::forward(desc)); } } // namespace schema diff --git a/fable/include/fable/schema/interface.hpp b/fable/include/fable/schema/interface.hpp index 0de49db10..3997d30b8 100644 --- a/fable/include/fable/schema/interface.hpp +++ b/fable/include/fable/schema/interface.hpp @@ -457,11 +457,11 @@ using enable_if_confable_t = std::enable_if_t::valu template using enable_if_not_confable_t = std::enable_if_t::value>; -template ::value, int> = 0> -auto make_prototype(std::string&& desc = ""); +template , int> = 0> +auto make_prototype(S&& desc = ""); -template ::value, int> = 0> -auto make_prototype(std::string&& desc = ""); +template , int> = 0> +auto make_prototype(S&& desc = ""); } // namespace schema } // namespace fable diff --git a/fable/include/fable/schema/magic.hpp b/fable/include/fable/schema/magic.hpp index a5ef24fe3..d2a1c5b5b 100644 --- a/fable/include/fable/schema/magic.hpp +++ b/fable/include/fable/schema/magic.hpp @@ -21,10 +21,10 @@ * \see fable/schema_test.cpp * * This file defines the `make_prototype` functions that can automatically - * derive the prototype via the `make_schema_impl` functions. It also contains the + * derive the prototype via the `make_schema` functions. It also contains the * definitions of constructors that make use of these functions. * - * Unfortunately, all `make_schema_impl` functions need to already be defined at the + * Unfortunately, all `make_schema` functions need to already be defined at the * point of definition of these constructors, which is why they have to be in * this file in the first place. * @@ -57,48 +57,47 @@ template Array::Array(std::vector* ptr, std::string&& desc) : Array(ptr, make_prototype(), std::move(desc)) {} -template -Array())> make_schema_impl(std::vector* ptr, std::string&& desc) { - return Array())>(ptr, std::move(desc)); +template +Array())> make_schema(std::vector* ptr, S&& desc) { + return Array())>(ptr, std::forward(desc)); } template Const::Const(const T& constant, std::string&& desc) : Const(constant, make_prototype(), std::move(desc)) {} -template -Const())> make_const_schema(const T& constant, std::string&& desc) { - return Const())>(constant, std::move(desc)); +template +Const())> make_const_schema(const T& constant, S&& desc) { + return Const())>(constant, std::forward(desc)); } template Map::Map(std::map* ptr, std::string&& desc) : Map(ptr, make_prototype(), std::move(desc)) {} -template -Map())> make_schema_impl(std::map* ptr, - std::string&& desc) { - return Map())>(ptr, std::move(desc)); +template +Map())> make_schema(std::map* ptr, + S&& desc) { + return Map())>(ptr, std::forward(desc)); } template Optional::Optional(boost::optional* ptr, std::string&& desc) : Optional(ptr, make_prototype(), std::move(desc)) {} -template -Optional())> make_schema_impl(boost::optional* ptr, - std::string&& desc) { - return Optional())>(ptr, std::move(desc)); +template +Optional())> make_schema(boost::optional* ptr, S&& desc) { + return Optional())>(ptr, std::forward(desc)); } -template ::value, int>> -auto make_prototype(std::string&& desc) { - return FromConfable(std::move(desc)); +template , int>> +auto make_prototype(S&& desc) { + return FromConfable(std::forward(desc)); } -template ::value, int>> -auto make_prototype(std::string&& desc) { - return make_schema_impl(static_cast(nullptr), std::move(desc)); +template , int>> +auto make_prototype(S&& desc) { + return make_schema(static_cast(nullptr), std::forward(desc)); } } // namespace schema diff --git a/fable/include/fable/schema/map.hpp b/fable/include/fable/schema/map.hpp index 127722560..cc7fbfd6e 100644 --- a/fable/include/fable/schema/map.hpp +++ b/fable/include/fable/schema/map.hpp @@ -188,9 +188,9 @@ class Map : public Base> { Type* ptr_{nullptr}; }; -template -Map make_schema_impl(std::map* ptr, P&& prototype, std::string&& desc) { - return Map(ptr, std::forward

(prototype), std::move(desc)); +template +Map make_schema(std::map* ptr, P&& prototype, S&& desc) { + return Map(ptr, std::forward

(prototype), std::forward(desc)); } } // namespace schema diff --git a/fable/include/fable/schema/number.hpp b/fable/include/fable/schema/number.hpp index 068a50bce..e69ef0e40 100644 --- a/fable/include/fable/schema/number.hpp +++ b/fable/include/fable/schema/number.hpp @@ -102,10 +102,9 @@ class Number : public Base> { Type* ptr_{nullptr}; }; -template ::value && !std::is_enum::value, int> = 0> -inline Number make_schema_impl(T* ptr, std::string&& desc) { - return Number(ptr, std::move(desc)); +template && !std::is_enum_v, int> = 0> +inline Number make_schema(T* ptr, S&& desc) { + return Number(ptr, std::forward(desc)); } } // namespace schema diff --git a/fable/include/fable/schema/optional.hpp b/fable/include/fable/schema/optional.hpp index fa111e4b4..62198c708 100644 --- a/fable/include/fable/schema/optional.hpp +++ b/fable/include/fable/schema/optional.hpp @@ -112,9 +112,9 @@ class Optional : public Base> { Type* ptr_{nullptr}; }; -template -Optional make_schema_impl(boost::optional* ptr, P&& prototype, std::string&& desc) { - return Optional(ptr, std::forward

(prototype), std::move(desc)); +template +Optional make_schema(boost::optional* ptr, P&& prototype, S&& desc) { + return Optional(ptr, std::forward

(prototype), std::forward(desc)); } } // namespace schema diff --git a/fable/include/fable/schema/passthru.hpp b/fable/include/fable/schema/passthru.hpp index d514b8066..fcdeff1fb 100644 --- a/fable/include/fable/schema/passthru.hpp +++ b/fable/include/fable/schema/passthru.hpp @@ -92,13 +92,14 @@ class Passthru : public Base> { Type* ptr_{nullptr}; }; -inline Passthru make_schema_impl(Conf* ptr, std::string&& desc) { - return Passthru(ptr, Ignore(), std::move(desc)); +template +inline Passthru make_schema(Conf* ptr, S&& desc) { + return Passthru(ptr, Ignore(), std::forward(desc)); } -template -Passthru

make_schema_impl(Conf* ptr, P&& prototype, std::string&& desc) { - return Passthru

(ptr, std::forward

(prototype), std::move(desc)); +template +Passthru

make_schema(Conf* ptr, P&& prototype, S&& desc) { + return Passthru

(ptr, std::forward

(prototype), std::forward(desc)); } } // namespace schema diff --git a/fable/include/fable/schema/path.hpp b/fable/include/fable/schema/path.hpp index abbbcf76a..b89996a12 100644 --- a/fable/include/fable/schema/path.hpp +++ b/fable/include/fable/schema/path.hpp @@ -213,8 +213,9 @@ class Path : public Base { Type* ptr_{nullptr}; }; -inline Path make_schema_impl(boost::filesystem::path* ptr, std::string&& desc) { - return Path(ptr, std::move(desc)); +template +inline Path make_schema(boost::filesystem::path* ptr, S&& desc) { + return Path(ptr, std::forward(desc)); } } // namespace schema diff --git a/fable/include/fable/schema/string.hpp b/fable/include/fable/schema/string.hpp index 54bea643e..49f9073f9 100644 --- a/fable/include/fable/schema/string.hpp +++ b/fable/include/fable/schema/string.hpp @@ -261,8 +261,9 @@ class String : public Base { Type* ptr_{nullptr}; }; -inline String make_schema_impl(std::string* ptr, std::string&& desc) { - return String(ptr, std::move(desc)); +template +inline String make_schema(std::string* ptr, S&& desc) { + return String(ptr, std::forward(desc)); } } // namespace schema diff --git a/fable/src/fable/make_schema.cpp b/fable/src/fable/make_schema.cpp deleted file mode 100644 index ae53778e1..000000000 --- a/fable/src/fable/make_schema.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2023 Robert Bosch GmbH - * - * 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. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -namespace fable::schema { - -#define extern -FABLE_TYPES() -#undef extern - -} From 2f320abe034850e90b7ba52761a3ee3f836a3338 Mon Sep 17 00:00:00 2001 From: Benjamin Morgan Date: Tue, 20 Feb 2024 12:46:34 +0100 Subject: [PATCH 6/7] fable: Use C++17 type traits with _t and _v suffixes --- fable/include/fable/enum.hpp | 8 ++++---- fable/include/fable/schema.hpp | 2 +- fable/include/fable/schema/confable.hpp | 2 +- fable/include/fable/schema/duration.hpp | 10 ++++------ fable/include/fable/schema/factory.hpp | 4 ++-- fable/include/fable/schema/interface.hpp | 6 +++--- fable/include/fable/schema/number.hpp | 6 +++--- fable/include/fable/schema/struct.hpp | 2 +- 8 files changed, 19 insertions(+), 21 deletions(-) diff --git a/fable/include/fable/enum.hpp b/fable/include/fable/enum.hpp index 60d55ff60..31a77c0d2 100644 --- a/fable/include/fable/enum.hpp +++ b/fable/include/fable/enum.hpp @@ -149,22 +149,22 @@ struct EnumSerializerImpl { } }; -template ::value, int> = 0> +template , int> = 0> const std::map& enum_serialization() { return EnumSerializerImpl::value>::serialization_impl(); } -template ::value, int> = 0> +template , int> = 0> const std::map& enum_deserialization() { return EnumSerializerImpl::value>::deserialization_impl(); } -template ::value, int> = 0> +template , int> = 0> std::string to_string(T x) { return enum_serialization().at(x); } -template ::value, int> = 0> +template , int> = 0> T from_string(const std::string& s) { return enum_deserialization().at(s); } diff --git a/fable/include/fable/schema.hpp b/fable/include/fable/schema.hpp index 44ea867da..65df0c306 100644 --- a/fable/include/fable/schema.hpp +++ b/fable/include/fable/schema.hpp @@ -200,7 +200,7 @@ class Schema : public schema::Interface { Schema(std::string&& desc, schema::BoxVec&& props); // Interface - template ::value, int> = 0> + template , int> = 0> Schema(const T& value) : impl_(value.clone()) {} // NOLINT(runtime/explicit) Schema(schema::Interface* i) : impl_(i) { assert(impl_); } // NOLINT(runtime/explicit) Schema(std::shared_ptr i) : impl_(std::move(i)) { // NOLINT(runtime/explicit) diff --git a/fable/include/fable/schema/confable.hpp b/fable/include/fable/schema/confable.hpp index c82f361d0..6a2f0cb1c 100644 --- a/fable/include/fable/schema/confable.hpp +++ b/fable/include/fable/schema/confable.hpp @@ -37,7 +37,7 @@ class Confable; namespace schema { -template ::value, int> = 0> +template , int> = 0> class FromConfable : public Base> { public: // Types and Constructors using Type = T; diff --git a/fable/include/fable/schema/duration.hpp b/fable/include/fable/schema/duration.hpp index 8dc14270e..eb0019261 100644 --- a/fable/include/fable/schema/duration.hpp +++ b/fable/include/fable/schema/duration.hpp @@ -39,17 +39,15 @@ class Duration : public Base> { public: // Types and Constructors using Type = std::chrono::duration; - template ::value && std::is_unsigned::value, int> = 0> + template && std::is_unsigned_v, int> = 0> Duration(Type* ptr, std::string&& desc) : Base>(JsonType::number_unsigned, std::move(desc)), ptr_(ptr) {} - template ::value && std::is_signed::value, int> = 0> + template && std::is_signed_v, int> = 0> Duration(Type* ptr, std::string&& desc) - : Base>(JsonType::number_integer, std::move(desc)), ptr_(ptr) {} + : Base>(JsonType::number_integer, std::move(desc)), ptr_(ptr) {} - template ::value, int> = 0> + template , int> = 0> Duration(Type* ptr, std::string&& desc) : Base>(JsonType::number_float, std::move(desc)), ptr_(ptr) {} diff --git a/fable/include/fable/schema/factory.hpp b/fable/include/fable/schema/factory.hpp index a7bf036da..5fc351040 100644 --- a/fable/include/fable/schema/factory.hpp +++ b/fable/include/fable/schema/factory.hpp @@ -229,8 +229,8 @@ class FactoryBase : public Base { * Most types inheriting from `Confable` will fulfill these requirements. */ template ::value && - std::is_convertible, T>::value), + std::enable_if_t<(std::is_default_constructible_v && + std::is_convertible_v, T>), int> = 0> void add_default_factory(const std::string& key) { add_factory(key, make_prototype().get_confable_schema(), [](const Conf& c) -> T { diff --git a/fable/include/fable/schema/interface.hpp b/fable/include/fable/schema/interface.hpp index 3997d30b8..7d3c7b861 100644 --- a/fable/include/fable/schema/interface.hpp +++ b/fable/include/fable/schema/interface.hpp @@ -254,7 +254,7 @@ class Interface { * void foobar(S schema); */ template -using enable_if_schema_t = std::enable_if_t::value>; +using enable_if_schema_t = std::enable_if_t>; // ------------------------------------------------------------------------- // @@ -444,7 +444,7 @@ class Base : public Interface { * void foobar(T x); */ template -using enable_if_confable_t = std::enable_if_t::value>; +using enable_if_confable_t = std::enable_if_t>; /** * Use SFINAE mechanism to disable a template function when S is a subclass @@ -455,7 +455,7 @@ using enable_if_confable_t = std::enable_if_t::valu * void foobar(T x); */ template -using enable_if_not_confable_t = std::enable_if_t::value>; +using enable_if_not_confable_t = std::enable_if_t>; template , int> = 0> auto make_prototype(S&& desc = ""); diff --git a/fable/include/fable/schema/number.hpp b/fable/include/fable/schema/number.hpp index e69ef0e40..72f2a02f3 100644 --- a/fable/include/fable/schema/number.hpp +++ b/fable/include/fable/schema/number.hpp @@ -40,15 +40,15 @@ class Number : public Base> { public: // Types and Constructors using Type = T; - template ::value && std::is_unsigned::value, int> = 0> + template && std::is_unsigned_v, int> = 0> Number(Type* ptr, std::string&& desc) : Base>(JsonType::number_unsigned, std::move(desc)), ptr_(ptr) {} - template ::value && std::is_signed::value, int> = 0> + template && std::is_signed_v, int> = 0> Number(Type* ptr, std::string&& desc) : Base>(JsonType::number_integer, std::move(desc)), ptr_(ptr) {} - template ::value, int> = 0> + template , int> = 0> Number(Type* ptr, std::string&& desc) : Base>(JsonType::number_float, std::move(desc)), ptr_(ptr) {} diff --git a/fable/include/fable/schema/struct.hpp b/fable/include/fable/schema/struct.hpp index dae7f046a..04eececbe 100644 --- a/fable/include/fable/schema/struct.hpp +++ b/fable/include/fable/schema/struct.hpp @@ -55,7 +55,7 @@ template using PropertyList = std::initializer_list>; template -using enable_if_property_list_t = std::enable_if_t, T>::value>; +using enable_if_property_list_t = std::enable_if_t, T>>; /** * Struct maintains a key-value mapping, where the list of keys is usually From ce7d504ce925f6263d3665abe1f956a75bac9c56 Mon Sep 17 00:00:00 2001 From: Benjamin Morgan Date: Tue, 20 Feb 2024 12:47:03 +0100 Subject: [PATCH 7/7] fable: Use std::string instead of std::string&& for constructors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is the optimal form, according to an analysis by Nicolai Josuttis in a CppCon18 talk: Nicolai Josuttis “The Nightmare of Initialization in C++” https://www.youtube.com/watch?v=7DTlWPgX6zs --- fable/include/fable/schema.hpp | 20 +++++++++---------- fable/include/fable/schema/array.hpp | 6 +++--- fable/include/fable/schema/boolean.hpp | 2 +- fable/include/fable/schema/confable.hpp | 6 +++--- fable/include/fable/schema/const.hpp | 6 +++--- fable/include/fable/schema/duration.hpp | 8 ++++---- fable/include/fable/schema/enum.hpp | 2 +- fable/include/fable/schema/factory.hpp | 12 +++++------ fable/include/fable/schema/ignore.hpp | 2 +- fable/include/fable/schema/interface.hpp | 6 +++--- fable/include/fable/schema/json.hpp | 2 +- fable/include/fable/schema/magic.hpp | 8 ++++---- fable/include/fable/schema/map.hpp | 6 +++--- fable/include/fable/schema/number.hpp | 6 +++--- fable/include/fable/schema/optional.hpp | 6 +++--- fable/include/fable/schema/passthru.hpp | 4 ++-- fable/include/fable/schema/path.hpp | 2 +- fable/include/fable/schema/string.hpp | 2 +- fable/include/fable/schema/struct.hpp | 6 +++--- fable/include/fable/schema/variant.hpp | 6 +++--- fable/src/fable/schema.cpp | 6 +++--- fable/src/fable/schema/boolean.cpp | 2 +- .../fable/schema/factory_advanced_test.cpp | 2 +- fable/src/fable/schema/variant.cpp | 2 +- 24 files changed, 64 insertions(+), 66 deletions(-) diff --git a/fable/include/fable/schema.hpp b/fable/include/fable/schema.hpp index 65df0c306..6a5005c64 100644 --- a/fable/include/fable/schema.hpp +++ b/fable/include/fable/schema.hpp @@ -114,8 +114,6 @@ #pragma once -#include // for duration<> -#include // for map<> #include // for shared_ptr<> #include // for string #include // for enable_if_t<>, is_arithmetic<>, is_enum<>, ... @@ -179,25 +177,25 @@ class Schema : public schema::Interface { Schema& operator=(const Schema&) = default; // Struct - Schema(std::string&& desc, schema::PropertyList<> props) + Schema(std::string desc, schema::PropertyList<> props) : impl_(new schema::Struct(std::move(desc), props)) {} Schema(schema::PropertyList<> props) : Schema("", props) {} - Schema(std::string&& desc, const Schema& base, schema::PropertyList<> props) + Schema(std::string desc, const Schema& base, schema::PropertyList<> props) : impl_(new schema::Struct(std::move(desc), base, props)) {} Schema(const Schema& base, schema::PropertyList<> props) : Schema("", base, props) {} // Variant Schema(const std::vector& xs); // NOLINT(runtime/explicit) - Schema(std::string&& desc, const std::vector& xs); + Schema(std::string desc, const std::vector& xs); Schema(schema::BoxList props); // NOLINT(runtime/explicit) - Schema(std::string&& desc, schema::BoxList props); + Schema(std::string desc, schema::BoxList props); Schema(schema::BoxVec&& props); // NOLINT(runtime/explicit) - Schema(std::string&& desc, schema::BoxVec&& props); + Schema(std::string desc, schema::BoxVec&& props); // Interface template , int> = 0> @@ -209,19 +207,19 @@ class Schema : public schema::Interface { // Ignore Schema() : impl_(new schema::Ignore("")) {} - explicit Schema(std::string&& desc, JsonType t = JsonType::object) + explicit Schema(std::string desc, JsonType t = JsonType::object) : impl_(new schema::Ignore(std::move(desc), t)) {} // Primitives template - Schema(T* ptr, std::string&& desc) : impl_(make_schema(ptr, std::move(desc)).clone()) {} + Schema(T* ptr, std::string desc) : impl_(make_schema(ptr, std::move(desc)).clone()) {} template - Schema(T* ptr, const schema::Box& prototype, std::string&& desc) + Schema(T* ptr, const schema::Box& prototype, std::string desc) : impl_(make_schema(ptr, prototype, std::move(desc)).clone()) {} // FromJson template - Schema(T* ptr, JsonType t, std::string&& desc) + Schema(T* ptr, JsonType t, std::string desc) : impl_(new schema::FromJson(ptr, t, std::move(desc))) {} public: // Special diff --git a/fable/include/fable/schema/array.hpp b/fable/include/fable/schema/array.hpp index c6a4e6621..c59d71604 100644 --- a/fable/include/fable/schema/array.hpp +++ b/fable/include/fable/schema/array.hpp @@ -42,15 +42,15 @@ class Array : public Base> { using Type = std::vector; using PrototypeSchema = std::remove_cv_t>; - Array(Type* ptr, std::string&& desc); + Array(Type* ptr, std::string desc); Array(Type* ptr, PrototypeSchema prototype) : Base>(JsonType::array), prototype_(std::move(prototype)), ptr_(ptr) {} - Array(Type* ptr, PrototypeSchema prototype, std::string&& desc) + Array(Type* ptr, PrototypeSchema prototype, std::string desc) : Base>(JsonType::array, std::move(desc)), prototype_(std::move(prototype)), ptr_(ptr) {} #if 0 // This is defined in: fable/schema/magic.hpp - Array(Type* ptr, std::string&& desc) + Array(Type* ptr, std::string desc) : Array(ptr, make_prototype(), std::move(desc)) {} #endif diff --git a/fable/include/fable/schema/boolean.hpp b/fable/include/fable/schema/boolean.hpp index c07a90eec..4c4b840f7 100644 --- a/fable/include/fable/schema/boolean.hpp +++ b/fable/include/fable/schema/boolean.hpp @@ -35,7 +35,7 @@ class Boolean : public Base { public: // Types and Constructors using Type = bool; - Boolean(Type* ptr, std::string&& desc); + Boolean(Type* ptr, std::string desc); public: // Overrides Json json_schema() const override; diff --git a/fable/include/fable/schema/confable.hpp b/fable/include/fable/schema/confable.hpp index 6a2f0cb1c..66a4da2d6 100644 --- a/fable/include/fable/schema/confable.hpp +++ b/fable/include/fable/schema/confable.hpp @@ -42,14 +42,14 @@ class FromConfable : public Base> { public: // Types and Constructors using Type = T; - explicit FromConfable(std::string&& desc = "") { - schema_ = Type().schema(); + FromConfable(std::string desc = "") { + schema_ = Type().schema(); // NOLINT schema_.reset_ptr(); this->type_ = schema_.type(); this->desc_ = std::move(desc); } - FromConfable(Type* ptr, std::string&& desc) + FromConfable(Type* ptr, std::string desc) : Base>(ptr->schema().type(), std::move(desc)) , schema_(ptr->schema()) , ptr_(ptr) { diff --git a/fable/include/fable/schema/const.hpp b/fable/include/fable/schema/const.hpp index 54b1ddd65..8836f7f7a 100644 --- a/fable/include/fable/schema/const.hpp +++ b/fable/include/fable/schema/const.hpp @@ -39,8 +39,8 @@ class Const : public Base> { using Type = T; using PrototypeSchema = std::remove_cv_t>; - Const(const Type& constant, std::string&& desc); - Const(const Type& constant, PrototypeSchema prototype, std::string&& desc) + Const(const Type& constant, std::string desc); + Const(const Type& constant, PrototypeSchema prototype, std::string desc) : Base>(prototype.type(), std::move(desc)) , prototype_(std::move(prototype)) , constant_(constant) { @@ -49,7 +49,7 @@ class Const : public Base> { #if 0 // This is defined in: fable/schema/magic.hpp - Const(const T& constant, std::string&& desc) + Const(const T& constant, std::string desc) : Const(constant, make_prototype(), std::move(desc)) {} #endif diff --git a/fable/include/fable/schema/duration.hpp b/fable/include/fable/schema/duration.hpp index eb0019261..791524339 100644 --- a/fable/include/fable/schema/duration.hpp +++ b/fable/include/fable/schema/duration.hpp @@ -40,15 +40,15 @@ class Duration : public Base> { using Type = std::chrono::duration; template && std::is_unsigned_v, int> = 0> - Duration(Type* ptr, std::string&& desc) + Duration(Type* ptr, std::string desc) : Base>(JsonType::number_unsigned, std::move(desc)), ptr_(ptr) {} template && std::is_signed_v, int> = 0> - Duration(Type* ptr, std::string&& desc) - : Base>(JsonType::number_integer, std::move(desc)), ptr_(ptr) {} + Duration(Type* ptr, std::string desc) + : Base>(JsonType::number_integer, std::move(desc)), ptr_(ptr) {} template , int> = 0> - Duration(Type* ptr, std::string&& desc) + Duration(Type* ptr, std::string desc) : Base>(JsonType::number_float, std::move(desc)), ptr_(ptr) {} public: // Special diff --git a/fable/include/fable/schema/enum.hpp b/fable/include/fable/schema/enum.hpp index 14691c6fc..5695ca7b8 100644 --- a/fable/include/fable/schema/enum.hpp +++ b/fable/include/fable/schema/enum.hpp @@ -40,7 +40,7 @@ class Enum : public Base> { public: // Types and Constructors using Type = T; - Enum(Type* ptr, std::string&& desc) + Enum(Type* ptr, std::string desc) : Base>(JsonType::string, std::move(desc)) , mapping_to_(enum_serialization()) , mapping_from_(enum_deserialization()) diff --git a/fable/include/fable/schema/factory.hpp b/fable/include/fable/schema/factory.hpp index 5fc351040..de3395e7a 100644 --- a/fable/include/fable/schema/factory.hpp +++ b/fable/include/fable/schema/factory.hpp @@ -78,14 +78,14 @@ class FactoryBase : public Base { * * \see add_factory() */ - explicit FactoryBase(std::string&& desc = "") : Base(JsonType::object, std::move(desc)) {} + explicit FactoryBase(std::string desc = "") : Base(JsonType::object, std::move(desc)) {} - FactoryBase(std::string&& desc, FactoryPairList fs) + FactoryBase(std::string desc, FactoryPairList fs) : Base(JsonType::object, std::move(desc)), available_(std::move(fs)) { reset_schema(); } - FactoryBase(std::string&& desc, FactoryMap&& fs) + FactoryBase(std::string desc, FactoryMap&& fs) : Base(JsonType::object, std::move(desc)), available_(std::move(fs)) { reset_schema(); } @@ -381,9 +381,9 @@ class Factory : public FactoryBase> { public: // Constructors using FactoryBase>::FactoryBase; - Factory(Type* ptr, std::string&& desc) : FactoryBase>(std::move(desc)), ptr_(ptr) {} + Factory(Type* ptr, std::string desc) : FactoryBase>(std::move(desc)), ptr_(ptr) {} - Factory(Type* ptr, std::string&& desc, FactoryMap&& fs) + Factory(Type* ptr, std::string desc, FactoryMap&& fs) : FactoryBase>(std::move(desc)), ptr_(ptr) { for (auto&& f : fs) { this->available_.insert(f); @@ -391,7 +391,7 @@ class Factory : public FactoryBase> { this->reset_schema(); } - Factory(Type* ptr, std::string&& desc, FactoryPairList fs) + Factory(Type* ptr, std::string desc, FactoryPairList fs) : FactoryBase>(std::move(desc)), ptr_(ptr) { for (auto&& f : fs) { this->available_.insert(f); diff --git a/fable/include/fable/schema/ignore.hpp b/fable/include/fable/schema/ignore.hpp index b62c1c48b..5021518ca 100644 --- a/fable/include/fable/schema/ignore.hpp +++ b/fable/include/fable/schema/ignore.hpp @@ -44,7 +44,7 @@ namespace schema { class Ignore : public Base { public: // Constructors Ignore() : Base(JsonType::object, "ignored") {} - explicit Ignore(std::string&& desc, JsonType t = JsonType::object) : Base(t, std::move(desc)) {} + explicit Ignore(std::string desc, JsonType t = JsonType::object) : Base(t, std::move(desc)) {} public: // Overrides Json json_schema() const override { diff --git a/fable/include/fable/schema/interface.hpp b/fable/include/fable/schema/interface.hpp index 7d3c7b861..4d0bd6cff 100644 --- a/fable/include/fable/schema/interface.hpp +++ b/fable/include/fable/schema/interface.hpp @@ -352,9 +352,9 @@ template class Base : public Interface { public: Base() = default; - Base(JsonType t, std::string&& desc) : type_(t), desc_(std::move(desc)) {} + Base(JsonType t, std::string desc) : type_(t), desc_(std::move(desc)) {} explicit Base(JsonType t) : type_(t) {} - explicit Base(std::string&& desc) : desc_(std::move(desc)) {} + explicit Base(std::string desc) : desc_(std::move(desc)) {} virtual ~Base() = default; Interface* clone() const override { return new CRTP(static_cast(*this)); } @@ -391,7 +391,7 @@ class Base : public Interface { void set_description(const std::string& s) override { desc_ = s; } void set_description(std::string&& s) { desc_ = std::move(s); } const std::string& description() const override { return desc_; } - CRTP description(std::string&& desc) && { + CRTP description(std::string desc) && { desc_ = std::move(desc); return std::move(*dynamic_cast(this)); } diff --git a/fable/include/fable/schema/json.hpp b/fable/include/fable/schema/json.hpp index 883f9fb5d..fb7305eb1 100644 --- a/fable/include/fable/schema/json.hpp +++ b/fable/include/fable/schema/json.hpp @@ -48,7 +48,7 @@ class FromJson : public Base> { public: // Types and Constructors using Type = T; - FromJson(Type* ptr, JsonType t, std::string&& desc) + FromJson(Type* ptr, JsonType t, std::string desc) : Base>(t, std::move(desc)), ptr_(ptr) {} public: // Overrides diff --git a/fable/include/fable/schema/magic.hpp b/fable/include/fable/schema/magic.hpp index d2a1c5b5b..449d04aa5 100644 --- a/fable/include/fable/schema/magic.hpp +++ b/fable/include/fable/schema/magic.hpp @@ -54,7 +54,7 @@ class Confable; namespace schema { template -Array::Array(std::vector* ptr, std::string&& desc) +Array::Array(std::vector* ptr, std::string desc) : Array(ptr, make_prototype(), std::move(desc)) {} template @@ -63,7 +63,7 @@ Array())> make_schema(std::vector* ptr, S&& des } template -Const::Const(const T& constant, std::string&& desc) +Const::Const(const T& constant, std::string desc) : Const(constant, make_prototype(), std::move(desc)) {} template @@ -72,7 +72,7 @@ Const())> make_const_schema(const T& constant, S&& } template -Map::Map(std::map* ptr, std::string&& desc) +Map::Map(std::map* ptr, std::string desc) : Map(ptr, make_prototype(), std::move(desc)) {} template @@ -82,7 +82,7 @@ Map())> make_schema(std::map* ptr, } template -Optional::Optional(boost::optional* ptr, std::string&& desc) +Optional::Optional(boost::optional* ptr, std::string desc) : Optional(ptr, make_prototype(), std::move(desc)) {} template diff --git a/fable/include/fable/schema/map.hpp b/fable/include/fable/schema/map.hpp index cc7fbfd6e..08c8d6363 100644 --- a/fable/include/fable/schema/map.hpp +++ b/fable/include/fable/schema/map.hpp @@ -52,19 +52,19 @@ class Map : public Base> { using Type = std::map; using PrototypeSchema = std::remove_cv_t>; - Map(Type* ptr, std::string&& desc); + Map(Type* ptr, std::string desc); Map(Type* ptr, PrototypeSchema prototype) : Base>(JsonType::object), prototype_(std::move(prototype)), ptr_(ptr) { prototype_.reset_ptr(); } - Map(Type* ptr, PrototypeSchema prototype, std::string&& desc) + Map(Type* ptr, PrototypeSchema prototype, std::string desc) : Base>(JsonType::object, std::move(desc)), prototype_(std::move(prototype)), ptr_(ptr) { prototype_.reset_ptr(); } #if 0 // This is defined in: fable/schema/magic.hpp - Map(Type* ptr, std::string&& desc) + Map(Type* ptr, std::string desc) : Map(ptr, make_prototype(), std::move(desc)) {} #endif diff --git a/fable/include/fable/schema/number.hpp b/fable/include/fable/schema/number.hpp index 72f2a02f3..6c85fe8ee 100644 --- a/fable/include/fable/schema/number.hpp +++ b/fable/include/fable/schema/number.hpp @@ -41,15 +41,15 @@ class Number : public Base> { using Type = T; template && std::is_unsigned_v, int> = 0> - Number(Type* ptr, std::string&& desc) + Number(Type* ptr, std::string desc) : Base>(JsonType::number_unsigned, std::move(desc)), ptr_(ptr) {} template && std::is_signed_v, int> = 0> - Number(Type* ptr, std::string&& desc) + Number(Type* ptr, std::string desc) : Base>(JsonType::number_integer, std::move(desc)), ptr_(ptr) {} template , int> = 0> - Number(Type* ptr, std::string&& desc) + Number(Type* ptr, std::string desc) : Base>(JsonType::number_float, std::move(desc)), ptr_(ptr) {} diff --git a/fable/include/fable/schema/optional.hpp b/fable/include/fable/schema/optional.hpp index 62198c708..a6938ed83 100644 --- a/fable/include/fable/schema/optional.hpp +++ b/fable/include/fable/schema/optional.hpp @@ -41,15 +41,15 @@ class Optional : public Base> { using Type = boost::optional; using PrototypeSchema = std::remove_cv_t>; - Optional(Type* ptr, std::string&& desc); - Optional(Type* ptr, PrototypeSchema prototype, std::string&& desc) + Optional(Type* ptr, std::string desc); + Optional(Type* ptr, PrototypeSchema prototype, std::string desc) : Base>(prototype.type(), std::move(desc)), prototype_(std::move(prototype)), ptr_(ptr) { prototype_.reset_ptr(); } #if 0 // This is defined in: fable/schema/magic.hpp - Optional(Type* ptr, std::string&& desc) + Optional(Type* ptr, std::string desc) : Optional(ptr, make_prototype(), std::move(desc)) {} #endif diff --git a/fable/include/fable/schema/passthru.hpp b/fable/include/fable/schema/passthru.hpp index fcdeff1fb..b5427c05d 100644 --- a/fable/include/fable/schema/passthru.hpp +++ b/fable/include/fable/schema/passthru.hpp @@ -48,9 +48,9 @@ class Passthru : public Base> { using Type = Conf; using PrototypeSchema = std::remove_cv_t>; - Passthru(Type* ptr, std::string&& desc) + Passthru(Type* ptr, std::string desc) : Passthru(ptr, PrototypeSchema(nullptr, ""), std::move(desc)) {} - Passthru(Type* ptr, PrototypeSchema prototype, std::string&& desc) + Passthru(Type* ptr, PrototypeSchema prototype, std::string desc) : Base>(prototype.type(), std::move(desc)), prototype_(std::move(prototype)), ptr_(ptr) { prototype_.reset_ptr(); } diff --git a/fable/include/fable/schema/path.hpp b/fable/include/fable/schema/path.hpp index b89996a12..69e26811c 100644 --- a/fable/include/fable/schema/path.hpp +++ b/fable/include/fable/schema/path.hpp @@ -71,7 +71,7 @@ class Path : public Base { NotDir, /// path does not exist or is a file }; - Path(Type* ptr, std::string&& desc) : Base(JsonType::string, std::move(desc)), ptr_(ptr) {} + Path(Type* ptr, std::string desc) : Base(JsonType::string, std::move(desc)), ptr_(ptr) {} public: // Special /** diff --git a/fable/include/fable/schema/string.hpp b/fable/include/fable/schema/string.hpp index 49f9073f9..19a4d72f5 100644 --- a/fable/include/fable/schema/string.hpp +++ b/fable/include/fable/schema/string.hpp @@ -65,7 +65,7 @@ class String : public Base { public: // Types and Constructors using Type = std::string; - String(Type* ptr, std::string&& desc) : Base(JsonType::string, std::move(desc)), ptr_(ptr) {} + String(Type* ptr, std::string desc) : Base(JsonType::string, std::move(desc)), ptr_(ptr) {} public: // Special /** diff --git a/fable/include/fable/schema/struct.hpp b/fable/include/fable/schema/struct.hpp index 04eececbe..ad6013dec 100644 --- a/fable/include/fable/schema/struct.hpp +++ b/fable/include/fable/schema/struct.hpp @@ -70,9 +70,9 @@ using enable_if_property_list_t = std::enable_if_t { public: // Constructors - explicit Struct(std::string&& desc = "") : Base(JsonType::object, std::move(desc)) {} + explicit Struct(std::string desc = "") : Base(JsonType::object, std::move(desc)) {} - Struct(std::string&& desc, PropertyList props) : Base(JsonType::object, std::move(desc)) { + Struct(std::string desc, PropertyList props) : Base(JsonType::object, std::move(desc)) { set_properties(props); } @@ -103,7 +103,7 @@ class Struct : public Base { * will internally call this->schema_impl(), which will lead to an * infinite recursion! Instead, call Base::schema_impl(). */ - Struct(std::string&& desc, const Box& base, PropertyList props) + Struct(std::string desc, const Box& base, PropertyList props) : Struct(*base.template as()) { desc_ = std::move(desc); set_properties(props); diff --git a/fable/include/fable/schema/variant.hpp b/fable/include/fable/schema/variant.hpp index 05176f9a1..7630b547f 100644 --- a/fable/include/fable/schema/variant.hpp +++ b/fable/include/fable/schema/variant.hpp @@ -57,11 +57,11 @@ using BoxList = std::initializer_list; class Variant : public Interface { public: // Constructors Variant(std::initializer_list vec) : Variant("", vec) {} - Variant(std::string&& desc, std::initializer_list vec) + Variant(std::string desc, std::initializer_list vec) : Variant(std::move(desc), std::vector(vec)) {} Variant(std::vector&& vec) : Variant("", std::move(vec)) {} // NOLINT(runtime/explicit) - Variant(std::string&& desc, std::vector&& vec); + Variant(std::string desc, std::vector&& vec); public: // Base Interface* clone() const override { return new Variant(*this); } @@ -85,7 +85,7 @@ class Variant : public Interface { void set_description(const std::string& s) override { desc_ = s; } void set_description(std::string&& s) { desc_ = std::move(s); } const std::string& description() const override { return desc_; } - Variant description(std::string&& desc) && { + Variant description(std::string desc) && { desc_ = std::move(desc); return std::move(*this); } diff --git a/fable/src/fable/schema.cpp b/fable/src/fable/schema.cpp index 5f3a6f553..72e662b72 100644 --- a/fable/src/fable/schema.cpp +++ b/fable/src/fable/schema.cpp @@ -45,13 +45,13 @@ BoxVec to_box_vec(const std::vector& xs) { // Variant constructions: Schema::Schema(const std::vector& xs) : impl_(new Variant(to_box_vec(xs))) {} -Schema::Schema(std::string&& desc, const std::vector& xs) +Schema::Schema(std::string desc, const std::vector& xs) : impl_(new Variant(std::move(desc), to_box_vec(xs))) {} Schema::Schema(schema::BoxList props) : impl_(new Variant(props)) {} -Schema::Schema(std::string&& desc, schema::BoxList props) +Schema::Schema(std::string desc, schema::BoxList props) : impl_(new Variant(std::move(desc), props)) {} Schema::Schema(schema::BoxVec&& props) : impl_(new Variant(std::move(props))) {} -Schema::Schema(std::string&& desc, schema::BoxVec&& props) +Schema::Schema(std::string desc, schema::BoxVec&& props) : impl_(new Variant(std::move(desc), std::move(props))) {} } // namespace fable diff --git a/fable/src/fable/schema/boolean.cpp b/fable/src/fable/schema/boolean.cpp index a27404f4f..dc4ab312f 100644 --- a/fable/src/fable/schema/boolean.cpp +++ b/fable/src/fable/schema/boolean.cpp @@ -28,7 +28,7 @@ namespace fable { namespace schema { -Boolean::Boolean(Boolean::Type* ptr, std::string&& desc) +Boolean::Boolean(Boolean::Type* ptr, std::string desc) : Base(JsonType::boolean, std::move(desc)), ptr_(ptr) {} Json Boolean::json_schema() const { diff --git a/fable/src/fable/schema/factory_advanced_test.cpp b/fable/src/fable/schema/factory_advanced_test.cpp index a655ef3f4..99f5b89d3 100644 --- a/fable/src/fable/schema/factory_advanced_test.cpp +++ b/fable/src/fable/schema/factory_advanced_test.cpp @@ -119,7 +119,7 @@ class Random { class DistributionFactory : public fable::schema::Factory { public: - DistributionFactory(DistributionPtr* ptr, std::string&& desc) + DistributionFactory(DistributionPtr* ptr, std::string desc) : fable::schema::Factory(ptr, std::move(desc)) { this->set_factory_key("binding"); this->set_args_key(""); diff --git a/fable/src/fable/schema/variant.cpp b/fable/src/fable/schema/variant.cpp index 3694351f9..2d9e8c1f8 100644 --- a/fable/src/fable/schema/variant.cpp +++ b/fable/src/fable/schema/variant.cpp @@ -34,7 +34,7 @@ namespace fable { namespace schema { -Variant::Variant(std::string&& desc, std::vector&& vec) +Variant::Variant(std::string desc, std::vector&& vec) : desc_(std::move(desc)), schemas_(std::move(vec)) { assert(!schemas_.empty());