Skip to content

Commit 044a69c

Browse files
authored
workaround bugs in clang and gcc to optimize compiled efficiency (#51)
resolves #50
1 parent 36ce015 commit 044a69c

File tree

1 file changed

+12
-26
lines changed

1 file changed

+12
-26
lines changed

include/cib/nexus.hpp

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -24,47 +24,33 @@ namespace cib {
2424
template<typename Config>
2525
struct nexus {
2626
private:
27-
template<typename T>
28-
using raw_service_t = decltype(initialized<Config, T>::value.template build<initialized<Config, T>>());
29-
30-
template<typename T>
31-
CIB_CONSTINIT static inline raw_service_t<T> raw_service =
32-
initialized<Config, T>::value.template build<initialized<Config, T>>();
27+
using this_t = nexus<Config>;
3328

3429
template<typename Tag>
3530
using service_name_to_raw_type_t =
3631
typename std::remove_const_t<std::remove_reference_t<decltype(cib::detail::find<Tag, cib::ServiceTagMetaFunc>(cib::initialized_builders_v<Config>))>>;
3732

38-
template<typename T>
39-
using service_t =
40-
decltype(initialized<Config, service_name_to_raw_type_t<T>>::value.template build<initialized<Config, service_name_to_raw_type_t<T>>>());
33+
// Workaround unfortunate bug in clang where it can't deduce "auto" sometimes
34+
#define CIB_BUILD_SERVICE initialized<Config, service_name_to_raw_type_t<T>>::value.template build<initialized<Config, service_name_to_raw_type_t<T>>>()
4135

4236
public:
4337
template<typename T>
44-
CIB_CONSTINIT static inline service_t<T> service =
45-
initialized<Config, service_name_to_raw_type_t<T>>::value.template build<initialized<Config, service_name_to_raw_type_t<T>>>();
38+
constexpr static decltype(CIB_BUILD_SERVICE) service = CIB_BUILD_SERVICE;
39+
#undef CIB_BUILD_SERVICE
4640

4741
static void init() {
4842
detail::for_each(initialized_builders_v<Config>, [](auto b){
49-
// Tag/CleanTag is the type name of the builder_meta in the ordered_set
50-
using Tag = typename decltype(b)::Service;
51-
using CleanTag = std::remove_cv_t<std::remove_reference_t<Tag>>;
52-
53-
using CleanTypename = std::remove_cv_t<std::remove_reference_t<decltype(b)>>;
43+
using service_tag = typename decltype(b)::Service;
44+
using clean_service_tag = std::remove_cv_t<std::remove_reference_t<service_tag>>;
5445

55-
// the built implementation is stored in Build<>::value
56-
auto & builtValue = raw_service<CleanTypename>;
57-
using BuiltType = std::remove_reference_t<decltype(builtValue)>;
46+
auto & service_impl = this_t::service<clean_service_tag>;
47+
using service_impl_type = std::remove_reference_t<decltype(service_impl)>;
5848

59-
// if the built type is a pointer, then it is a function pointer and we should return its value
60-
// directly to the 'built<>' abstract interface variable.
61-
if constexpr(std::is_pointer_v<BuiltType>) {
62-
cib::service<CleanTag> = builtValue;
49+
if constexpr(std::is_pointer_v<service_impl_type>) {
50+
cib::service<clean_service_tag> = service_impl;
6351

64-
// if the built type is not a pointer, then it is a class and the 'built<>' variable is a pointer to
65-
// the base class. we will need to get a pointer to the builtValue in order to initialize 'built<>'.
6652
} else {
67-
cib::service<CleanTag> = &builtValue;
53+
cib::service<clean_service_tag> = &service_impl;
6854
}
6955
});
7056
}

0 commit comments

Comments
 (0)