Skip to content

Commit 6700c73

Browse files
clsimcassava
authored andcommitted
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.
1 parent 6113b48 commit 6700c73

19 files changed

+148
-105
lines changed

fable/include/fable/make_schema.hpp

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
* Copyright 2023 Robert Bosch GmbH
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* SPDX-License-Identifier: Apache-2.0
17+
*/
18+
/**
19+
* \file fable/make_schema.hpp
20+
*
21+
* This file provides a facade for the make_schema function which implements
22+
* a short-cut for the compiler which reduces the excessive resource
23+
* consumption of the actual implementation.
24+
*/
25+
26+
#pragma once
27+
28+
#include <string> // for string
29+
30+
#include <fable/schema/array.hpp> // for Array<>
31+
#include <fable/schema/boolean.hpp> // for Boolean
32+
#include <fable/schema/confable.hpp> // for FromConfable
33+
#include <fable/schema/const.hpp> // for Const<>
34+
#include <fable/schema/duration.hpp> // for Duration<>
35+
#include <fable/schema/enum.hpp> // for Enum<>
36+
#include <fable/schema/ignore.hpp> // for Ignore
37+
#include <fable/schema/interface.hpp> // for Interface, Box
38+
#include <fable/schema/json.hpp> // for FromJson<>
39+
#include <fable/schema/map.hpp> // for Map<>
40+
#include <fable/schema/number.hpp> // for Number<>
41+
#include <fable/schema/optional.hpp> // for Optional<>
42+
#include <fable/schema/passthru.hpp> // for Passthru
43+
#include <fable/schema/path.hpp> // for Path
44+
#include <fable/schema/string.hpp> // for String
45+
#include <fable/schema/struct.hpp> // for Struct
46+
#include <fable/schema/variant.hpp> // for Variant
47+
48+
// It is important that this include comes after all the other ones,
49+
// so that it has access to ALL the previous definitions.
50+
#include <fable/schema/magic.hpp> // for make_prototype, ...
51+
52+
namespace fable::schema {
53+
namespace details {
54+
55+
/**
56+
* Implements the make_schema function for one datatype
57+
*/
58+
template <typename T>
59+
struct make_schema_wrapper1 {
60+
static auto make_schema(T* ptr, std::string&& desc) {
61+
return ::fable::schema::make_schema_impl(ptr, std::move(desc));
62+
}
63+
};
64+
65+
/**
66+
*/
67+
template <typename T, typename P>
68+
struct make_schema_wrapper2 {
69+
static auto make_schema(T* ptr, P proto, std::string&& desc) {
70+
return ::fable::schema::make_schema_impl(ptr, std::move(proto), std::move(desc));
71+
}
72+
};
73+
74+
} // namespace details
75+
76+
/**
77+
* Returns the schema for a given datum and its description
78+
*
79+
* \param ptr Pointer to the datum
80+
* \param desc Textual description of the datum
81+
* \return Schema for the datum
82+
*/
83+
template <typename T>
84+
auto make_schema(T* ptr, std::string&& desc) {
85+
return details::make_schema_wrapper1<T>::make_schema(ptr, std::move(desc));
86+
}
87+
88+
/**
89+
* Returns the schema for a given datum and its description
90+
*
91+
* \param ptr Pointer to the datum
92+
* \param proto Prototype of the data-value
93+
* \param desc Textual description of the datum
94+
* \return Schema for the datum
95+
* \note Those types which have a prototype, namely string & path
96+
* do not matter for the compile-time reduction
97+
*/
98+
template <typename T, typename P>
99+
auto make_schema(T* ptr, P proto, std::string&& desc) {
100+
return details::make_schema_wrapper2<T, P>::make_schema(ptr, std::move(proto), std::move(desc));
101+
}
102+
103+
} // namespace fable::schema

fable/include/fable/schema.hpp

+2-23
Original file line numberDiff line numberDiff line change
@@ -122,29 +122,7 @@
122122
#include <utility> // for move
123123
#include <vector> // for vector<>
124124

125-
#include <boost/optional.hpp> // for optional<>
126-
127-
#include <fable/schema/array.hpp> // for Array<>
128-
#include <fable/schema/boolean.hpp> // for Boolean
129-
#include <fable/schema/confable.hpp> // for FromConfable
130-
#include <fable/schema/const.hpp> // for Const<>
131-
#include <fable/schema/duration.hpp> // for Duration<>
132-
#include <fable/schema/enum.hpp> // for Enum<>
133-
#include <fable/schema/ignore.hpp> // for Ignore
134-
#include <fable/schema/interface.hpp> // for Interface, Box
135-
#include <fable/schema/json.hpp> // for FromJson<>
136-
#include <fable/schema/map.hpp> // for Map<>
137-
#include <fable/schema/number.hpp> // for Number<>
138-
#include <fable/schema/optional.hpp> // for Optional<>
139-
#include <fable/schema/passthru.hpp> // for Passthru
140-
#include <fable/schema/path.hpp> // for Path
141-
#include <fable/schema/string.hpp> // for String
142-
#include <fable/schema/struct.hpp> // for Struct
143-
#include <fable/schema/variant.hpp> // for Variant
144-
145-
// It is important that this include comes after all the other ones,
146-
// so that it has access to ALL the previous definitions.
147-
#include <fable/schema/magic.hpp> // for make_prototype, ...
125+
#include <fable/make_schema.hpp> // for make_schema
148126

149127
namespace fable {
150128

@@ -153,6 +131,7 @@ using schema::make_const_schema;
153131
using schema::make_const_str;
154132
using schema::make_prototype;
155133
using schema::make_schema;
134+
using schema::make_schema_impl;
156135

157136
/**
158137
* Define the automatically deduced schema class of a given type.

fable/include/fable/schema/array.hpp

+7-7
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,13 @@ template <typename T, typename P>
4040
class Array : public Base<Array<T, P>> {
4141
public: // Types and Constructors
4242
using Type = std::vector<T>;
43-
using PrototypeSchema = P;
43+
using PrototypeSchema = std::remove_cv_t<std::remove_reference_t<P>>;
4444

4545
Array(Type* ptr, std::string&& desc);
46-
Array(Type* ptr, const PrototypeSchema& prototype)
47-
: Base<Array<T, P>>(JsonType::array), prototype_(prototype), ptr_(ptr) {}
48-
Array(Type* ptr, const PrototypeSchema& prototype, std::string&& desc)
49-
: Base<Array<T, P>>(JsonType::array, std::move(desc)), prototype_(prototype), ptr_(ptr) {}
46+
Array(Type* ptr, PrototypeSchema prototype)
47+
: Base<Array<T, P>>(JsonType::array), prototype_(std::move(prototype)), ptr_(ptr) {}
48+
Array(Type* ptr, PrototypeSchema prototype, std::string&& desc)
49+
: Base<Array<T, P>>(JsonType::array, std::move(desc)), prototype_(std::move(prototype)), ptr_(ptr) {}
5050

5151
#if 0
5252
// This is defined in: fable/schema/magic.hpp
@@ -174,8 +174,8 @@ class Array : public Base<Array<T, P>> {
174174
};
175175

176176
template <typename T, typename P>
177-
Array<T, P> make_schema(std::vector<T>* ptr, const P& prototype, std::string&& desc) {
178-
return Array<T, P>(ptr, prototype, std::move(desc));
177+
Array<T, P> make_schema_impl(std::vector<T>* ptr, P&& prototype, std::string&& desc) {
178+
return Array<T, P>(ptr, std::forward<P>(prototype), std::move(desc));
179179
}
180180

181181
} // namespace schema

fable/include/fable/schema/boolean.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class Boolean : public Base<Boolean> {
5151
Type* ptr_{nullptr};
5252
};
5353

54-
inline Boolean make_schema(bool* ptr, std::string&& desc) { return Boolean(ptr, std::move(desc)); }
54+
inline Boolean make_schema_impl(bool* ptr, std::string&& desc) { return Boolean(ptr, std::move(desc)); }
5555

5656
} // namespace schema
5757
} // namespace fable

fable/include/fable/schema/confable.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ class FromConfable : public Base<FromConfable<T>> {
104104
};
105105

106106
template <typename T>
107-
FromConfable<T> make_schema(T* ptr, std::string&& desc) {
107+
FromConfable<T> make_schema_impl(T* ptr, std::string&& desc) {
108108
assert(ptr != nullptr);
109109
return FromConfable<T>(ptr, std::move(desc));
110110
}

fable/include/fable/schema/const.hpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,12 @@ template <typename T, typename P>
3737
class Const : public Base<Const<T, P>> {
3838
public: // Types and Constructors
3939
using Type = T;
40-
using PrototypeSchema = P;
40+
using PrototypeSchema = std::remove_cv_t<std::remove_reference_t<P>>;
4141

4242
Const(const Type& constant, std::string&& desc);
43-
Const(const Type& constant, const PrototypeSchema& prototype, std::string&& desc)
43+
Const(const Type& constant, PrototypeSchema prototype, std::string&& desc)
4444
: Base<Const<T, P>>(prototype.type(), std::move(desc))
45-
, prototype_(prototype)
45+
, prototype_(std::move(prototype))
4646
, constant_(constant) {
4747
prototype_.reset_ptr();
4848
}
@@ -89,8 +89,8 @@ class Const : public Base<Const<T, P>> {
8989
};
9090

9191
template <typename T, typename P>
92-
Const<T, P> make_const_schema(const T& constant, const P& prototype, std::string&& desc) {
93-
return Const<T, P>(constant, prototype, std::move(desc));
92+
Const<T, P> make_const_schema(const T& constant, P&& prototype, std::string&& desc) {
93+
return Const<T, P>(constant, std::forward<P>(prototype), std::move(desc));
9494
}
9595

9696
inline Const<std::string, String> make_const_str(const std::string& constant, std::string&& desc) {

fable/include/fable/schema/duration.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ class Duration : public Base<Duration<T, Period>> {
187187
};
188188

189189
template <typename Rep, typename Period>
190-
inline Duration<Rep, Period> make_schema(std::chrono::duration<Rep, Period>* ptr,
190+
inline Duration<Rep, Period> make_schema_impl(std::chrono::duration<Rep, Period>* ptr,
191191
std::string&& desc) {
192192
return Duration<Rep, Period>(ptr, std::move(desc));
193193
}

fable/include/fable/schema/enum.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ class Enum : public Base<Enum<T>> {
103103
};
104104

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

fable/include/fable/schema/ignore.hpp

-4
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,5 @@ class Ignore : public Base<Ignore> {
6060
void reset_ptr() override {}
6161
};
6262

63-
inline Ignore make_schema(std::string&& desc, JsonType t = JsonType::object) {
64-
return Ignore(std::move(desc), t);
65-
}
66-
6763
} // namespace schema
6864
} // namespace fable

fable/include/fable/schema/json.hpp

-5
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,5 @@ class FromJson : public Base<FromJson<T>> {
7979
Type* ptr_{nullptr};
8080
};
8181

82-
template <typename T>
83-
inline FromJson<T> make_schema(T* ptr, JsonType t, std::string&& desc) {
84-
return FromJson<T>(ptr, t, std::move(desc));
85-
}
86-
8782
} // namespace schema
8883
} // namespace fable

fable/include/fable/schema/magic.hpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@
2121
* \see fable/schema_test.cpp
2222
*
2323
* This file defines the `make_prototype` functions that can automatically
24-
* derive the prototype via the `make_schema` functions. It also contains the
24+
* derive the prototype via the `make_schema_impl` functions. It also contains the
2525
* definitions of constructors that make use of these functions.
2626
*
27-
* Unfortunately, all `make_schema` functions need to already be defined at the
27+
* Unfortunately, all `make_schema_impl` functions need to already be defined at the
2828
* point of definition of these constructors, which is why they have to be in
2929
* this file in the first place.
3030
*
@@ -58,7 +58,7 @@ Array<T, P>::Array(std::vector<T>* ptr, std::string&& desc)
5858
: Array<T, P>(ptr, make_prototype<T>(), std::move(desc)) {}
5959

6060
template <typename T>
61-
Array<T, decltype(make_prototype<T>())> make_schema(std::vector<T>* ptr, std::string&& desc) {
61+
Array<T, decltype(make_prototype<T>())> make_schema_impl(std::vector<T>* ptr, std::string&& desc) {
6262
return Array<T, decltype(make_prototype<T>())>(ptr, std::move(desc));
6363
}
6464

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

7878
template <typename T>
79-
Map<T, decltype(make_prototype<T>())> make_schema(std::map<std::string, T>* ptr,
79+
Map<T, decltype(make_prototype<T>())> make_schema_impl(std::map<std::string, T>* ptr,
8080
std::string&& desc) {
8181
return Map<T, decltype(make_prototype<T>())>(ptr, std::move(desc));
8282
}
@@ -86,7 +86,7 @@ Optional<T, P>::Optional(boost::optional<T>* ptr, std::string&& desc)
8686
: Optional<T, P>(ptr, make_prototype<T>(), std::move(desc)) {}
8787

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

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

104104
} // namespace schema

fable/include/fable/schema/map.hpp

+7-7
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,15 @@ template <typename T, typename P>
5050
class Map : public Base<Map<T, P>> {
5151
public: // Types and Constructors
5252
using Type = std::map<std::string, T>;
53-
using PrototypeSchema = P;
53+
using PrototypeSchema = std::remove_cv_t<std::remove_reference_t<P>>;
5454

5555
Map(Type* ptr, std::string&& desc);
56-
Map(Type* ptr, const PrototypeSchema& prototype)
57-
: Base<Map<T, P>>(JsonType::object), prototype_(prototype), ptr_(ptr) {
56+
Map(Type* ptr, PrototypeSchema prototype)
57+
: Base<Map<T, P>>(JsonType::object), prototype_(std::move(prototype)), ptr_(ptr) {
5858
prototype_.reset_ptr();
5959
}
60-
Map(Type* ptr, const PrototypeSchema& prototype, std::string&& desc)
61-
: Base<Map<T, P>>(JsonType::object, std::move(desc)), prototype_(prototype), ptr_(ptr) {
60+
Map(Type* ptr, PrototypeSchema prototype, std::string&& desc)
61+
: Base<Map<T, P>>(JsonType::object, std::move(desc)), prototype_(std::move(prototype)), ptr_(ptr) {
6262
prototype_.reset_ptr();
6363
}
6464

@@ -189,8 +189,8 @@ class Map : public Base<Map<T, P>> {
189189
};
190190

191191
template <typename T, typename P>
192-
Map<T, P> make_schema(std::map<std::string, T>* ptr, const P& prototype, std::string&& desc) {
193-
return Map<T, P>(ptr, prototype, std::move(desc));
192+
Map<T, P> make_schema_impl(std::map<std::string, T>* ptr, P&& prototype, std::string&& desc) {
193+
return Map<T, P>(ptr, std::forward<P>(prototype), std::move(desc));
194194
}
195195

196196
} // namespace schema

fable/include/fable/schema/number.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ class Number : public Base<Number<T>> {
104104

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

fable/include/fable/schema/optional.hpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@ template <typename T, typename P>
3939
class Optional : public Base<Optional<T, P>> {
4040
public: // Types and Constructors
4141
using Type = boost::optional<T>;
42-
using PrototypeSchema = P;
42+
using PrototypeSchema = std::remove_cv_t<std::remove_reference_t<P>>;
4343

4444
Optional(Type* ptr, std::string&& desc);
45-
Optional(Type* ptr, const PrototypeSchema& prototype, std::string&& desc)
46-
: Base<Optional<T, P>>(prototype.type(), std::move(desc)), prototype_(prototype), ptr_(ptr) {
45+
Optional(Type* ptr, PrototypeSchema prototype, std::string&& desc)
46+
: Base<Optional<T, P>>(prototype.type(), std::move(desc)), prototype_(std::move(prototype)), ptr_(ptr) {
4747
prototype_.reset_ptr();
4848
}
4949

@@ -113,8 +113,8 @@ class Optional : public Base<Optional<T, P>> {
113113
};
114114

115115
template <typename T, typename P>
116-
Optional<T, P> make_schema(boost::optional<T>* ptr, const P& prototype, std::string&& desc) {
117-
return Optional<T, P>(ptr, prototype, std::move(desc));
116+
Optional<T, P> make_schema_impl(boost::optional<T>* ptr, P&& prototype, std::string&& desc) {
117+
return Optional<T, P>(ptr, std::forward<P>(prototype), std::move(desc));
118118
}
119119

120120
} // namespace schema

0 commit comments

Comments
 (0)