Fix a performance bug that was preventing binding compression from working. E.g. with the 100 classes benchmark under Clang 4.0, this fix reduces the per-request injection time by 27%.
diff --git a/include/fruit/impl/component_functors.defn.h b/include/fruit/impl/component_functors.defn.h
index dbed564..25e1509 100644
--- a/include/fruit/impl/component_functors.defn.h
+++ b/include/fruit/impl/component_functors.defn.h
@@ -239,7 +239,7 @@
template <typename Comp, typename AnnotatedSignature, typename Lambda>
struct apply {
using AnnotatedC = NormalizeType(SignatureType(AnnotatedSignature));
- using OptionalAnnotatedI = FindInMap(typename Comp::InterfaceBindings, AnnotatedC);
+ using OptionalAnnotatedI = FindValueInMap(typename Comp::InterfaceBindings, AnnotatedC);
struct Op {
using Result = Comp;
void operator()(ComponentStorage& storage) {
@@ -469,7 +469,7 @@
void operator()(ComponentStorage& storage) {
PostProcessRegisterConstructorHelper<
UnwrapType<AnnotatedSignature>,
- Eval<FindInMap(typename Comp::InterfaceBindings, AnnotatedC)>
+ Eval<FindValueInMap(typename Comp::InterfaceBindings, AnnotatedC)>
>()(storage);
}
};
diff --git a/include/fruit/impl/meta/map.h b/include/fruit/impl/meta/map.h
index 4645cbb..c6f3b43 100644
--- a/include/fruit/impl/meta/map.h
+++ b/include/fruit/impl/meta/map.h
@@ -77,6 +77,27 @@
};
};
+// TODO: Consider implementing this by finding the position first, then calling VectorRemoveFirstN
+// and getting the first element.
+struct FindValueInMap {
+ template <typename TToFind>
+ struct Helper {
+ template <typename CurrentResult, typename T>
+ struct apply {
+ using type = CurrentResult;
+ };
+ template <typename CurrentResult, typename Value>
+ struct apply<CurrentResult, Pair<Value, TToFind>> {
+ using type = Value;
+ };
+ };
+
+ template <typename M, typename TToFind>
+ struct apply {
+ using type = FoldVector(M, Helper<TToFind>, None);
+ };
+};
+
} // namespace meta
} // namespace impl
} // namespace fruit
diff --git a/tests/test_binding_compression.py b/tests/test_binding_compression.py
index 7a27f1c..77c7d1c 100755
--- a/tests/test_binding_compression.py
+++ b/tests/test_binding_compression.py
@@ -60,6 +60,7 @@
Assert((injector.get<WithAnnot<const I* >>()->value == 5));
Assert((injector.get<WithAnnot<const I& >>() .value == 5));
Assert((injector.get<WithAnnot<std::shared_ptr<I>>>()->value == 5));
+ Assert(injector.unsafeGet<WithAnnot<X>>() == nullptr);
Assert(X::num_objects_constructed == 1);
}
@@ -97,6 +98,7 @@
Assert((injector.get<WithAnnot<const I* >>()->value == 5));
Assert((injector.get<WithAnnot<const I& >>() .value == 5));
Assert((injector.get<WithAnnot<std::shared_ptr<I>>>()->value == 5));
+ Assert(injector.unsafeGet<WithAnnot<X>>() == nullptr);
Assert(X::num_objects_constructed == 1);
}
'''
@@ -147,6 +149,7 @@
Assert(C1::num_objects_constructed == 0);
injector.get<I2*>();
injector.get<X*>();
+ Assert(injector.unsafeGet<C1>() != nullptr);
Assert(C1::num_objects_constructed == 1);
}
'''