Skip to content

Commit

Permalink
fable: Fix excessive compilation duration
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
clsim authored and cassava committed Jan 10, 2024
1 parent 0bdbe6d commit f0ee64d
Show file tree
Hide file tree
Showing 19 changed files with 148 additions and 105 deletions.
103 changes: 103 additions & 0 deletions fable/include/fable/make_schema.hpp
Original file line number Diff line number Diff line change
@@ -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 <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_wrapper1 {
static auto make_schema(T* ptr, std::string&& desc) {
return ::fable::schema::make_schema_impl(ptr, std::move(desc));
}
};

/**
*/
template <typename T, typename P>
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 <typename T>
auto make_schema(T* ptr, std::string&& desc) {
return details::make_schema_wrapper1<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 P>
auto make_schema(T* ptr, P proto, std::string&& desc) {
return details::make_schema_wrapper2<T, P>::make_schema(ptr, std::move(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
14 changes: 7 additions & 7 deletions fable/include/fable/schema/array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ template <typename T, typename P>
class Array : public Base<Array<T, P>> {
public: // Types and Constructors
using Type = std::vector<T>;
using PrototypeSchema = P;
using PrototypeSchema = std::remove_cv_t<std::remove_reference_t<P>>;

Array(Type* ptr, std::string&& desc);
Array(Type* ptr, const PrototypeSchema& prototype)
: Base<Array<T, P>>(JsonType::array), prototype_(prototype), ptr_(ptr) {}
Array(Type* ptr, const PrototypeSchema& prototype, std::string&& desc)
: Base<Array<T, P>>(JsonType::array, std::move(desc)), prototype_(prototype), ptr_(ptr) {}
Array(Type* ptr, PrototypeSchema prototype)
: Base<Array<T, P>>(JsonType::array), prototype_(std::move(prototype)), ptr_(ptr) {}
Array(Type* ptr, PrototypeSchema prototype, std::string&& desc)
: Base<Array<T, P>>(JsonType::array, std::move(desc)), prototype_(std::move(prototype)), ptr_(ptr) {}

#if 0
// This is defined in: fable/schema/magic.hpp
Expand Down Expand Up @@ -174,8 +174,8 @@ 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) {
return Array<T, P>(ptr, prototype, std::move(desc));
Array<T, P> make_schema_impl(std::vector<T>* ptr, P&& prototype, std::string&& desc) {
return Array<T, P>(ptr, std::forward<P>(prototype), std::move(desc));
}

} // namespace schema
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
10 changes: 5 additions & 5 deletions fable/include/fable/schema/const.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ template <typename T, typename P>
class Const : public Base<Const<T, P>> {
public: // Types and Constructors
using Type = T;
using PrototypeSchema = P;
using PrototypeSchema = std::remove_cv_t<std::remove_reference_t<P>>;

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<Const<T, P>>(prototype.type(), std::move(desc))
, prototype_(prototype)
, prototype_(std::move(prototype))
, constant_(constant) {
prototype_.reset_ptr();
}
Expand Down Expand Up @@ -89,8 +89,8 @@ class Const : public Base<Const<T, P>> {
};

template <typename T, typename P>
Const<T, P> make_const_schema(const T& constant, const P& prototype, std::string&& desc) {
return Const<T, P>(constant, prototype, std::move(desc));
Const<T, P> make_const_schema(const T& constant, P&& prototype, std::string&& desc) {
return Const<T, P>(constant, std::forward<P>(prototype), std::move(desc));
}

inline Const<std::string, String> make_const_str(const std::string& constant, std::string&& 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
4 changes: 0 additions & 4 deletions fable/include/fable/schema/ignore.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,5 @@ class Ignore : public Base<Ignore> {
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
5 changes: 0 additions & 5 deletions fable/include/fable/schema/json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,5 @@ class FromJson : public Base<FromJson<T>> {
Type* ptr_{nullptr};
};

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

} // namespace schema
} // namespace fable
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
14 changes: 7 additions & 7 deletions fable/include/fable/schema/map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,15 @@ template <typename T, typename P>
class Map : public Base<Map<T, P>> {
public: // Types and Constructors
using Type = std::map<std::string, T>;
using PrototypeSchema = P;
using PrototypeSchema = std::remove_cv_t<std::remove_reference_t<P>>;

Map(Type* ptr, std::string&& desc);
Map(Type* ptr, const PrototypeSchema& prototype)
: Base<Map<T, P>>(JsonType::object), prototype_(prototype), ptr_(ptr) {
Map(Type* ptr, PrototypeSchema prototype)
: Base<Map<T, P>>(JsonType::object), prototype_(std::move(prototype)), ptr_(ptr) {
prototype_.reset_ptr();
}
Map(Type* ptr, const PrototypeSchema& prototype, std::string&& desc)
: Base<Map<T, P>>(JsonType::object, std::move(desc)), prototype_(prototype), ptr_(ptr) {
Map(Type* ptr, PrototypeSchema prototype, std::string&& desc)
: Base<Map<T, P>>(JsonType::object, std::move(desc)), prototype_(std::move(prototype)), ptr_(ptr) {
prototype_.reset_ptr();
}

Expand Down Expand Up @@ -189,8 +189,8 @@ 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) {
return Map<T, P>(ptr, prototype, std::move(desc));
Map<T, P> make_schema_impl(std::map<std::string, T>* ptr, P&& prototype, std::string&& desc) {
return Map<T, P>(ptr, std::forward<P>(prototype), std::move(desc));
}

} // namespace schema
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
10 changes: 5 additions & 5 deletions fable/include/fable/schema/optional.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ template <typename T, typename P>
class Optional : public Base<Optional<T, P>> {
public: // Types and Constructors
using Type = boost::optional<T>;
using PrototypeSchema = P;
using PrototypeSchema = std::remove_cv_t<std::remove_reference_t<P>>;

Optional(Type* ptr, std::string&& desc);
Optional(Type* ptr, const PrototypeSchema& prototype, std::string&& desc)
: Base<Optional<T, P>>(prototype.type(), std::move(desc)), prototype_(prototype), ptr_(ptr) {
Optional(Type* ptr, PrototypeSchema prototype, std::string&& desc)
: Base<Optional<T, P>>(prototype.type(), std::move(desc)), prototype_(std::move(prototype)), ptr_(ptr) {
prototype_.reset_ptr();
}

Expand Down Expand Up @@ -113,8 +113,8 @@ 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) {
return Optional<T, P>(ptr, prototype, std::move(desc));
Optional<T, P> make_schema_impl(boost::optional<T>* ptr, P&& prototype, std::string&& desc) {
return Optional<T, P>(ptr, std::forward<P>(prototype), std::move(desc));
}

} // namespace schema
Expand Down
Loading

0 comments on commit f0ee64d

Please sign in to comment.