Skip to content

Commit

Permalink
fable: Fix excessive compilation duration
Browse files Browse the repository at this point in the history
  • Loading branch information
clsim authored and cassava committed Jan 9, 2024
1 parent b13c718 commit 6ff5af8
Show file tree
Hide file tree
Showing 18 changed files with 127 additions and 54 deletions.
94 changes: 94 additions & 0 deletions fable/include/fable/make_schema.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* 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 <string> // for string

#include <fable/schema/array.hpp> // for Array<>
#include <fable/schema/boolean.hpp> // for Boolean
#include <fable/schema/confable.hpp> // for FromConfable
#include <fable/schema/const.hpp> // for Const<>
#include <fable/schema/duration.hpp> // for Duration<>
#include <fable/schema/enum.hpp> // for Enum<>
#include <fable/schema/ignore.hpp> // for Ignore
#include <fable/schema/interface.hpp> // for Interface, Box
#include <fable/schema/json.hpp> // for FromJson<>
#include <fable/schema/map.hpp> // for Map<>
#include <fable/schema/number.hpp> // for Number<>
#include <fable/schema/optional.hpp> // for Optional<>
#include <fable/schema/passthru.hpp> // for Passthru
#include <fable/schema/path.hpp> // for Path
#include <fable/schema/string.hpp> // for String
#include <fable/schema/struct.hpp> // for Struct
#include <fable/schema/variant.hpp> // 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 <fable/schema/magic.hpp> // for make_prototype, ...

namespace fable::schema {
namespace details {

/**
* Implements the make_schema function for one datatype
*/
template <typename T>
struct make_schema_wrapper {
static auto make_schema(T* ptr, std::string&& desc) {
return ::fable::schema::make_schema_impl(ptr, 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 <typename T>
auto make_schema(T* ptr, std::string&& desc) {
return details::make_schema_wrapper<T>::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 <typename T, typename T2>
auto make_schema(T* ptr, T2 proto, std::string&& desc) {
return ::fable::schema::make_schema_impl(ptr, proto, std::move(desc));
}

} // namespace fable::schema
25 changes: 2 additions & 23 deletions fable/include/fable/schema.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,29 +122,7 @@
#include <utility> // for move
#include <vector> // for vector<>

#include <boost/optional.hpp> // for optional<>

#include <fable/schema/array.hpp> // for Array<>
#include <fable/schema/boolean.hpp> // for Boolean
#include <fable/schema/confable.hpp> // for FromConfable
#include <fable/schema/const.hpp> // for Const<>
#include <fable/schema/duration.hpp> // for Duration<>
#include <fable/schema/enum.hpp> // for Enum<>
#include <fable/schema/ignore.hpp> // for Ignore
#include <fable/schema/interface.hpp> // for Interface, Box
#include <fable/schema/json.hpp> // for FromJson<>
#include <fable/schema/map.hpp> // for Map<>
#include <fable/schema/number.hpp> // for Number<>
#include <fable/schema/optional.hpp> // for Optional<>
#include <fable/schema/passthru.hpp> // for Passthru
#include <fable/schema/path.hpp> // for Path
#include <fable/schema/string.hpp> // for String
#include <fable/schema/struct.hpp> // for Struct
#include <fable/schema/variant.hpp> // 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 <fable/schema/magic.hpp> // for make_prototype, ...
#include <fable/make_schema.hpp> // for make_schema

namespace fable {

Expand All @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion fable/include/fable/schema/array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ class Array : public Base<Array<T, P>> {
};

template <typename T, typename P>
Array<T, P> make_schema(std::vector<T>* ptr, const P& prototype, std::string&& desc) {
Array<T, P> make_schema_impl(std::vector<T>* ptr, const P& prototype, std::string&& desc) {
return Array<T, P>(ptr, prototype, std::move(desc));
}

Expand Down
2 changes: 1 addition & 1 deletion fable/include/fable/schema/boolean.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class Boolean : public Base<Boolean> {
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
2 changes: 1 addition & 1 deletion fable/include/fable/schema/confable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ class FromConfable : public Base<FromConfable<T>> {
};

template <typename T>
FromConfable<T> make_schema(T* ptr, std::string&& desc) {
FromConfable<T> make_schema_impl(T* ptr, std::string&& desc) {
assert(ptr != nullptr);
return FromConfable<T>(ptr, std::move(desc));
}
Expand Down
2 changes: 1 addition & 1 deletion fable/include/fable/schema/duration.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ class Duration : public Base<Duration<T, Period>> {
};

template <typename Rep, typename Period>
inline Duration<Rep, Period> make_schema(std::chrono::duration<Rep, Period>* ptr,
inline Duration<Rep, Period> make_schema_impl(std::chrono::duration<Rep, Period>* ptr,
std::string&& desc) {
return Duration<Rep, Period>(ptr, std::move(desc));
}
Expand Down
2 changes: 1 addition & 1 deletion fable/include/fable/schema/enum.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class Enum : public Base<Enum<T>> {
};

template <typename T, std::enable_if_t<std::is_enum<T>::value, int> = 0>
inline Enum<T> make_schema(T* ptr, std::string&& desc) {
inline Enum<T> make_schema_impl(T* ptr, std::string&& desc) {
return Enum<T>(ptr, std::move(desc));
}

Expand Down
2 changes: 1 addition & 1 deletion fable/include/fable/schema/ignore.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class Ignore : public Base<Ignore> {
void reset_ptr() override {}
};

inline Ignore make_schema(std::string&& desc, JsonType t = JsonType::object) {
inline Ignore make_schema_impl(std::string&& desc, JsonType t = JsonType::object) {
return Ignore(std::move(desc), t);
}

Expand Down
2 changes: 1 addition & 1 deletion fable/include/fable/schema/json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class FromJson : public Base<FromJson<T>> {
};

template <typename T>
inline FromJson<T> make_schema(T* ptr, JsonType t, std::string&& desc) {
inline FromJson<T> make_schema_impl(T* ptr, JsonType t, std::string&& desc) {
return FromJson<T>(ptr, t, std::move(desc));
}

Expand Down
12 changes: 6 additions & 6 deletions fable/include/fable/schema/magic.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down Expand Up @@ -58,7 +58,7 @@ Array<T, P>::Array(std::vector<T>* ptr, std::string&& desc)
: Array<T, P>(ptr, make_prototype<T>(), std::move(desc)) {}

template <typename T>
Array<T, decltype(make_prototype<T>())> make_schema(std::vector<T>* ptr, std::string&& desc) {
Array<T, decltype(make_prototype<T>())> make_schema_impl(std::vector<T>* ptr, std::string&& desc) {
return Array<T, decltype(make_prototype<T>())>(ptr, std::move(desc));
}

Expand All @@ -76,7 +76,7 @@ Map<T, P>::Map(std::map<std::string, T>* ptr, std::string&& desc)
: Map<T, P>(ptr, make_prototype<T>(), std::move(desc)) {}

template <typename T>
Map<T, decltype(make_prototype<T>())> make_schema(std::map<std::string, T>* ptr,
Map<T, decltype(make_prototype<T>())> make_schema_impl(std::map<std::string, T>* ptr,
std::string&& desc) {
return Map<T, decltype(make_prototype<T>())>(ptr, std::move(desc));
}
Expand All @@ -86,7 +86,7 @@ Optional<T, P>::Optional(boost::optional<T>* ptr, std::string&& desc)
: Optional<T, P>(ptr, make_prototype<T>(), std::move(desc)) {}

template <typename T>
Optional<T, decltype(make_prototype<T>())> make_schema(boost::optional<T>* ptr,
Optional<T, decltype(make_prototype<T>())> make_schema_impl(boost::optional<T>* ptr,
std::string&& desc) {
return Optional<T, decltype(make_prototype<T>())>(ptr, std::move(desc));
}
Expand All @@ -98,7 +98,7 @@ auto make_prototype(std::string&& desc) {

template <typename T, std::enable_if_t<!std::is_base_of<Confable, T>::value, int>>
auto make_prototype(std::string&& desc) {
return make_schema(static_cast<T*>(nullptr), std::move(desc));
return make_schema_impl(static_cast<T*>(nullptr), std::move(desc));
}

} // namespace schema
Expand Down
2 changes: 1 addition & 1 deletion fable/include/fable/schema/map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ class Map : public Base<Map<T, P>> {
};

template <typename T, typename P>
Map<T, P> make_schema(std::map<std::string, T>* ptr, const P& prototype, std::string&& desc) {
Map<T, P> make_schema_impl(std::map<std::string, T>* ptr, const P& prototype, std::string&& desc) {
return Map<T, P>(ptr, prototype, std::move(desc));
}

Expand Down
2 changes: 1 addition & 1 deletion fable/include/fable/schema/number.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ class Number : public Base<Number<T>> {

template <typename T,
std::enable_if_t<std::is_arithmetic<T>::value && !std::is_enum<T>::value, int> = 0>
inline Number<T> make_schema(T* ptr, std::string&& desc) {
inline Number<T> make_schema_impl(T* ptr, std::string&& desc) {
return Number<T>(ptr, std::move(desc));
}

Expand Down
2 changes: 1 addition & 1 deletion fable/include/fable/schema/optional.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ class Optional : public Base<Optional<T, P>> {
};

template <typename T, typename P>
Optional<T, P> make_schema(boost::optional<T>* ptr, const P& prototype, std::string&& desc) {
Optional<T, P> make_schema_impl(boost::optional<T>* ptr, const P& prototype, std::string&& desc) {
return Optional<T, P>(ptr, prototype, std::move(desc));
}

Expand Down
4 changes: 2 additions & 2 deletions fable/include/fable/schema/passthru.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,12 @@ class Passthru : public Base<Passthru<P>> {
Type* ptr_{nullptr};
};

inline Passthru<Ignore> make_schema(Conf* ptr, std::string&& desc) {
inline Passthru<Ignore> make_schema_impl(Conf* ptr, std::string&& desc) {
return Passthru<Ignore>(ptr, Ignore(), std::move(desc));
}

template <typename P>
Passthru<P> make_schema(Conf* ptr, const P& prototype, std::string&& desc) {
Passthru<P> make_schema_impl(Conf* ptr, const P& prototype, std::string&& desc) {
return Passthru<P>(ptr, prototype, std::move(desc));
}

Expand Down
2 changes: 1 addition & 1 deletion fable/include/fable/schema/path.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ class Path : public Base<Path> {
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));
}

Expand Down
2 changes: 1 addition & 1 deletion fable/include/fable/schema/string.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ class String : public Base<String> {
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));
}

Expand Down
14 changes: 7 additions & 7 deletions fable/include/fable/schema/struct.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ namespace schema {
* Struct can be instantiated then like so:
*
* return Struct{
* {"prop_a", make_schema(...)},
* {"prop_b", make_schema(...)},
* {"prop_a", make_schema_impl(...)},
* {"prop_b", make_schema_impl(...)},
* };
*/
template <typename S = Box>
Expand Down Expand Up @@ -92,7 +92,7 @@ class Struct : public Base<Struct> {
* return Struct{
* Base::schema_impl(),
* {
* {"member", make_schema(&member, "important addition")},
* {"member", make_schema_impl(&member, "important addition")},
* }
* };
* }
Expand Down Expand Up @@ -218,22 +218,22 @@ class Struct : public Base<Struct> {
};

template <typename T, typename = enable_if_property_list_t<T>>
inline Struct make_schema(T&& props) {
inline Struct make_schema_impl(T&& props) {
return Struct(std::forward<T>(props));
}

template <typename T, typename = enable_if_property_list_t<T>>
inline Struct make_schema(std::string&& desc, T&& props) {
inline Struct make_schema_impl(std::string&& desc, T&& props) {
return Struct(std::move(desc), std::forward<T>(props));
}

template <typename T, typename = enable_if_property_list_t<T>>
inline Struct make_schema(std::string&& desc, const Box& base, T&& props) {
inline Struct make_schema_impl(std::string&& desc, const Box& base, T&& props) {
return Struct(std::move(desc), base, std::forward<T>(props));
}

template <typename T, typename = enable_if_property_list_t<T>>
inline Struct make_schema(std::string&& desc, const Struct& base, T&& props) {
inline Struct make_schema_impl(std::string&& desc, const Struct& base, T&& props) {
return Struct(std::move(desc), base, std::forward<T>(props));
}

Expand Down
8 changes: 4 additions & 4 deletions fable/include/fable/schema/variant.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,13 @@ class Variant : public Interface {
bool unique_match_{false};
};

inline Variant make_schema(std::initializer_list<Box> vec) { return Variant(vec); }
inline Variant make_schema(std::string&& desc, std::initializer_list<Box> vec) {
inline Variant make_schema_impl(std::initializer_list<Box> vec) { return Variant(vec); }
inline Variant make_schema_impl(std::string&& desc, std::initializer_list<Box> vec) {
return Variant(std::move(desc), std::vector<Box>(vec));
}

inline Variant make_schema(std::vector<Box>&& vec) { return Variant(std::move(vec)); }
inline Variant make_schema(std::string&& desc, std::vector<Box>&& vec) {
inline Variant make_schema_impl(std::vector<Box>&& vec) { return Variant(std::move(vec)); }
inline Variant make_schema_impl(std::string&& desc, std::vector<Box>&& vec) {
return Variant(std::move(desc), std::move(vec));
}

Expand Down

0 comments on commit 6ff5af8

Please sign in to comment.