-
Notifications
You must be signed in to change notification settings - Fork 60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reduce build time by suppressing template instantiation #1419
base: master
Are you sure you want to change the base?
Changes from all commits
f9a953b
d4600c3
e136f89
cc83724
619bba6
6e75007
65edc60
9ee8e98
f12442d
b3a5354
84f77bd
8fc9e2e
c47b8b3
904fbfe
2400904
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -54,11 +54,13 @@ ament_export_include_directories(${boost_json_SOURCE_DIR}/include) | |
file(GLOB ${PROJECT_NAME}_POSIX_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/posix/*.cpp) | ||
file(GLOB ${PROJECT_NAME}_SYNTAX_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/syntax/*.cpp) | ||
file(GLOB ${PROJECT_NAME}_UTILITY_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/utility/*.cpp) | ||
file(GLOB ${PROJECT_NAME}_READER_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/reader/*.cpp) | ||
|
||
ament_auto_add_library(${PROJECT_NAME} SHARED | ||
${${PROJECT_NAME}_POSIX_SOURCES} | ||
${${PROJECT_NAME}_SYNTAX_SOURCES} | ||
${${PROJECT_NAME}_UTILITY_SOURCES} | ||
${${PROJECT_NAME}_READER_SOURCES} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please sort in lexicographic order unless there is a technical reason not to. |
||
src/object.cpp | ||
src/evaluate.cpp | ||
src/openscenario_interpreter.cpp | ||
|
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -31,74 +31,16 @@ | |||||||
|
||||||||
namespace openscenario_interpreter | ||||||||
{ | ||||||||
inline namespace reader | ||||||||
{ | ||||||||
template <typename Scope> | ||||||||
auto substitute(std::string attribute, Scope & scope) | ||||||||
{ | ||||||||
auto dirname = [](auto &&, auto && scope) { return scope.dirname(); }; | ||||||||
struct Scope; | ||||||||
|
||||||||
auto find_pkg_share = [](auto && package_name, auto &&) { | ||||||||
return ament_index_cpp::get_package_share_directory(package_name); | ||||||||
}; | ||||||||
|
||||||||
auto ros2 = [](auto && arguments, auto &&) { | ||||||||
auto remove_trailing_newline = [](auto && s) { | ||||||||
while (s.back() == '\n') { | ||||||||
s.pop_back(); | ||||||||
} | ||||||||
return s; | ||||||||
}; | ||||||||
if (auto && result = remove_trailing_newline(concealer::dollar("ros2 " + arguments)); | ||||||||
result.find('\n') != std::string::npos) { | ||||||||
throw SyntaxError( | ||||||||
"The substitution result by `$(ros2 ...)` must not contain a newline character. " | ||||||||
"You gave `$(ros2 ", | ||||||||
arguments, ")` and the result was ", | ||||||||
std::quoted(boost::replace_all_copy(result, "\n", "\\n")), | ||||||||
", which is unacceptable for the reasons stated above."); | ||||||||
} else { | ||||||||
return result; | ||||||||
} | ||||||||
}; | ||||||||
|
||||||||
auto var = [](auto && name, auto && scope) { | ||||||||
// TODO: Return the value of the launch configuration variable instead of the OpenSCENARIO parameter. | ||||||||
if (const auto found = scope.ref(name); found) { | ||||||||
return boost::lexical_cast<String>(found); | ||||||||
} else { | ||||||||
return String(); | ||||||||
} | ||||||||
}; | ||||||||
|
||||||||
// NOTE: https://design.ros2.org/articles/roslaunch_xml.html#dynamic-configuration | ||||||||
static const std::unordered_map< | ||||||||
std::string, std::function<std::string(const std::string &, Scope &)> > | ||||||||
substitutions{ | ||||||||
{"dirname", dirname}, | ||||||||
// TODO {"env", env}, | ||||||||
// TODO {"eval", eval}, | ||||||||
// TODO {"exec-in-package", exec_in_package}, | ||||||||
// TODO {"find-exec", find_exec}, | ||||||||
// TODO {"find-pkg-prefix", find_pkg_prefix}, | ||||||||
{"find-pkg-share", find_pkg_share}, | ||||||||
{"ros2", | ||||||||
ros2}, // NOTE: TIER IV extension (Not included in the ROS 2 Launch XML Substitution) | ||||||||
{"var", var}, | ||||||||
}; | ||||||||
|
||||||||
static const auto pattern = std::regex(R"((.*)\$\((([\w-]+)\s?([^\)]*))\)(.*))"); | ||||||||
|
||||||||
for (std::smatch result; std::regex_match(attribute, result, pattern);) { | ||||||||
if (const auto iter = substitutions.find(result.str(3)); iter != std::end(substitutions)) { | ||||||||
attribute = result.str(1) + std::get<1>(*iter)(result.str(4), scope) + result.str(5); | ||||||||
} else { | ||||||||
throw SyntaxError("Unknown substitution ", std::quoted(result.str(3)), " specified"); | ||||||||
} | ||||||||
} | ||||||||
inline namespace syntax | ||||||||
{ | ||||||||
struct Rule; | ||||||||
} // namespace syntax | ||||||||
|
||||||||
return attribute; | ||||||||
} | ||||||||
inline namespace reader | ||||||||
{ | ||||||||
auto substitute(std::string attribute, const Scope & scope) -> String; | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
|
||||||||
template <typename T, typename Node, typename Scope> | ||||||||
auto readAttribute(const std::string & name, const Node & node, const Scope & scope) -> T | ||||||||
|
@@ -156,8 +98,22 @@ auto readAttribute(const std::string & name, const Node & node, const Scope & sc | |||||||
} | ||||||||
} | ||||||||
|
||||||||
extern template auto readAttribute(const std::string &, const pugi::xml_node &, const Scope &) | ||||||||
-> Boolean; | ||||||||
extern template auto readAttribute(const std::string &, const pugi::xml_node &, const Scope &) | ||||||||
-> UnsignedShort; | ||||||||
extern template auto readAttribute(const std::string &, const pugi::xml_node &, const Scope &) | ||||||||
-> UnsignedInteger; | ||||||||
extern template auto readAttribute(const std::string &, const pugi::xml_node &, const Scope &) | ||||||||
-> Double; | ||||||||
extern template auto readAttribute(const std::string &, const pugi::xml_node &, const Scope &) | ||||||||
-> String; | ||||||||
extern template auto readAttribute(const std::string &, const pugi::xml_node &, const Scope &) | ||||||||
-> syntax::Rule; | ||||||||
Comment on lines
+101
to
+112
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please sort in lexicographic order unless there is a technical reason not to. |
||||||||
|
||||||||
template <typename T, typename Node, typename Scope> | ||||||||
auto readAttribute(const std::string & name, const Node & node, const Scope & scope, T && value) | ||||||||
-> T | ||||||||
{ | ||||||||
if (node.attribute(name.c_str())) { | ||||||||
return readAttribute<T>(name, node, scope); | ||||||||
|
@@ -177,5 +133,4 @@ auto readAttribute(const std::string & name, const Node & node, const Scope & sc | |||||||
} | ||||||||
} // namespace reader | ||||||||
} // namespace openscenario_interpreter | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
|
||||||||
#endif // OPENSCENARIO_INTERPRETER__READER__ATTRIBUTE_HPP_ |
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -36,6 +36,17 @@ | |||||||||||||
|
||||||||||||||
namespace openscenario_interpreter | ||||||||||||||
{ | ||||||||||||||
|
||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
struct Scope; | ||||||||||||||
|
||||||||||||||
inline namespace syntax | ||||||||||||||
{ | ||||||||||||||
struct Orientation; | ||||||||||||||
struct Position; | ||||||||||||||
struct Properties; | ||||||||||||||
struct Range; | ||||||||||||||
} // namespace syntax | ||||||||||||||
|
||||||||||||||
inline namespace reader | ||||||||||||||
{ | ||||||||||||||
using Cardinality = | ||||||||||||||
|
@@ -72,7 +83,7 @@ auto traverse(const pugi::xml_node & parent, const std::string & name, F && f) - | |||||||||||||
} | ||||||||||||||
|
||||||||||||||
template <typename T, typename Scope> | ||||||||||||||
auto readElement(const std::string & name, const pugi::xml_node & parent, Scope & scope) | ||||||||||||||
auto readElement(const std::string & name, const pugi::xml_node & parent, Scope & scope) -> T | ||||||||||||||
{ | ||||||||||||||
if (const auto child = parent.child(name.c_str())) { | ||||||||||||||
return T(child, scope); | ||||||||||||||
|
@@ -89,6 +100,15 @@ auto readElement(const std::string & name, const pugi::xml_node & parent, Scope | |||||||||||||
} | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
extern template auto readElement(const std::string &, const pugi::xml_node &, Scope &) | ||||||||||||||
-> syntax::Orientation; | ||||||||||||||
extern template auto readElement(const std::string &, const pugi::xml_node &, Scope &) | ||||||||||||||
-> syntax::Position; | ||||||||||||||
extern template auto readElement(const std::string &, const pugi::xml_node &, Scope &) | ||||||||||||||
-> syntax::Properties; | ||||||||||||||
extern template auto readElement(const std::string &, const pugi::xml_node &, Scope &) | ||||||||||||||
-> syntax::Range; | ||||||||||||||
|
||||||||||||||
template <typename T, typename U, typename Scope> | ||||||||||||||
auto readElement(const std::string & name, const pugi::xml_node & parent, Scope & scope, U && value) | ||||||||||||||
{ | ||||||||||||||
|
@@ -153,62 +173,9 @@ auto readGroups(const pugi::xml_node & node, Ts &&... xs) | |||||||||||||
return groups; | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
template <typename... Ts> | ||||||||||||||
auto choice(const pugi::xml_node & node, Ts &&... xs) -> decltype(auto) | ||||||||||||||
{ | ||||||||||||||
const std::unordered_map<std::string, std::function<Object(const pugi::xml_node &)>> callees{ | ||||||||||||||
std::forward<decltype(xs)>(xs)...}; | ||||||||||||||
|
||||||||||||||
std::unordered_map<std::string, pugi::xml_node> specs{}; | ||||||||||||||
|
||||||||||||||
for (const auto & each : callees) { | ||||||||||||||
if (const auto child = node.child(std::get<0>(each).c_str())) { | ||||||||||||||
specs.emplace(std::get<0>(each), child); | ||||||||||||||
} | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
auto print_keys_to = [&](auto & os, const auto & xs) -> decltype(auto) { | ||||||||||||||
if (not xs.empty()) { | ||||||||||||||
for (auto iter = std::begin(xs); iter != std::end(xs); ++iter) { | ||||||||||||||
os << std::get<0>(*iter); | ||||||||||||||
|
||||||||||||||
switch (std::distance(iter, std::end(xs))) { | ||||||||||||||
case 1: | ||||||||||||||
return os; | ||||||||||||||
|
||||||||||||||
case 2: | ||||||||||||||
os << " and "; | ||||||||||||||
break; | ||||||||||||||
|
||||||||||||||
default: | ||||||||||||||
os << ", "; | ||||||||||||||
break; | ||||||||||||||
} | ||||||||||||||
} | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
return os; | ||||||||||||||
}; | ||||||||||||||
|
||||||||||||||
if (specs.empty()) { | ||||||||||||||
std::stringstream what; | ||||||||||||||
what << "Class " << node.name() << " requires one of following elements: "; | ||||||||||||||
print_keys_to(what, callees); | ||||||||||||||
what << ". But no element specified"; | ||||||||||||||
throw SyntaxError(what.str()); | ||||||||||||||
} else if (1 < specs.size()) { | ||||||||||||||
std::stringstream what; | ||||||||||||||
what << "Class " << node.name() << " requires just one of following elements: "; | ||||||||||||||
print_keys_to(what, callees); | ||||||||||||||
what << ". But " << specs.size() << " element" << (1 < specs.size() ? "s" : "") << " ("; | ||||||||||||||
print_keys_to(what, specs); | ||||||||||||||
what << ") specified"; | ||||||||||||||
throw SyntaxError(what.str()); | ||||||||||||||
} else { | ||||||||||||||
const auto iter = std::cbegin(specs); | ||||||||||||||
return callees.at(std::get<0>(*iter))(std::get<1>(*iter)); | ||||||||||||||
} | ||||||||||||||
} | ||||||||||||||
auto choice( | ||||||||||||||
const pugi::xml_node & node, | ||||||||||||||
std::unordered_map<std::string, std::function<Object(const pugi::xml_node &)>> callees) -> Object; | ||||||||||||||
Comment on lines
+176
to
+178
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
} // namespace reader | ||||||||||||||
} // namespace openscenario_interpreter | ||||||||||||||
|
||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,99 @@ | ||||||
// Copyright 2015 TIER IV, Inc. All rights reserved. | ||||||
// | ||||||
// 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. | ||||||
|
||||||
#include <openscenario_interpreter/reader/attribute.hpp> | ||||||
#include <openscenario_interpreter/scope.hpp> | ||||||
#include <openscenario_interpreter/syntax/rule.hpp> | ||||||
|
||||||
namespace openscenario_interpreter | ||||||
{ | ||||||
inline namespace reader | ||||||
{ | ||||||
auto substitute(std::string attribute, const Scope & scope) -> String | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
{ | ||||||
auto dirname = [](auto &&, auto && scope) { return scope.dirname(); }; | ||||||
|
||||||
auto find_pkg_share = [](auto && package_name, const auto &) { | ||||||
return ament_index_cpp::get_package_share_directory(package_name); | ||||||
}; | ||||||
|
||||||
auto ros2 = [](auto && arguments, const auto &) { | ||||||
auto remove_trailing_newline = [](auto && s) { | ||||||
while (s.back() == '\n') { | ||||||
s.pop_back(); | ||||||
} | ||||||
return s; | ||||||
}; | ||||||
if (auto && result = remove_trailing_newline(concealer::dollar("ros2 " + arguments)); | ||||||
result.find('\n') != std::string::npos) { | ||||||
throw SyntaxError( | ||||||
"The substitution result by `$(ros2 ...)` must not contain a newline character. " | ||||||
"You gave `$(ros2 ", | ||||||
arguments, ")` and the result was ", | ||||||
std::quoted(boost::replace_all_copy(result, "\n", "\\n")), | ||||||
", which is unacceptable for the reasons stated above."); | ||||||
} else { | ||||||
return result; | ||||||
} | ||||||
}; | ||||||
|
||||||
auto var = [](auto && name, const auto & scope) { | ||||||
// TODO: Return the value of the launch configuration variable instead of the OpenSCENARIO parameter. | ||||||
if (const auto found = scope.ref(name); found) { | ||||||
return boost::lexical_cast<String>(found); | ||||||
} else { | ||||||
return String(); | ||||||
} | ||||||
}; | ||||||
|
||||||
// NOTE: https://design.ros2.org/articles/roslaunch_xml.html#dynamic-configuration | ||||||
static const std::unordered_map< | ||||||
std::string, std::function<std::string(const std::string &, const Scope &)> > | ||||||
substitutions{ | ||||||
{"dirname", dirname}, | ||||||
// TODO {"env", env}, | ||||||
// TODO {"eval", eval}, | ||||||
// TODO {"exec-in-package", exec_in_package}, | ||||||
// TODO {"find-exec", find_exec}, | ||||||
// TODO {"find-pkg-prefix", find_pkg_prefix}, | ||||||
{"find-pkg-share", find_pkg_share}, | ||||||
{"ros2", | ||||||
ros2}, // NOTE: TIER IV extension (Not included in the ROS 2 Launch XML Substitution) | ||||||
{"var", var}, | ||||||
}; | ||||||
|
||||||
static const auto pattern = std::regex(R"((.*)\$\((([\w-]+)\s?([^\)]*))\)(.*))"); | ||||||
|
||||||
for (std::smatch result; std::regex_match(attribute, result, pattern);) { | ||||||
if (const auto iter = substitutions.find(result.str(3)); iter != std::end(substitutions)) { | ||||||
attribute = result.str(1) + std::get<1>(*iter)(result.str(4), scope) + result.str(5); | ||||||
} else { | ||||||
throw SyntaxError("Unknown substitution ", std::quoted(result.str(3)), " specified"); | ||||||
} | ||||||
} | ||||||
|
||||||
return attribute; | ||||||
} | ||||||
|
||||||
template auto readAttribute(const std::string &, const pugi::xml_node &, const Scope &) -> Boolean; | ||||||
template auto readAttribute(const std::string &, const pugi::xml_node &, const Scope &) | ||||||
-> UnsignedShort; | ||||||
template auto readAttribute(const std::string &, const pugi::xml_node &, const Scope &) | ||||||
-> UnsignedInteger; | ||||||
template auto readAttribute(const std::string &, const pugi::xml_node &, const Scope &) -> Double; | ||||||
template auto readAttribute(const std::string &, const pugi::xml_node &, const Scope &) -> String; | ||||||
template auto readAttribute(const std::string &, const pugi::xml_node &, const Scope &) | ||||||
-> syntax::Rule; | ||||||
Comment on lines
+89
to
+97
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please sort in lexicographic order unless there is a technical reason not to. |
||||||
} // namespace reader | ||||||
} // namespace openscenario_interpreter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please sort in lexicographic order unless there is a technical reason not to.