Add a .clang-format config file and reformat all C++ source code using that. Also added some documentation on the preferred style in CONTRIBUTING.md.
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..ad65d48
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,6 @@
+BasedOnStyle: LLVM
+Language: Cpp
+ColumnLimit: 120
+AllowShortFunctionsOnASingleLine: Empty
+AlwaysBreakTemplateDeclarations: true
+PointerAlignment: Left
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index f1dc344..336737e 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -220,3 +220,12 @@
Note that the "percentage of **functions** covered" metric is not meaningful for Fruit, since it considers each
instantiation of a template function/method as separate (even if they share the same source lines).
+
+## Code style
+
+C++ code in Fruit should be indented using clang-format (a `.clang-format` file is provided in the Fruit root
+directory). You can re-indent all code using this command:
+
+```bash
+$ clang-format -i $(git ls-files | egrep '\.cpp|\.h' )
+```
diff --git a/configuration/bazel/fruit/impl/fruit-config-base.h b/configuration/bazel/fruit/impl/fruit-config-base.h
index 4244489..8e7af1d 100644
--- a/configuration/bazel/fruit/impl/fruit-config-base.h
+++ b/configuration/bazel/fruit/impl/fruit-config-base.h
@@ -4,9 +4,9 @@
* 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.
diff --git a/configuration/fruit-config-base.h.in b/configuration/fruit-config-base.h.in
index 2efd81c..5554eea 100644
--- a/configuration/fruit-config-base.h.in
+++ b/configuration/fruit-config-base.h.in
@@ -4,9 +4,9 @@
* 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.
@@ -36,5 +36,4 @@
#cmakedefine FRUIT_HAS_MSVC_ASSUME 1
#cmakedefine FRUIT_HAS_BUILTIN_UNREACHABLE 1
-
#endif // FRUIT_CONFIG_BASE_H
diff --git a/examples/annotated_injection/brake.h b/examples/annotated_injection/brake.h
index 0eb7d9b..3cfaf52 100644
--- a/examples/annotated_injection/brake.h
+++ b/examples/annotated_injection/brake.h
@@ -4,9 +4,9 @@
* 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.
diff --git a/examples/annotated_injection/car.cpp b/examples/annotated_injection/car.cpp
index 53d4ce1..605a4de 100644
--- a/examples/annotated_injection/car.cpp
+++ b/examples/annotated_injection/car.cpp
@@ -4,9 +4,9 @@
* 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.
@@ -15,33 +15,31 @@
*/
#include "car.h"
-#include "main_brake.h"
#include "emergency_brake.h"
+#include "main_brake.h"
class CarImpl : public Car {
private:
- Brake* mainBrake;
- Brake* emergencyBrake;
-
+ Brake* mainBrake;
+ Brake* emergencyBrake;
+
public:
- INJECT(CarImpl(ANNOTATED(MainBrake, Brake*) mainBrake,
- ANNOTATED(EmergencyBrake, Brake*) emergencyBrake))
- : mainBrake(mainBrake), emergencyBrake(emergencyBrake) {
+ INJECT(CarImpl(ANNOTATED(MainBrake, Brake*) mainBrake, ANNOTATED(EmergencyBrake, Brake*) emergencyBrake))
+ : mainBrake(mainBrake), emergencyBrake(emergencyBrake) {}
+
+ void brake() override {
+ try {
+ mainBrake->activate();
+ } catch (...) {
+ // The main brake failed!
+ emergencyBrake->activate();
}
-
- void brake() override {
- try {
- mainBrake->activate();
- } catch (...) {
- // The main brake failed!
- emergencyBrake->activate();
- }
- }
+ }
};
fruit::Component<Car> getCarComponent() {
- return fruit::createComponent()
- .bind<Car, CarImpl>()
- .install(getMainBrakeComponent)
- .install(getEmergencyBrakeComponent);
+ return fruit::createComponent()
+ .bind<Car, CarImpl>()
+ .install(getMainBrakeComponent)
+ .install(getEmergencyBrakeComponent);
}
diff --git a/examples/annotated_injection/car.h b/examples/annotated_injection/car.h
index 45a9662..4b25043 100644
--- a/examples/annotated_injection/car.h
+++ b/examples/annotated_injection/car.h
@@ -4,9 +4,9 @@
* 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.
diff --git a/examples/annotated_injection/emergency_brake.cpp b/examples/annotated_injection/emergency_brake.cpp
index 8fe69aa..f78a67f 100644
--- a/examples/annotated_injection/emergency_brake.cpp
+++ b/examples/annotated_injection/emergency_brake.cpp
@@ -4,9 +4,9 @@
* 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.
@@ -19,13 +19,12 @@
class EmergencyBrakeImpl : public Brake {
public:
INJECT(EmergencyBrakeImpl()) = default;
-
+
void activate() override {
// ...
}
};
fruit::Component<fruit::Annotated<EmergencyBrake, Brake>> getEmergencyBrakeComponent() {
- return fruit::createComponent()
- .bind<fruit::Annotated<EmergencyBrake, Brake>, EmergencyBrakeImpl>();
+ return fruit::createComponent().bind<fruit::Annotated<EmergencyBrake, Brake>, EmergencyBrakeImpl>();
}
diff --git a/examples/annotated_injection/emergency_brake.h b/examples/annotated_injection/emergency_brake.h
index 335d9f1..c5650b4 100644
--- a/examples/annotated_injection/emergency_brake.h
+++ b/examples/annotated_injection/emergency_brake.h
@@ -4,9 +4,9 @@
* 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.
diff --git a/examples/annotated_injection/main.cpp b/examples/annotated_injection/main.cpp
index 92e8d15..f054717 100644
--- a/examples/annotated_injection/main.cpp
+++ b/examples/annotated_injection/main.cpp
@@ -4,9 +4,9 @@
* 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.
@@ -21,8 +21,8 @@
int main() {
Injector<Car> injector(getCarComponent);
Car* car(injector);
-
+
car->brake();
-
+
return 0;
}
diff --git a/examples/annotated_injection/main_brake.cpp b/examples/annotated_injection/main_brake.cpp
index 9383305..722368c 100644
--- a/examples/annotated_injection/main_brake.cpp
+++ b/examples/annotated_injection/main_brake.cpp
@@ -4,9 +4,9 @@
* 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.
@@ -18,14 +18,13 @@
class MainBrakeImpl : public Brake {
public:
- INJECT(MainBrakeImpl()) = default;
-
- void activate() override {
- // ...
- }
+ INJECT(MainBrakeImpl()) = default;
+
+ void activate() override {
+ // ...
+ }
};
fruit::Component<fruit::Annotated<MainBrake, Brake>> getMainBrakeComponent() {
- return fruit::createComponent()
- .bind<fruit::Annotated<MainBrake, Brake>, MainBrakeImpl>();
+ return fruit::createComponent().bind<fruit::Annotated<MainBrake, Brake>, MainBrakeImpl>();
}
diff --git a/examples/annotated_injection/main_brake.h b/examples/annotated_injection/main_brake.h
index 6b96f10..34730e9 100644
--- a/examples/annotated_injection/main_brake.h
+++ b/examples/annotated_injection/main_brake.h
@@ -4,9 +4,9 @@
* 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.
diff --git a/examples/hello_world/main.cpp b/examples/hello_world/main.cpp
index 5136f5d..4364993 100644
--- a/examples/hello_world/main.cpp
+++ b/examples/hello_world/main.cpp
@@ -15,7 +15,7 @@
// Like "StdoutWriter() = default;" but also marks this constructor as the
// one to use for injection.
INJECT(StdoutWriter()) = default;
-
+
virtual void write(std::string s) override {
std::cout << s;
}
@@ -33,27 +33,23 @@
public:
// Like "GreeterImpl(Writer* writer) {...}" but also marks this constructor
// as the one to use for injection.
- INJECT(GreeterImpl(Writer* writer))
- : writer(writer) {
- }
-
+ INJECT(GreeterImpl(Writer* writer)) : writer(writer) {}
+
virtual void greet() override {
writer->write("Hello world!\n");
}
};
Component<Greeter> getGreeterComponent() {
- return fruit::createComponent()
- .bind<Writer, StdoutWriter>()
- .bind<Greeter, GreeterImpl>();
+ return fruit::createComponent().bind<Writer, StdoutWriter>().bind<Greeter, GreeterImpl>();
}
int main() {
Injector<Greeter> injector(getGreeterComponent);
Greeter* greeter = injector.get<Greeter*>();
-
+
greeter->greet();
-
+
return 0;
}
diff --git a/examples/multibindings/main.cpp b/examples/multibindings/main.cpp
index f672673..bc34240 100644
--- a/examples/multibindings/main.cpp
+++ b/examples/multibindings/main.cpp
@@ -4,9 +4,9 @@
* 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.
@@ -28,7 +28,7 @@
class Listener1 : public Listener {
public:
INJECT(Listener1()) = default;
-
+
void notify() override {
std::cout << "Listener 1 notified" << std::endl;
}
@@ -43,7 +43,7 @@
class StdoutWriter : public Writer {
public:
INJECT(StdoutWriter()) = default;
-
+
void write(std::string s) override {
std::cout << s << std::endl;
}
@@ -52,19 +52,18 @@
class Listener2 : public Listener {
private:
Writer* writer;
-
+
public:
- INJECT(Listener2(Writer* writer))
- : writer(writer) {
- }
-
+ INJECT(Listener2(Writer* writer)) : writer(writer) {}
+
void notify() override {
writer->write("Listener 2 notified");
}
};
Component<> getListenersComponent() {
- // Here they are in the same component to keep it simple, but Fruit collects all multibindings in installed components.
+ // Here they are in the same component to keep it simple, but Fruit collects all multibindings in installed
+ // components.
return fruit::createComponent()
.bind<Writer, StdoutWriter>()
.addMultibinding<Listener, Listener1>()
@@ -74,11 +73,11 @@
int main() {
Injector<> injector(getListenersComponent);
std::vector<Listener*> listeners = injector.getMultibindings<Listener>();
-
+
// The order of the returned listeners is unspecified, so the lines in output may have any order.
for (Listener* listener : listeners) {
listener->notify();
}
-
+
return 0;
}
diff --git a/examples/scaling_doubles/main.cpp b/examples/scaling_doubles/main.cpp
index c26e152..d4d733a 100644
--- a/examples/scaling_doubles/main.cpp
+++ b/examples/scaling_doubles/main.cpp
@@ -4,9 +4,9 @@
* 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.
@@ -23,9 +23,9 @@
int main() {
Injector<ScalerFactory> injector(getScalerComponent);
ScalerFactory scalerFactory(injector);
-
+
std::unique_ptr<Scaler> scaler = scalerFactory(12.1);
std::cout << scaler->scale(3) << std::endl;
-
+
return 0;
}
diff --git a/examples/scaling_doubles/multiplier.cpp b/examples/scaling_doubles/multiplier.cpp
index 24b2d2a..be0d349 100644
--- a/examples/scaling_doubles/multiplier.cpp
+++ b/examples/scaling_doubles/multiplier.cpp
@@ -4,9 +4,9 @@
* 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.
@@ -24,7 +24,5 @@
};
fruit::Component<Multiplier> getMultiplierComponent() {
- return fruit::createComponent()
- .bind<Multiplier, MultiplierImpl>()
- .registerConstructor<MultiplierImpl()>();
+ return fruit::createComponent().bind<Multiplier, MultiplierImpl>().registerConstructor<MultiplierImpl()>();
}
diff --git a/examples/scaling_doubles/multiplier.h b/examples/scaling_doubles/multiplier.h
index 9baeb28..ae22c3d 100644
--- a/examples/scaling_doubles/multiplier.h
+++ b/examples/scaling_doubles/multiplier.h
@@ -4,9 +4,9 @@
* 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.
diff --git a/examples/scaling_doubles/scaler.cpp b/examples/scaling_doubles/scaler.cpp
index da27794..32838bd 100644
--- a/examples/scaling_doubles/scaler.cpp
+++ b/examples/scaling_doubles/scaler.cpp
@@ -4,9 +4,9 @@
* 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.
@@ -25,20 +25,15 @@
private:
Multiplier* multiplier;
double factor;
-
+
public:
- INJECT(ScalerImpl(ASSISTED(double) factor, Multiplier* multiplier))
- : multiplier(multiplier), factor(factor) {
- }
-
+ INJECT(ScalerImpl(ASSISTED(double) factor, Multiplier* multiplier)) : multiplier(multiplier), factor(factor) {}
+
double scale(double x) override {
return multiplier->multiply(x, factor);
}
};
-
Component<ScalerFactory> getScalerComponent() {
- return createComponent()
- .bind<Scaler, ScalerImpl>()
- .install(getMultiplierComponent);
+ return createComponent().bind<Scaler, ScalerImpl>().install(getMultiplierComponent);
}
diff --git a/examples/scaling_doubles/scaler.h b/examples/scaling_doubles/scaler.h
index 58fa48c..9011e81 100644
--- a/examples/scaling_doubles/scaler.h
+++ b/examples/scaling_doubles/scaler.h
@@ -4,9 +4,9 @@
* 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.
diff --git a/examples/server/bar_handler.cpp b/examples/server/bar_handler.cpp
index 0644492..c70b9cc 100644
--- a/examples/server/bar_handler.cpp
+++ b/examples/server/bar_handler.cpp
@@ -4,9 +4,9 @@
* 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.
@@ -25,19 +25,17 @@
private:
const Request& request;
const ServerContext& serverContext;
-
+
public:
INJECT(BarHandlerImpl(const Request& request, const ServerContext& serverContext))
- : request(request), serverContext(serverContext) {
- }
-
+ : request(request), serverContext(serverContext) {}
+
void handleRequest() override {
- cout << "BarHandler handling request on server started at " << serverContext.startupTime << " for path: " << request.path << endl;
+ cout << "BarHandler handling request on server started at " << serverContext.startupTime
+ << " for path: " << request.path << endl;
}
};
Component<Required<Request, ServerContext>, BarHandler> getBarHandlerComponent() {
- return fruit::createComponent()
- .bind<BarHandler, BarHandlerImpl>();
+ return fruit::createComponent().bind<BarHandler, BarHandlerImpl>();
}
-
diff --git a/examples/server/bar_handler.h b/examples/server/bar_handler.h
index e86ec58..475d8f5 100644
--- a/examples/server/bar_handler.h
+++ b/examples/server/bar_handler.h
@@ -4,9 +4,9 @@
* 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.
diff --git a/examples/server/foo_handler.cpp b/examples/server/foo_handler.cpp
index e2aabb3..db1261c 100644
--- a/examples/server/foo_handler.cpp
+++ b/examples/server/foo_handler.cpp
@@ -4,9 +4,9 @@
* 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.
@@ -25,19 +25,17 @@
private:
const Request& request;
const ServerContext& serverContext;
-
+
public:
INJECT(FooHandlerImpl(const Request& request, const ServerContext& serverContext))
- : request(request), serverContext(serverContext) {
- }
-
+ : request(request), serverContext(serverContext) {}
+
void handleRequest() override {
- cout << "FooHandler handling request on server started at " << serverContext.startupTime << " for path: " << request.path << endl;
+ cout << "FooHandler handling request on server started at " << serverContext.startupTime
+ << " for path: " << request.path << endl;
}
};
Component<Required<Request, ServerContext>, FooHandler> getFooHandlerComponent() {
- return fruit::createComponent()
- .bind<FooHandler, FooHandlerImpl>();
+ return fruit::createComponent().bind<FooHandler, FooHandlerImpl>();
}
-
diff --git a/examples/server/foo_handler.h b/examples/server/foo_handler.h
index 6d85bdd..02d21ee 100644
--- a/examples/server/foo_handler.h
+++ b/examples/server/foo_handler.h
@@ -4,9 +4,9 @@
* 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.
diff --git a/examples/server/main.cpp b/examples/server/main.cpp
index ba84b18..a1804e6 100644
--- a/examples/server/main.cpp
+++ b/examples/server/main.cpp
@@ -4,9 +4,9 @@
* 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.
@@ -16,16 +16,16 @@
#include <fruit/fruit.h>
-#include "server.h"
#include "request_dispatcher.h"
+#include "server.h"
using namespace fruit;
int main() {
Injector<Server> injector(getServerComponent);
-
+
Server* server(injector);
server->run(getRequestDispatcherComponent);
-
+
return 0;
}
diff --git a/examples/server/request.h b/examples/server/request.h
index 6fa8eb1..b09cf93 100644
--- a/examples/server/request.h
+++ b/examples/server/request.h
@@ -4,9 +4,9 @@
* 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.
diff --git a/examples/server/request_dispatcher.cpp b/examples/server/request_dispatcher.cpp
index 2901a3b..f63ca0b 100644
--- a/examples/server/request_dispatcher.cpp
+++ b/examples/server/request_dispatcher.cpp
@@ -4,9 +4,9 @@
* 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.
@@ -16,8 +16,8 @@
#include "request_dispatcher.h"
-#include "foo_handler.h"
#include "bar_handler.h"
+#include "foo_handler.h"
#include <iostream>
@@ -27,21 +27,18 @@
class RequestDispatcherImpl : public RequestDispatcher {
private:
const Request& request;
- // We hold providers here for lazy injection; we only want to inject the handler that is actually used for the request.
- // In a large system, there will be many handlers, and many will have lots of dependencies that also have to be injected.
+ // We hold providers here for lazy injection; we only want to inject the handler that is actually used for the
+ // request.
+ // In a large system, there will be many handlers, and many will have lots of dependencies that also have to be
+ // injected.
Provider<FooHandler> fooHandler;
Provider<BarHandler> barHandler;
-
+
public:
- INJECT(RequestDispatcherImpl(
- const Request& request,
- Provider<FooHandler> fooHandler,
- Provider<BarHandler> barHandler))
- : request(request),
- fooHandler(fooHandler),
- barHandler(barHandler) {
- }
-
+ INJECT(RequestDispatcherImpl(const Request& request, Provider<FooHandler> fooHandler,
+ Provider<BarHandler> barHandler))
+ : request(request), fooHandler(fooHandler), barHandler(barHandler) {}
+
void handleRequest() override {
if (stringStartsWith(request.path, "/foo/")) {
fooHandler.get()->handleRequest();
@@ -51,16 +48,16 @@
cerr << "Error: no handler found for request path: '" << request.path << "' , ignoring request." << endl;
}
}
-
+
private:
static bool stringStartsWith(const string& s, const string& candidatePrefix) {
return s.compare(0, candidatePrefix.size(), candidatePrefix) == 0;
- }
+ }
};
Component<Required<Request, ServerContext>, RequestDispatcher> getRequestDispatcherComponent() {
return createComponent()
- .bind<RequestDispatcher, RequestDispatcherImpl>()
- .install(getFooHandlerComponent)
- .install(getBarHandlerComponent);
+ .bind<RequestDispatcher, RequestDispatcherImpl>()
+ .install(getFooHandlerComponent)
+ .install(getBarHandlerComponent);
}
diff --git a/examples/server/request_dispatcher.h b/examples/server/request_dispatcher.h
index 7cb0214..5580ce1 100644
--- a/examples/server/request_dispatcher.h
+++ b/examples/server/request_dispatcher.h
@@ -4,9 +4,9 @@
* 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.
diff --git a/examples/server/server.cpp b/examples/server/server.cpp
index 6da7a83..60e6853 100644
--- a/examples/server/server.cpp
+++ b/examples/server/server.cpp
@@ -4,9 +4,9 @@
* 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.
@@ -17,8 +17,8 @@
#include "server.h"
#include <ctime>
-#include <thread>
#include <iostream>
+#include <thread>
using namespace std;
using namespace fruit;
@@ -26,31 +26,29 @@
class ServerImpl : public Server {
private:
std::vector<std::thread> threads;
-
+
public:
- INJECT(ServerImpl()) {
- }
-
+ INJECT(ServerImpl()) {}
+
~ServerImpl() {
for (std::thread& t : threads) {
t.join();
}
}
- void run(Component<Required<Request, ServerContext>, RequestDispatcher>(*getRequestDispatcherComponent)()) override {
+ void run(Component<Required<Request, ServerContext>, RequestDispatcher> (*getRequestDispatcherComponent)()) override {
ServerContext serverContext;
serverContext.startupTime = getTime();
-
+
const NormalizedComponent<Required<Request>, RequestDispatcher> requestDispatcherNormalizedComponent(
- getRequestDispatcherComponentWithContext,
- getRequestDispatcherComponent,
- &serverContext);
-
+ getRequestDispatcherComponentWithContext, getRequestDispatcherComponent, &serverContext);
+
cerr << "Server started." << endl;
-
+
while (1) {
cerr << endl;
- cerr << "Enter the request (absolute path starting with \"/foo/\" or \"/bar/\"), or an empty line to exit." << endl;
+ cerr << "Enter the request (absolute path starting with \"/foo/\" or \"/bar/\"), or an empty line to exit."
+ << endl;
Request request;
getline(cin, request.path);
cerr << "Server received request: " + request.path << endl;
@@ -58,22 +56,23 @@
cerr << "Server received empty line, shutting down." << endl;
break;
}
-
+
// In production code we would use a thread pool.
// Here we spawn a new thread each time to keep it simple.
threads.push_back(std::thread(worker_thread_main, std::ref(requestDispatcherNormalizedComponent), request));
}
}
-
+
private:
- static void worker_thread_main(const NormalizedComponent<Required<Request>, RequestDispatcher>& requestDispatcherNormalizedComponent,
- Request request) {
+ static void worker_thread_main(
+ const NormalizedComponent<Required<Request>, RequestDispatcher>& requestDispatcherNormalizedComponent,
+ Request request) {
Injector<RequestDispatcher> injector(requestDispatcherNormalizedComponent, getRequestComponent, &request);
-
+
RequestDispatcher* requestDispatcher(injector);
requestDispatcher->handleRequest();
}
-
+
static string getTime() {
time_t now = time(nullptr);
tm* localTime = localtime(&now);
@@ -83,22 +82,18 @@
}
return result;
}
-
+
static Component<Request> getRequestComponent(Request* request) {
- return createComponent()
- .bindInstance(*request);
+ return createComponent().bindInstance(*request);
}
static Component<Required<Request>, RequestDispatcher> getRequestDispatcherComponentWithContext(
- Component<Required<Request, ServerContext>, RequestDispatcher>(*getRequestDispatcherComponent)(),
+ Component<Required<Request, ServerContext>, RequestDispatcher> (*getRequestDispatcherComponent)(),
ServerContext* serverContext) {
- return createComponent()
- .install(getRequestDispatcherComponent)
- .bindInstance(*serverContext);
+ return createComponent().install(getRequestDispatcherComponent).bindInstance(*serverContext);
}
};
fruit::Component<Server> getServerComponent() {
- return fruit::createComponent()
- .bind<Server, ServerImpl>();
+ return fruit::createComponent().bind<Server, ServerImpl>();
}
diff --git a/examples/server/server.h b/examples/server/server.h
index be3ae2b..b97c55c 100644
--- a/examples/server/server.h
+++ b/examples/server/server.h
@@ -4,9 +4,9 @@
* 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.
@@ -18,15 +18,16 @@
#define SERVER_H
#include "request.h"
-#include "server_context.h"
#include "request_dispatcher.h"
+#include "server_context.h"
#include <fruit/fruit.h>
#include <string>
class Server {
public:
- virtual void run(fruit::Component<fruit::Required<Request, ServerContext>, RequestDispatcher>(*getrequestDispatcherComponent)()) = 0;
+ virtual void run(fruit::Component<fruit::Required<Request, ServerContext>, RequestDispatcher> (
+ *getrequestDispatcherComponent)()) = 0;
};
fruit::Component<Server> getServerComponent();
diff --git a/examples/server/server_context.h b/examples/server/server_context.h
index 1560e1d..3da38dc 100644
--- a/examples/server/server_context.h
+++ b/examples/server/server_context.h
@@ -4,9 +4,9 @@
* 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.
diff --git a/examples/simple_injection/adder.h b/examples/simple_injection/adder.h
index dae3488..111c5da 100644
--- a/examples/simple_injection/adder.h
+++ b/examples/simple_injection/adder.h
@@ -4,9 +4,9 @@
* 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.
diff --git a/examples/simple_injection/checked_adder.cpp b/examples/simple_injection/checked_adder.cpp
index ff50d56..7ca6754 100644
--- a/examples/simple_injection/checked_adder.cpp
+++ b/examples/simple_injection/checked_adder.cpp
@@ -4,9 +4,9 @@
* 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.
@@ -16,8 +16,8 @@
#include "checked_adder.h"
-#include <iostream>
#include <climits>
+#include <iostream>
class CheckedAdder : public Adder {
private:
@@ -25,8 +25,8 @@
if (y > x)
std::swap(x, y);
// Now y <= x.
- const int half_max = INT_MAX/2;
- const int half_min = INT_MIN/2;
+ const int half_max = INT_MAX / 2;
+ const int half_min = INT_MIN / 2;
if (x > half_max) {
// We can't have negative overflow, but might have positive overflow.
if (y > half_max)
@@ -57,10 +57,10 @@
// Neither negative nor positive overflow.
return false;
}
-
+
public:
INJECT(CheckedAdder()) = default;
-
+
virtual int add(int x, int y) override {
if (add_overflows(x, y)) {
std::cerr << "CheckedAdder: detected overflow during addition of " << x << " and " << y << std::endl;
@@ -71,6 +71,5 @@
};
fruit::Component<Adder> getCheckedAdderComponent() {
- return fruit::createComponent()
- .bind<Adder, CheckedAdder>();
+ return fruit::createComponent().bind<Adder, CheckedAdder>();
}
diff --git a/examples/simple_injection/checked_adder.h b/examples/simple_injection/checked_adder.h
index c18ed0b..e3d9cc3 100644
--- a/examples/simple_injection/checked_adder.h
+++ b/examples/simple_injection/checked_adder.h
@@ -4,9 +4,9 @@
* 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.
@@ -17,8 +17,8 @@
#ifndef CHECKED_ADDER_H
#define CHECKED_ADDER_H
-#include <fruit/fruit.h>
#include "adder.h"
+#include <fruit/fruit.h>
fruit::Component<Adder> getCheckedAdderComponent();
diff --git a/examples/simple_injection/checked_incrementer.cpp b/examples/simple_injection/checked_incrementer.cpp
index 7f27a35..2ba166f 100644
--- a/examples/simple_injection/checked_incrementer.cpp
+++ b/examples/simple_injection/checked_incrementer.cpp
@@ -4,9 +4,9 @@
* 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.
@@ -16,11 +16,9 @@
#include "checked_incrementer.h"
-#include "incrementer_impl.h"
#include "checked_adder.h"
+#include "incrementer_impl.h"
fruit::Component<Incrementer> getCheckedIncrementerComponent() {
- return fruit::createComponent()
- .install(getIncrementerImplComponent)
- .install(getCheckedAdderComponent);
+ return fruit::createComponent().install(getIncrementerImplComponent).install(getCheckedAdderComponent);
}
diff --git a/examples/simple_injection/checked_incrementer.h b/examples/simple_injection/checked_incrementer.h
index 3efccdd..0394a1f 100644
--- a/examples/simple_injection/checked_incrementer.h
+++ b/examples/simple_injection/checked_incrementer.h
@@ -4,9 +4,9 @@
* 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.
@@ -17,8 +17,8 @@
#ifndef CHECKED_INCREMENTER_H
#define CHECKED_INCREMENTER_H
-#include <fruit/fruit.h>
#include "incrementer.h"
+#include <fruit/fruit.h>
fruit::Component<Incrementer> getCheckedIncrementerComponent();
diff --git a/examples/simple_injection/incrementer.h b/examples/simple_injection/incrementer.h
index ac05cdd..373d28c 100644
--- a/examples/simple_injection/incrementer.h
+++ b/examples/simple_injection/incrementer.h
@@ -4,9 +4,9 @@
* 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.
diff --git a/examples/simple_injection/incrementer_component.cpp b/examples/simple_injection/incrementer_component.cpp
index 603f3fb..534ee81 100644
--- a/examples/simple_injection/incrementer_component.cpp
+++ b/examples/simple_injection/incrementer_component.cpp
@@ -4,9 +4,9 @@
* 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.
@@ -16,8 +16,8 @@
#include "incrementer_component.h"
-#include "simple_incrementer.h"
#include "checked_incrementer.h"
+#include "simple_incrementer.h"
fruit::Component<Incrementer> getIncrementerComponent(bool checked) {
if (checked)
diff --git a/examples/simple_injection/incrementer_component.h b/examples/simple_injection/incrementer_component.h
index be1741d..8d25212 100644
--- a/examples/simple_injection/incrementer_component.h
+++ b/examples/simple_injection/incrementer_component.h
@@ -4,9 +4,9 @@
* 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.
diff --git a/examples/simple_injection/incrementer_impl.cpp b/examples/simple_injection/incrementer_impl.cpp
index 712a525..fb2bf2b 100644
--- a/examples/simple_injection/incrementer_impl.cpp
+++ b/examples/simple_injection/incrementer_impl.cpp
@@ -4,9 +4,9 @@
* 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.
@@ -19,18 +19,15 @@
class IncrementerImpl : public Incrementer {
private:
Adder* adder;
-
+
public:
- INJECT(IncrementerImpl(Adder* adder))
- : adder(adder) {
- }
-
+ INJECT(IncrementerImpl(Adder* adder)) : adder(adder) {}
+
virtual int increment(int x) override {
return adder->add(x, 1);
}
};
fruit::Component<fruit::Required<Adder>, Incrementer> getIncrementerImplComponent() {
- return fruit::createComponent()
- .bind<Incrementer, IncrementerImpl>();
+ return fruit::createComponent().bind<Incrementer, IncrementerImpl>();
}
diff --git a/examples/simple_injection/incrementer_impl.h b/examples/simple_injection/incrementer_impl.h
index 71ee82d..1e4df49 100644
--- a/examples/simple_injection/incrementer_impl.h
+++ b/examples/simple_injection/incrementer_impl.h
@@ -4,9 +4,9 @@
* 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.
@@ -17,9 +17,9 @@
#ifndef INCREMENTER_IMPL_H
#define INCREMENTER_IMPL_H
-#include <fruit/fruit.h>
-#include "incrementer.h"
#include "adder.h"
+#include "incrementer.h"
+#include <fruit/fruit.h>
fruit::Component<fruit::Required<Adder>, Incrementer> getIncrementerImplComponent();
diff --git a/examples/simple_injection/main.cpp b/examples/simple_injection/main.cpp
index 0fa305a..f97793e 100644
--- a/examples/simple_injection/main.cpp
+++ b/examples/simple_injection/main.cpp
@@ -4,9 +4,9 @@
* 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.
@@ -25,18 +25,18 @@
// echo 2147483647 | ./incrementer
// echo 2147483647 | ./incrementer --checked
int main(int argc, const char* argv[]) {
-
+
bool checked = false;
-
+
if (argc == 2 && std::string(argv[1]) == "--checked")
checked = true;
-
+
Injector<Incrementer> injector(getIncrementerComponent, checked);
Incrementer* incrementer(injector);
-
+
int x;
std::cin >> x;
std::cout << incrementer->increment(x) << std::endl;
-
+
return 0;
}
diff --git a/examples/simple_injection/main_v1.cpp b/examples/simple_injection/main_v1.cpp
index f887dd0..ddcd5a0 100644
--- a/examples/simple_injection/main_v1.cpp
+++ b/examples/simple_injection/main_v1.cpp
@@ -4,9 +4,9 @@
* 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.
@@ -24,13 +24,13 @@
// echo 5 | ./incrementer
// echo 2147483647 | ./incrementer
int main() {
-
+
Injector<Incrementer> injector(getSimpleIncrementerComponent);
Incrementer* incrementer = injector.get<Incrementer*>();
-
+
int x;
std::cin >> x;
std::cout << incrementer->increment(x) << std::endl;
-
+
return 0;
}
diff --git a/examples/simple_injection/simple_adder.cpp b/examples/simple_injection/simple_adder.cpp
index 5cc4d9f..8277d23 100644
--- a/examples/simple_injection/simple_adder.cpp
+++ b/examples/simple_injection/simple_adder.cpp
@@ -4,9 +4,9 @@
* 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.
@@ -19,13 +19,12 @@
class SimpleAdder : public Adder {
public:
INJECT(SimpleAdder()) = default;
-
+
virtual int add(int x, int y) override {
return x + y;
}
};
fruit::Component<Adder> getSimpleAdderComponent() {
- return fruit::createComponent()
- .bind<Adder, SimpleAdder>();
+ return fruit::createComponent().bind<Adder, SimpleAdder>();
}
diff --git a/examples/simple_injection/simple_adder.h b/examples/simple_injection/simple_adder.h
index 564b8f0..9b75a79 100644
--- a/examples/simple_injection/simple_adder.h
+++ b/examples/simple_injection/simple_adder.h
@@ -4,9 +4,9 @@
* 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.
@@ -17,8 +17,8 @@
#ifndef SIMPLE_ADDER_H
#define SIMPLE_ADDER_H
-#include <fruit/fruit.h>
#include "adder.h"
+#include <fruit/fruit.h>
fruit::Component<Adder> getSimpleAdderComponent();
diff --git a/examples/simple_injection/simple_incrementer.cpp b/examples/simple_injection/simple_incrementer.cpp
index 9a0b869..2ecf4a2 100644
--- a/examples/simple_injection/simple_incrementer.cpp
+++ b/examples/simple_injection/simple_incrementer.cpp
@@ -4,9 +4,9 @@
* 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.
@@ -20,7 +20,5 @@
#include "simple_adder.h"
fruit::Component<Incrementer> getSimpleIncrementerComponent() {
- return fruit::createComponent()
- .install(getIncrementerImplComponent)
- .install(getSimpleAdderComponent);
+ return fruit::createComponent().install(getIncrementerImplComponent).install(getSimpleAdderComponent);
}
diff --git a/examples/simple_injection/simple_incrementer.h b/examples/simple_injection/simple_incrementer.h
index 6ff18ce..ac6e3a7 100644
--- a/examples/simple_injection/simple_incrementer.h
+++ b/examples/simple_injection/simple_incrementer.h
@@ -4,9 +4,9 @@
* 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.
@@ -17,8 +17,8 @@
#ifndef SIMPLE_INCREMENTER_H
#define SIMPLE_INCREMENTER_H
-#include <fruit/fruit.h>
#include "incrementer.h"
+#include <fruit/fruit.h>
fruit::Component<Incrementer> getSimpleIncrementerComponent();
diff --git a/extras/benchmark/compile_time_benchmark.cpp b/extras/benchmark/compile_time_benchmark.cpp
index ae27aa1..ddc6fd3 100644
--- a/extras/benchmark/compile_time_benchmark.cpp
+++ b/extras/benchmark/compile_time_benchmark.cpp
@@ -4,9 +4,9 @@
* 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.
@@ -60,99 +60,72 @@
#define EVAL2(...) EVAL1(EVAL1(EVAL1(EVAL1(__VA_ARGS__))))
#define EVAL(...) EVAL2(EVAL2(EVAL2(EVAL2(__VA_ARGS__))))
-#define META_REPEAT_2(R, X, I) \
-R PLACEHOLDER(X, I##0) \
-R PLACEHOLDER(X, I##1)
+#define META_REPEAT_2(R, X, I) R PLACEHOLDER(X, I##0) R PLACEHOLDER(X, I##1)
-#define REPEAT_1(X, I) \
-X(I)
+#define REPEAT_1(X, I) X(I)
-#define REPEAT_2(X, I) \
-META_REPEAT_2(REPEAT_1, X, I)
+#define REPEAT_2(X, I) META_REPEAT_2(REPEAT_1, X, I)
-#define REPEAT_4(X, I) \
-META_REPEAT_2(REPEAT_2, X, I)
+#define REPEAT_4(X, I) META_REPEAT_2(REPEAT_2, X, I)
-#define REPEAT_8(X, I) \
-META_REPEAT_2(REPEAT_4, X, I)
+#define REPEAT_8(X, I) META_REPEAT_2(REPEAT_4, X, I)
-#define REPEAT_16(X, I) \
-META_REPEAT_2(REPEAT_8, X, I)
+#define REPEAT_16(X, I) META_REPEAT_2(REPEAT_8, X, I)
-#define REPEAT_32(X, I) \
-META_REPEAT_2(REPEAT_16, X, I)
+#define REPEAT_32(X, I) META_REPEAT_2(REPEAT_16, X, I)
-#define REPEAT_64(X, I) \
-META_REPEAT_2(REPEAT_32, X, I)
+#define REPEAT_64(X, I) META_REPEAT_2(REPEAT_32, X, I)
-#define REPEAT_128(X, I) \
-META_REPEAT_2(REPEAT_64, X, I)
+#define REPEAT_128(X, I) META_REPEAT_2(REPEAT_64, X, I)
-#define REPEAT_256(X, I) \
-META_REPEAT_2(REPEAT_128, X, I)
+#define REPEAT_256(X, I) META_REPEAT_2(REPEAT_128, X, I)
-#define REPEAT_512(X, I) \
-META_REPEAT_2(REPEAT_256, X, I)
+#define REPEAT_512(X, I) META_REPEAT_2(REPEAT_256, X, I)
-#define REPEAT_1024(X, I) \
-META_REPEAT_2(REPEAT_512, X, I)
+#define REPEAT_1024(X, I) META_REPEAT_2(REPEAT_512, X, I)
using namespace fruit;
-#define DEFINITIONS(N) \
-struct A##N { \
- INJECT(A##N()) = default; \
-}; \
- \
-struct B##N { \
-}; \
- \
-struct C##N { \
-}; \
- \
-struct I##N { \
- virtual void f() = 0; \
-}; \
- \
-struct X##N : public I##N { \
- INJECT(X##N(A##N, B##N*, const C##N&)) {}; \
- \
- virtual void f(); \
-}; \
- \
-struct Y##N { \
-}; \
- \
-struct Z##N { \
-}; \
- \
-Component<Required<Y##N>, Z##N> getZ##N##Component(); \
+#define DEFINITIONS(N) \
+ struct A##N { \
+ INJECT(A##N()) = default; \
+ }; \
+ \
+ struct B##N {}; \
+ \
+ struct C##N {}; \
+ \
+ struct I##N { \
+ virtual void f() = 0; \
+ }; \
+ \
+ struct X##N : public I##N { \
+ INJECT(X##N(A##N, B##N*, const C##N&)){}; \
+ \
+ virtual void f(); \
+ }; \
+ \
+ struct Y##N {}; \
+ \
+ struct Z##N {}; \
+ \
+ Component<Required<Y##N>, Z##N> getZ##N##Component();
-#define REQUIREMENTS(N) \
-C##N,
+#define REQUIREMENTS(N) C##N,
-#define PARAMETERS(N) \
-B##N& b##N,
+#define PARAMETERS(N) B##N &b##N,
#ifdef USE_FRUIT_2_X_SYNTAX
-#define BINDINGS(N) \
- .bind<I##N, X##N>() \
- .bindInstance(b##N) \
- .install(getZ##N##Component()) \
- .registerProvider([](){return Y##N();})
+#define BINDINGS(N) \
+ .bind<I##N, X##N>().bindInstance(b##N).install(getZ##N##Component()).registerProvider([]() { return Y##N(); })
#else
-#define BINDINGS(N) \
- .bind<I##N, X##N>() \
- .bindInstance(b##N) \
- .install(getZ##N##Component) \
- .registerProvider([](){return Y##N();})
+#define BINDINGS(N) \
+ .bind<I##N, X##N>().bindInstance(b##N).install(getZ##N##Component).registerProvider([]() { return Y##N(); })
#endif
EVAL(REPEAT(DEFINITIONS))
Component<Required<EVAL(REPEAT(REQUIREMENTS)) int>> getComponent(EVAL(REPEAT(PARAMETERS)) int) {
- return createComponent()
- EVAL(REPEAT(BINDINGS))
- ;
+ return createComponent() EVAL(REPEAT(BINDINGS));
}
diff --git a/extras/benchmark/new_delete_benchmark.cpp b/extras/benchmark/new_delete_benchmark.cpp
index 218f335..8131eac 100644
--- a/extras/benchmark/new_delete_benchmark.cpp
+++ b/extras/benchmark/new_delete_benchmark.cpp
@@ -4,9 +4,9 @@
* 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.
@@ -14,11 +14,11 @@
* limitations under the License.
*/
-#include <ctime>
-#include <vector>
-#include <iostream>
-#include <iomanip>
#include <chrono>
+#include <ctime>
+#include <iomanip>
+#include <iostream>
+#include <vector>
#if MULTIPLIER == 1
#define REPEAT(X) REPEAT_1(X, _)
@@ -43,46 +43,33 @@
#define EVAL2(...) EVAL1(EVAL1(EVAL1(EVAL1(__VA_ARGS__))))
#define EVAL(...) EVAL2(EVAL2(EVAL2(EVAL2(__VA_ARGS__))))
-#define META_REPEAT_10(R, X, I) \
-R PLACEHOLDER(X, I##0) \
-R PLACEHOLDER(X, I##1) \
-R PLACEHOLDER(X, I##2) \
-R PLACEHOLDER(X, I##3) \
-R PLACEHOLDER(X, I##4) \
-R PLACEHOLDER(X, I##5) \
-R PLACEHOLDER(X, I##6) \
-R PLACEHOLDER(X, I##7) \
-R PLACEHOLDER(X, I##8) \
-R PLACEHOLDER(X, I##9)
+#define META_REPEAT_10(R, X, I) \
+ R PLACEHOLDER(X, I##0) R PLACEHOLDER(X, I##1) R PLACEHOLDER(X, I##2) R PLACEHOLDER(X, I##3) R PLACEHOLDER(X, I##4) \
+ R PLACEHOLDER(X, I##5) R PLACEHOLDER(X, I##6) R PLACEHOLDER(X, I##7) R PLACEHOLDER(X, I##8) \
+ R PLACEHOLDER(X, I##9)
-#define REPEAT_1(X, I) \
-X(I)
+#define REPEAT_1(X, I) X(I)
-#define REPEAT_10(X, I) \
-META_REPEAT_10(REPEAT_1, X, I)
+#define REPEAT_10(X, I) META_REPEAT_10(REPEAT_1, X, I)
-#define REPEAT_100(X, I) \
-META_REPEAT_10(REPEAT_10, X, I)
+#define REPEAT_100(X, I) META_REPEAT_10(REPEAT_10, X, I)
-#define REPEAT_1000(X, I) \
-META_REPEAT_10(REPEAT_100, X, I)
+#define REPEAT_1000(X, I) META_REPEAT_10(REPEAT_100, X, I)
using namespace std;
-#define DEFINITIONS(N) \
-struct I##N { \
- virtual ~I##N() = default; \
-}; \
- \
-struct C##N : public I##N { \
- virtual ~C##N() = default; \
-};
+#define DEFINITIONS(N) \
+ struct I##N { \
+ virtual ~I##N() = default; \
+ }; \
+ \
+ struct C##N : public I##N { \
+ virtual ~C##N() = default; \
+ };
-#define ALLOCATE(N) \
-C##N* c##N = new C##N();
+#define ALLOCATE(N) C##N* c##N = new C##N();
-#define DEALLOCATE(N) \
-delete c##N;
+#define DEALLOCATE(N) delete c##N;
EVAL(REPEAT(DEFINITIONS))
@@ -99,11 +86,13 @@
EVAL(REPEAT(ALLOCATE))
EVAL(REPEAT(DEALLOCATE))
}
- double totalTime = std::chrono::duration_cast<std::chrono::duration<double>>(std::chrono::high_resolution_clock::now() - start_time).count();
-
+ double totalTime =
+ std::chrono::duration_cast<std::chrono::duration<double>>(std::chrono::high_resolution_clock::now() - start_time)
+ .count();
+
std::cout << std::fixed;
std::cout << std::setprecision(15);
std::cout << "Total = " << totalTime * 1.0 / num_loops << std::endl;
-
+
return 0;
}
diff --git a/include/fruit/component.h b/include/fruit/component.h
index 769beb5..5e2a4ec 100644
--- a/include/fruit/component.h
+++ b/include/fruit/component.h
@@ -4,9 +4,9 @@
* 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.
@@ -22,10 +22,10 @@
#include <fruit/fruit_forward_decls.h>
#include <fruit/impl/bindings.h>
-#include <fruit/impl/meta/component.h>
+#include <fruit/impl/component_functors.defn.h>
#include <fruit/impl/component_storage/component_storage.h>
#include <fruit/impl/component_storage/partial_component_storage.h>
-#include <fruit/impl/component_functors.defn.h>
+#include <fruit/impl/meta/component.h>
namespace fruit {
@@ -41,36 +41,36 @@
*
* See PartialComponent below for how to construct a Component.
*/
-template<typename... Params>
+template <typename... Params>
class Component {
- public:
- Component(Component &&) = default;
+public:
+ Component(Component&&) = default;
- Component &operator=(Component &&) = delete;
- Component &operator=(const Component &) = delete;
+ Component& operator=(Component&&) = delete;
+ Component& operator=(const Component&) = delete;
/**
* Converts a PartialComponent to an arbitrary Component, auto-injecting the missing types (if
* any).
* This is usually called implicitly when returning a component from a function. See PartialComponent for an example.
*/
- template<typename... Bindings>
+ template <typename... Bindings>
Component(PartialComponent<Bindings...>&& component);
- private:
+private:
// Do not use. Use fruit::createComponent() instead.
Component() = default;
- template<typename... Types>
+ template <typename... Types>
friend class Component;
- template<typename... Bindings>
+ template <typename... Bindings>
friend class PartialComponent;
- template<typename... OtherParams>
+ template <typename... OtherParams>
friend class NormalizedComponent;
- template<typename... OtherParams>
+ template <typename... OtherParams>
friend class Injector;
template <typename... Bindings>
@@ -97,50 +97,50 @@
* Constructs an empty component.
*
* Example usage:
- *
+ *
* fruit::Component<Foo> getFooComponent() {
* return fruit::createComponent()
* .install(getComponent1)
* .install(getComponent2)
* .bind<Foo, FooImpl>();
* }
- *
+ *
* Since types are auto-injected when needed, just converting this to the desired component can suffice in some cases,
* e.g.:
- *
+ *
* fruit::Component<Foo> getFooComponent() {
* return fruit::createComponent();
* }
- *
+ *
* That works if Foo has an Inject typedef or a constructor wrapped in INJECT.
*/
PartialComponent<> createComponent();
/**
* A partially constructed component.
- *
+ *
* Client code should never write `PartialComponent'; always start the construction of a component with
* fruit::createComponent(), and end it by casting the PartialComponent to the desired Component (often done implicitly
* by returning a PartialComponent from a function that has Component<...> as the return type).
- *
+ *
* The template parameter is used to propagate information about bound types, it is purely an implementation detail;
* users of the Fruit library can pretend that this class is not templated, in no case a specific template parameter is
* required. All methods of this class return a PartialComponent, which allows to chain method invocations without
* declaring a variable of type PartialComponent.
- *
+ *
* Example usage:
- *
+ *
* fruit::Component<Foo> getFooComponent() {
* return fruit::createComponent()
* .install(getComponent1)
* .install(getComponent2)
* .bind<Foo, FooImpl>();
* }
- *
+ *
* Note that no variable of type PartialComponent has been declared; this class should only be used for temporary
* values.
*/
-template<typename... Bindings>
+template <typename... Bindings>
class PartialComponent {
public:
PartialComponent(PartialComponent&&) = default;
@@ -174,7 +174,7 @@
* return fruit::createComponent()
* .bind<MyInterface, MyImplementation>();
* }
- *
+ *
* The implementation class can be bound in any way, it doesn't need to be bound using constructor injection as above
* (although that's a very common use case).
*
@@ -256,39 +256,39 @@
* .bind<fruit::Annotated<MyAnnotation, MyInterface>, MyImplementation>();
* }
*/
- template<typename I, typename C>
+ template <typename I, typename C>
PartialComponent<fruit::impl::Bind<I, C>, Bindings...> bind();
/**
* Registers Signature as the constructor signature to use to inject a type.
- *
+ *
* Example usage:
- *
+ *
* fruit::createComponent()
* .registerConstructor<Foo(Bar*,Baz*)>() // Registers the constructor Foo::Foo(Bar*,Baz*)
- *
+ *
* It's usually more convenient to use an INJECT macro or Inject typedef instead, e.g.:
- *
+ *
* class Foo {
* public:
* // This also declares the constructor
* INJECT(Foo(Bar* bar, Baz* baz));
* ...
* };
- *
+ *
* or (equivalent):
- *
+ *
* class Foo {
* public:
* using Inject = Foo(Bar*, Baz*);
* Foo(Bar* bar, Baz* baz);
* ...
* };
- *
+ *
* Use registerConstructor() when you want to inject the class C in different ways in different components (just make
* sure those don't end up in the same injector, or use annotated injection to prevent the bindings from clashing),
* or when C is a third-party class that can't be modified.
- *
+ *
* This supports annotated injection, just wrap the desired types (return type and/or argument types of the signature)
* with fruit::Annotated<> if desired. For example:
*
@@ -328,7 +328,7 @@
* Annotated<Annotation, Provider<C>> (for any type `Annotation')
* Annotated<Annotation, Provider<const C>> (for any type `Annotation')
*/
- template<typename Signature>
+ template <typename Signature>
PartialComponent<fruit::impl::RegisterConstructor<Signature>, Bindings...> registerConstructor();
/**
@@ -336,20 +336,20 @@
* The caller must ensure that the provided reference is valid for the entire lifetime of the component and of any
* components or injectors that install this component; the caller must also ensure that the object is destroyed after
* the last components/injectors using it are destroyed.
- *
+ *
* Example usage:
*
* Component<Request> getRequestComponent(Request* request) {
* return fruit::createComponent()
* .bindInstance(*request);
* }
- *
+ *
* NormalizedComponent<...> normalizedComponent = ...;
* Request request;
* Injector<...> injector(normalizedComponent,
* getRequestComponent,
* request));
- *
+ *
* This should be used sparingly (you should let Fruit handle the object lifetime when possible), but in some cases it
* is necessary; for example, if a web server creates an injector to handle each request, this method can be used to
* inject the request itself as in the example above (see the Server page in the Fruit tutorial for more details).
@@ -357,7 +357,7 @@
* It's also possible to bind constants, see the documentation of the bindInstance() method taking a const& for
* details.
*/
- template<typename C>
+ template <typename C>
PartialComponent<fruit::impl::BindInstance<C, C>, Bindings...> bindInstance(C& instance);
/**
@@ -394,13 +394,13 @@
* Annotated<Annotation, shared_ptr<C>> (for any type `Annotation')
* Annotated<Annotation, Provider<C>> (for any type `Annotation')
*/
- template<typename C>
+ template <typename C>
PartialComponent<fruit::impl::BindConstInstance<C, C>, Bindings...> bindInstance(const C& instance);
/**
* This is deleted to catch cases where the instance would likely be destroyed before the component/injectors.
*/
- template<typename C>
+ template <typename C>
PartialComponent<fruit::impl::BindConstInstance<C, C>, Bindings...> bindInstance(C&&) = delete;
/**
@@ -413,7 +413,7 @@
* .bindInstance<fruit::Annotated<Hostname, std::string>>(*hostname);
* }
*/
- template<typename AnnotatedType, typename C>
+ template <typename AnnotatedType, typename C>
PartialComponent<fruit::impl::BindInstance<AnnotatedType, C>, Bindings...> bindInstance(C& instance);
/**
@@ -427,24 +427,24 @@
*
* See the documentation for the bindInstance() overload that takes a non-annotated const& for more details.
*/
- template<typename AnnotatedType, typename C>
+ template <typename AnnotatedType, typename C>
PartialComponent<fruit::impl::BindConstInstance<AnnotatedType, C>, Bindings...> bindInstance(const C& instance);
/**
* This is deleted to catch cases where the instance would likely be destroyed before the component/injectors.
*/
- template<typename AnnotatedType, typename C>
+ template <typename AnnotatedType, typename C>
PartialComponent<fruit::impl::BindConstInstance<AnnotatedType, C>, Bindings...> bindInstance(C&& instance);
/**
* Registers `provider' as a provider of C, where provider is a lambda with no captures returning either C or C*
* (prefer returning a C by value instead of allocating a C using `new C', to avoid the allocation).
- *
+ *
* When injecting a C, the arguments of the provider will be injected and the provider will then be called to create
* the C instance, that will then be stored in the injector.
- *
+ *
* If `provider' returns a pointer, it must be non-null; otherwise the program will abort.
- *
+ *
* Example:
*
* fruit::Component<Foo> getFooComponent() {
@@ -459,18 +459,18 @@
* }
*
* As in the previous example, it's not necessary to specify the type parameter, it will be inferred by the compiler.
- *
+ *
* registerProvider() can't be called with a plain function, but you can write a lambda that wraps the function to
* achieve the same result.
- *
+ *
* Registering stateful functors (including lambdas with captures) is NOT supported.
- * However, you can write something like:
- *
+ * However, you can write something like:
+ *
* struct Functor {
* Functor(int n) {...}
* MyClass operator()(Foo* foo) const {...}
* };
- *
+ *
* Component<MyClass> getMyClassComponent() {
* static const Functor aFunctor(42);
* return fruit::createComponent()
@@ -479,7 +479,7 @@
* .registerProvider([](const Functor& functor, Foo* foo) { return functor(foo); });
* }
*/
- template<typename Lambda>
+ template <typename Lambda>
PartialComponent<fruit::impl::RegisterProvider<Lambda>, Bindings...> registerProvider(Lambda lambda);
/**
@@ -508,17 +508,17 @@
* });
* }
*/
- template<typename AnnotatedSignature, typename Lambda>
- PartialComponent<fruit::impl::RegisterProvider<AnnotatedSignature, Lambda>, Bindings...> registerProvider(
- Lambda lambda);
+ template <typename AnnotatedSignature, typename Lambda>
+ PartialComponent<fruit::impl::RegisterProvider<AnnotatedSignature, Lambda>, Bindings...>
+ registerProvider(Lambda lambda);
/**
* Similar to bind<I, C>(), but adds a multibinding instead.
- *
+ *
* Multibindings are independent from bindings; creating a binding with bind doesn't count as a multibinding, and
* adding a multibinding doesn't allow to inject the type (it only allows to retrieve multibindings through the
* getMultibindings method of the injector).
- *
+ *
* Unlike bindings, where adding a the same binding twice is allowed (and ignored), adding the same multibinding
* multiple times will result in the creation of multiple "equivalent" instances, that will all be returned by
* getMultibindings().
@@ -530,25 +530,25 @@
* As bind(), this supports annotated injection, just wrap I and/or C in fruit::Annotated<> if desired. See the
* documentation of bind() for more details.
*/
- template<typename I, typename C>
+ template <typename I, typename C>
PartialComponent<fruit::impl::AddMultibinding<I, C>, Bindings...> addMultibinding();
/**
* Similar to bindInstance(), but adds a multibinding instead.
- *
+ *
* Multibindings are independent from bindings; creating a binding with bindInstance doesn't count as a
* multibinding, and adding a multibinding doesn't allow to inject the type (it only allows to retrieve
* multibindings through the getMultibindings method of the injector).
- *
+ *
* Unlike bindings, where adding a the same binding twice is allowed (and ignored), adding several multibindings for
* the same instance will result in duplicated values in the result of getMultibindings.
*
* Another difference compared to bindInstance() is that you can't use this to bind a const& (note that there is no
* overload of this method that takes a const&).
- *
+ *
* This method adds a multibinding for C. If the object implements an interface I and you want to add a multibinding
* for that interface instead, you must cast the object to I& before passing it to this method.
- *
+ *
* Note that this takes the instance by reference, not by value; it must remain valid for the entire lifetime of this
* component and of any injectors created from this component.
*
@@ -570,7 +570,7 @@
* // This vector contains {&x, &y}.
* const std::vector<MyClass*>& objects = injector.getMultibindings<MyClass>();
*/
- template<typename C>
+ template <typename C>
PartialComponent<fruit::impl::AddInstanceMultibinding<C>, Bindings...> addInstanceMultibinding(C& instance);
/**
@@ -596,13 +596,13 @@
* // This vector contains {&x, &y}.
* const std::vector<MyClass*>& objects = injector.getMultibindings<fruit::Annotated<MyAnnotation, MyClass>>();
*/
- template<typename AnnotatedC, typename C>
+ template <typename AnnotatedC, typename C>
PartialComponent<fruit::impl::AddInstanceMultibinding<AnnotatedC>, Bindings...> addInstanceMultibinding(C& instance);
/**
* Equivalent to calling addInstanceMultibinding() for each elements of `instances'.
* See the documentation of addInstanceMultibinding() for more details.
- *
+ *
* Note that this takes the vector by reference, not by value; the vector (and its elements) must remain valid for the
* entire lifetime of this component and of any injectors created from this component.
*
@@ -624,9 +624,9 @@
* // This vector contains {&x, &(other_objects[0]), &(other_objects[1])}.
* const std::vector<MyClass*>& objects = injector.getMultibindings<MyClass>();
*/
- template<typename C>
- PartialComponent<fruit::impl::AddInstanceVectorMultibindings<C>, Bindings...> addInstanceMultibindings(
- std::vector<C>& instances);
+ template <typename C>
+ PartialComponent<fruit::impl::AddInstanceVectorMultibindings<C>, Bindings...>
+ addInstanceMultibindings(std::vector<C>& instances);
/**
* Similar to the previous version of addInstanceMultibindings(), but it allows to specify an annotated type.
@@ -649,17 +649,17 @@
* // This vector contains {&x, &(other_objects[0]), &(other_objects[1])}.
* const std::vector<MyClass*>& objects = injector.getMultibindings<fruit::Annotated<MyAnnotation, MyClass>>();
*/
- template<typename AnnotatedC, typename C>
- PartialComponent<fruit::impl::AddInstanceVectorMultibindings<AnnotatedC>, Bindings...> addInstanceMultibindings(
- std::vector<C>& instances);
+ template <typename AnnotatedC, typename C>
+ PartialComponent<fruit::impl::AddInstanceVectorMultibindings<AnnotatedC>, Bindings...>
+ addInstanceMultibindings(std::vector<C>& instances);
/**
* Similar to registerProvider, but adds a multibinding instead.
- *
+ *
* Multibindings are independent from bindings; creating a binding with registerProvider doesn't count as a
* multibinding, and adding a multibinding doesn't allow to inject the type (it only allows to retrieve multibindings
* through the getMultibindings method of the injector).
- *
+ *
* Unlike bindings, where adding a the same binding twice is allowed (and ignored), adding the same multibinding
* provider multiple times will result in the creation of multiple "equivalent" instances, that will all be returned
* by getMultibindings.
@@ -684,12 +684,12 @@
* // This vector contains {&x, &y, &z} where x and y are MyClass objects constructed with 10 and z is a MyClass
* // object constructed with 20.
* const std::vector<MyClass*>& objects = injector.getMultibindings<MyClass>();
- *
+ *
* Note that this method adds a multibinding for the type returned by the provider. If the returned object implements
* an interface I and you want to add a multibinding for that interface instead, you should cast the pointer to I*
* before returning it.
*/
- template<typename Lambda>
+ template <typename Lambda>
PartialComponent<fruit::impl::AddMultibindingProvider<Lambda>, Bindings...> addMultibindingProvider(Lambda lambda);
/**
@@ -726,24 +726,23 @@
* // instances of Bar and Baz.
* const std::vector<MyClass*>& objects = injector.getMultibindings<fruit::Annotated<Annotation2, Foo>>();
*/
- template<typename AnnotatedSignature, typename Lambda>
+ template <typename AnnotatedSignature, typename Lambda>
PartialComponent<fruit::impl::AddMultibindingProvider<AnnotatedSignature, Lambda>, Bindings...>
- addMultibindingProvider(
- Lambda lambda);
+ addMultibindingProvider(Lambda lambda);
/**
* Registers `factory' as a factory of C, where `factory' is a lambda with no captures returning C.
* This is typically used for assisted injection (but it can also be used if no parameters are assisted).
- *
+ *
* C can be any class (or fundamental) type. If C is std::unique_ptr<T>, the factory together with a bind<I,C> in the
* same component will automatically bind the corresponding std::function that returns a std::unique_ptr<I>.
* See the documentation of bind() for more details.
- *
+ *
* The returned type can't be a pointer type. If you don't want to return it by value, you should return a
* std::unique_ptr instead.
- *
+ *
* Example:
- *
+ *
* Component<std::function<std::unique_ptr<MyClass>(int)>> getMyClassComponent() {
* fruit::createComponent()
* .install(getFooComponent)
@@ -752,49 +751,49 @@
* return std::unique_ptr<MyClass>(new MyClass(foo, n));
* });
* }
- *
+ *
* Injector<std::function<std::unique_ptr<MyClass>(int)>> injector(getMyClassComponent);
- *
+ *
* std::function<std::unique_ptr<MyClass>(int)> factory(injector);
* std::unique_ptr<MyClass> x = factory(42);
*
* The parameters marked as Assisted will become parameters of the std::function (in the same order), while the others
* (e.g. Foo in the example above) will be injected.
- *
+ *
* Unlike registerProvider(), where the signature is inferred, for this method the signature (including any Assisted
* annotations) must be specified explicitly, while the second template parameter is inferred.
- *
+ *
* If the only thing that the factory does is to call new and the constructor of the class, it's usually more
* convenient to use an Inject typedef or INJECT macro instead, e.g. the following are equivalent to the above:
- *
+ *
* class MyClass {
* public:
* using Inject = MyClass(Foo*, Assisted<int>);
- *
+ *
* MyClass(Foo* foo, int n) {...}
* };
- *
+ *
* or:
- *
+ *
* class MyClass {
* public:
* INJECT(MyClass(Foo* foo, ASSISTED(int) n)) {...}
* };
- *
+ *
* Use registerFactory() when you want to inject the class in different ways in different components (just make sure
* those don't end up in the same injector), or when MyClass is a third-party class that can't be modified.
- *
+ *
* registerFactory() can't be called with a plain function, but you can write a lambda that wraps the function to
* achieve the same result.
- *
+ *
* Registering stateful functors (including lambdas with captures) is NOT supported.
- * However, you can write something like:
- *
+ * However, you can write something like:
+ *
* struct Functor {
* Functor(float x) {...}
* std::unique_ptr<MyClass> operator()(Foo* foo, int n) {...}
* };
- *
+ *
* Component<std::function<std::unique_ptr<MyClass>(int)>> getMyClassComponent() {
* static const Functor aFunctor(42.0);
* return fruit::createComponent()
@@ -810,9 +809,9 @@
* });
* }
*/
- template<typename DecoratedSignature, typename Factory>
- PartialComponent<fruit::impl::RegisterFactory<DecoratedSignature, Factory>, Bindings...> registerFactory(
- Factory factory);
+ template <typename DecoratedSignature, typename Factory>
+ PartialComponent<fruit::impl::RegisterFactory<DecoratedSignature, Factory>, Bindings...>
+ registerFactory(Factory factory);
/**
* Adds the bindings (and multibindings) in the Component obtained by calling fun(args...) to the current component.
@@ -892,9 +891,7 @@
*/
template <typename... OtherComponentParams, typename... FormalArgs, typename... Args>
PartialComponent<fruit::impl::InstallComponent<fruit::Component<OtherComponentParams...>(FormalArgs...)>, Bindings...>
- install(
- fruit::Component<OtherComponentParams...>(*)(FormalArgs...),
- Args&&... args);
+ install(fruit::Component<OtherComponentParams...> (*)(FormalArgs...), Args&&... args);
/**
* This class is returned by PartialComponent::replace, see the documentation of that method for more information.
@@ -902,23 +899,17 @@
template <typename ReplacedComponent, typename... GetReplacedComponentFormalArgs>
class PartialComponentWithReplacementInProgress {
private:
- using storage_t =
- fruit::impl::PartialComponentStorage<
- fruit::impl::PartialReplaceComponent<ReplacedComponent(GetReplacedComponentFormalArgs...)>, Bindings...>;
+ using storage_t = fruit::impl::PartialComponentStorage<
+ fruit::impl::PartialReplaceComponent<ReplacedComponent(GetReplacedComponentFormalArgs...)>, Bindings...>;
public:
template <typename... FormalArgs, typename... Args>
- PartialComponent<
- fruit::impl::ReplaceComponent<
- ReplacedComponent(GetReplacedComponentFormalArgs...), ReplacedComponent(FormalArgs...)>,
- Bindings...>
- with(
- ReplacedComponent(*)(FormalArgs...),
- Args&&... args);
+ PartialComponent<fruit::impl::ReplaceComponent<ReplacedComponent(GetReplacedComponentFormalArgs...),
+ ReplacedComponent(FormalArgs...)>,
+ Bindings...>
+ with(ReplacedComponent (*)(FormalArgs...), Args&&... args);
- PartialComponentWithReplacementInProgress(storage_t storage)
- : storage(storage) {
- }
+ PartialComponentWithReplacementInProgress(storage_t storage) : storage(storage) {}
private:
storage_t storage;
@@ -1024,17 +1015,17 @@
* injector for getBarComponentWithFakeDependency it would not install getFakeDependencyComponent.
*/
template <typename... OtherComponentParams, typename... FormalArgs, typename... Args>
- typename PartialComponent<Bindings...>::template PartialComponentWithReplacementInProgress<fruit::Component<OtherComponentParams...>, FormalArgs...>
- replace(fruit::Component<OtherComponentParams...>(*)(FormalArgs...),
- Args&&... args);
+ typename PartialComponent<Bindings...>::template PartialComponentWithReplacementInProgress<
+ fruit::Component<OtherComponentParams...>, FormalArgs...>
+ replace(fruit::Component<OtherComponentParams...> (*)(FormalArgs...), Args&&... args);
~PartialComponent();
private:
- template<typename... OtherBindings>
+ template <typename... OtherBindings>
friend class PartialComponent;
- template<typename... Types>
+ template <typename... Types>
friend class Component;
fruit::impl::PartialComponentStorage<Bindings...> storage;
@@ -1043,11 +1034,11 @@
PartialComponent() = delete;
// Do not use. Only use PartialComponent for temporaries, and then convert it to a Component.
- PartialComponent(const PartialComponent &) = delete;
+ PartialComponent(const PartialComponent&) = delete;
PartialComponent(fruit::impl::PartialComponentStorage<Bindings...> storage);
- template<typename NewBinding>
+ template <typename NewBinding>
using OpFor = typename fruit::impl::meta::OpForComponent<Bindings...>::template AddBinding<NewBinding>;
friend PartialComponent<> createComponent();
@@ -1057,5 +1048,4 @@
#include <fruit/impl/component.defn.h>
-
#endif // FRUIT_COMPONENT_H
diff --git a/include/fruit/fruit.h b/include/fruit/fruit.h
index e00d608..ff208e7 100644
--- a/include/fruit/fruit.h
+++ b/include/fruit/fruit.h
@@ -4,9 +4,9 @@
* 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.
@@ -24,11 +24,11 @@
// This include is not required here, but having it here shortens the include trace in error messages.
#include <fruit/impl/injection_errors.h>
-#include <fruit/fruit_forward_decls.h>
#include <fruit/component.h>
-#include <fruit/normalized_component.h>
-#include <fruit/macro.h>
+#include <fruit/fruit_forward_decls.h>
#include <fruit/injector.h>
+#include <fruit/macro.h>
+#include <fruit/normalized_component.h>
#include <fruit/provider.h>
#endif // FRUIT_FRUIT_H
diff --git a/include/fruit/fruit_forward_decls.h b/include/fruit/fruit_forward_decls.h
index e5d0e61..af02706 100644
--- a/include/fruit/fruit_forward_decls.h
+++ b/include/fruit/fruit_forward_decls.h
@@ -4,9 +4,9 @@
* 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.
diff --git a/include/fruit/impl/bindings.h b/include/fruit/impl/bindings.h
index 9f395e3..c8694e5 100644
--- a/include/fruit/impl/bindings.h
+++ b/include/fruit/impl/bindings.h
@@ -4,9 +4,9 @@
* 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.
@@ -108,7 +108,7 @@
/**
* Registers `Lambda' as a factory of C, where `Lambda' is a lambda with no captures returning C.
- * Lambda must have signature DecoratedSignature (ignoring any fruit::Annotated<> and
+ * Lambda must have signature DecoratedSignature (ignoring any fruit::Annotated<> and
* fruit::Assisted<>).
* Lambda must return a C by value, or a std::unique_ptr<C>.
*/
@@ -140,5 +140,3 @@
} // namespace fruit
#endif // FRUIT_BINDINGS_H
-
-
diff --git a/include/fruit/impl/component.defn.h b/include/fruit/impl/component.defn.h
index 55f2898..ce3fb90 100644
--- a/include/fruit/impl/component.defn.h
+++ b/include/fruit/impl/component.defn.h
@@ -4,9 +4,9 @@
* 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.
@@ -19,8 +19,8 @@
#include <fruit/component.h>
-#include <fruit/impl/injection_errors.h>
#include <fruit/impl/component_storage/component_storage.h>
+#include <fruit/impl/injection_errors.h>
#include <memory>
@@ -33,25 +33,21 @@
template <typename... PreviousBindings>
struct OpForComponent {
template <typename Comp>
- using ConvertTo = Eval<
- Call(ReverseComposeFunctors(Id<ComponentFunctor(ConvertComponent, Comp)>,
- ProcessDeferredBindings,
- Id<ProcessBinding(PreviousBindings)>...),
- ConstructComponentImpl())>;
-
+ using ConvertTo = Eval<Call(ReverseComposeFunctors(Id<ComponentFunctor(ConvertComponent, Comp)>,
+ ProcessDeferredBindings, Id<ProcessBinding(PreviousBindings)>...),
+ ConstructComponentImpl())>;
+
template <typename Binding>
- using AddBinding = Eval<
- Call(ReverseComposeFunctors(Id<ProcessBinding(Binding)>,
- Id<ProcessBinding(PreviousBindings)>...),
- ConstructComponentImpl())>;
+ using AddBinding =
+ Eval<Call(ReverseComposeFunctors(Id<ProcessBinding(Binding)>, Id<ProcessBinding(PreviousBindings)>...),
+ ConstructComponentImpl())>;
};
} // namespace meta
} // namespace impl
template <typename... Params>
template <typename... Bindings>
-inline Component<Params...>::Component(PartialComponent<Bindings...>&& partial_component)
- : storage() {
+inline Component<Params...>::Component(PartialComponent<Bindings...>&& partial_component) : storage() {
(void)typename fruit::impl::meta::CheckIfError<Comp>::type();
@@ -59,7 +55,8 @@
(void)typename fruit::impl::meta::CheckIfError<Op>::type();
#ifndef FRUIT_NO_LOOP_CHECK
- (void)typename fruit::impl::meta::CheckIfError<fruit::impl::meta::Eval<fruit::impl::meta::CheckNoLoopInDeps(typename Op::Result)>>::type();
+ (void)typename fruit::impl::meta::CheckIfError<
+ fruit::impl::meta::Eval<fruit::impl::meta::CheckNoLoopInDeps(typename Op::Result)>>::type();
#endif // !FRUIT_NO_LOOP_CHECK
std::size_t num_entries = partial_component.storage.numBindings() + Op().numEntries();
@@ -80,8 +77,7 @@
}
template <typename... Bindings>
-inline PartialComponent<Bindings...>::~PartialComponent() {
-}
+inline PartialComponent<Bindings...>::~PartialComponent() {}
inline PartialComponent<> createComponent() {
return {{}};
@@ -89,11 +85,10 @@
template <typename... Bindings>
template <typename AnnotatedI, typename AnnotatedC>
-inline PartialComponent<fruit::impl::Bind<AnnotatedI, AnnotatedC>, Bindings...>
-PartialComponent<Bindings...>::bind() {
+inline PartialComponent<fruit::impl::Bind<AnnotatedI, AnnotatedC>, Bindings...> PartialComponent<Bindings...>::bind() {
using Op = OpFor<fruit::impl::Bind<AnnotatedI, AnnotatedC>>;
(void)typename fruit::impl::meta::CheckIfError<Op>::type();
-
+
return {{storage}};
}
@@ -167,7 +162,7 @@
PartialComponent<Bindings...>::addMultibinding() {
using Op = OpFor<fruit::impl::AddMultibinding<AnnotatedI, AnnotatedC>>;
(void)typename fruit::impl::meta::CheckIfError<Op>::type();
-
+
return {{storage}};
}
@@ -175,10 +170,8 @@
template <typename C>
inline PartialComponent<fruit::impl::AddInstanceMultibinding<C>, Bindings...>
PartialComponent<Bindings...>::addInstanceMultibinding(C& instance) {
- using Op = fruit::impl::meta::Eval<
- fruit::impl::meta::CheckNormalizedTypes(
- fruit::impl::meta::Vector<
- fruit::impl::meta::Type<C>>)>;
+ using Op = fruit::impl::meta::Eval<fruit::impl::meta::CheckNormalizedTypes(
+ fruit::impl::meta::Vector<fruit::impl::meta::Type<C>>)>;
(void)typename fruit::impl::meta::CheckIfError<Op>::type();
return {{storage, instance}};
@@ -188,10 +181,8 @@
template <typename AnnotatedC, typename C>
inline PartialComponent<fruit::impl::AddInstanceMultibinding<AnnotatedC>, Bindings...>
PartialComponent<Bindings...>::addInstanceMultibinding(C& instance) {
- using Op = fruit::impl::meta::Eval<
- fruit::impl::meta::CheckNormalizedTypes(
- fruit::impl::meta::Vector<
- fruit::impl::meta::Type<C>>)>;
+ using Op = fruit::impl::meta::Eval<fruit::impl::meta::CheckNormalizedTypes(
+ fruit::impl::meta::Vector<fruit::impl::meta::Type<C>>)>;
(void)typename fruit::impl::meta::CheckIfError<Op>::type();
return {{storage, instance}};
}
@@ -200,10 +191,8 @@
template <typename C>
inline PartialComponent<fruit::impl::AddInstanceVectorMultibindings<C>, Bindings...>
PartialComponent<Bindings...>::addInstanceMultibindings(std::vector<C>& instances) {
- using Op = fruit::impl::meta::Eval<
- fruit::impl::meta::CheckNormalizedTypes(
- fruit::impl::meta::Vector<
- fruit::impl::meta::Type<C>>)>;
+ using Op = fruit::impl::meta::Eval<fruit::impl::meta::CheckNormalizedTypes(
+ fruit::impl::meta::Vector<fruit::impl::meta::Type<C>>)>;
(void)typename fruit::impl::meta::CheckIfError<Op>::type();
return {{storage, instances}};
}
@@ -212,10 +201,8 @@
template <typename AnnotatedC, typename C>
inline PartialComponent<fruit::impl::AddInstanceVectorMultibindings<AnnotatedC>, Bindings...>
PartialComponent<Bindings...>::addInstanceMultibindings(std::vector<C>& instances) {
- using Op = fruit::impl::meta::Eval<
- fruit::impl::meta::CheckNormalizedTypes(
- fruit::impl::meta::Vector<
- fruit::impl::meta::Type<C>>)>;
+ using Op = fruit::impl::meta::Eval<fruit::impl::meta::CheckNormalizedTypes(
+ fruit::impl::meta::Vector<fruit::impl::meta::Type<C>>)>;
(void)typename fruit::impl::meta::CheckIfError<Op>::type();
return {{storage, instances}};
@@ -230,7 +217,7 @@
return {{storage}};
}
-
+
template <typename... Bindings>
template <typename AnnotatedSignature, typename Lambda>
inline PartialComponent<fruit::impl::AddMultibindingProvider<AnnotatedSignature, Lambda>, Bindings...>
@@ -240,7 +227,7 @@
return {{storage}};
}
-
+
template <typename... Bindings>
template <typename DecoratedSignature, typename Lambda>
inline PartialComponent<fruit::impl::RegisterFactory<DecoratedSignature, Lambda>, Bindings...>
@@ -253,12 +240,10 @@
template <typename... Bindings>
inline PartialComponent<Bindings...>::PartialComponent(fruit::impl::PartialComponentStorage<Bindings...> storage)
- : storage(std::move(storage)) {
-}
+ : storage(std::move(storage)) {}
template <typename T>
-FRUIT_ALWAYS_INLINE
-inline int checkAcceptableComponentInstallArg() {
+FRUIT_ALWAYS_INLINE inline int checkAcceptableComponentInstallArg() {
// This lambda checks that the required operations on T exist.
// Note that the lambda is never actually executed.
auto checkRequirements = [](const T& constRef, T value) {
@@ -279,8 +264,10 @@
template <typename... Bindings>
template <typename... OtherComponentParams, typename... FormalArgs, typename... Args>
-inline PartialComponent<fruit::impl::InstallComponent<fruit::Component<OtherComponentParams...>(FormalArgs...)>, Bindings...>
-PartialComponent<Bindings...>::install(fruit::Component<OtherComponentParams...>(*getComponent)(FormalArgs...), Args&&... args) {
+inline PartialComponent<fruit::impl::InstallComponent<fruit::Component<OtherComponentParams...>(FormalArgs...)>,
+ Bindings...>
+PartialComponent<Bindings...>::install(fruit::Component<OtherComponentParams...> (*getComponent)(FormalArgs...),
+ Args&&... args) {
using IntCollector = int[];
(void)IntCollector{0, checkAcceptableComponentInstallArg<FormalArgs>()...};
@@ -294,8 +281,10 @@
template <typename... Bindings>
template <typename... OtherComponentParams, typename... FormalArgs, typename... Args>
-inline typename PartialComponent<Bindings...>::template PartialComponentWithReplacementInProgress<fruit::Component<OtherComponentParams...>, FormalArgs...>
-PartialComponent<Bindings...>::replace(fruit::Component<OtherComponentParams...>(*getReplacedComponent)(FormalArgs...), Args&&... args) {
+inline typename PartialComponent<Bindings...>::template PartialComponentWithReplacementInProgress<
+ fruit::Component<OtherComponentParams...>, FormalArgs...>
+PartialComponent<Bindings...>::replace(fruit::Component<OtherComponentParams...> (*getReplacedComponent)(FormalArgs...),
+ Args&&... args) {
using IntCollector = int[];
(void)IntCollector{0, checkAcceptableComponentInstallArg<FormalArgs>()...};
@@ -307,10 +296,12 @@
template <typename... Bindings>
template <typename OtherComponent, typename... GetReplacedComponentFormalArgs>
template <typename... GetReplacementComponentFormalArgs, typename... Args>
-inline
-PartialComponent<fruit::impl::ReplaceComponent<OtherComponent(GetReplacedComponentFormalArgs...), OtherComponent(GetReplacementComponentFormalArgs...)>, Bindings...>
-PartialComponent<Bindings...>::PartialComponentWithReplacementInProgress<OtherComponent, GetReplacedComponentFormalArgs...>::with(
- OtherComponent(*getReplacementComponent)(GetReplacementComponentFormalArgs...), Args&&... args) {
+inline PartialComponent<fruit::impl::ReplaceComponent<OtherComponent(GetReplacedComponentFormalArgs...),
+ OtherComponent(GetReplacementComponentFormalArgs...)>,
+ Bindings...>
+PartialComponent<Bindings...>::
+ PartialComponentWithReplacementInProgress<OtherComponent, GetReplacedComponentFormalArgs...>::with(
+ OtherComponent (*getReplacementComponent)(GetReplacementComponentFormalArgs...), Args&&... args) {
using IntCollector = int[];
(void)IntCollector{0, checkAcceptableComponentInstallArg<GetReplacementComponentFormalArgs>()...};
diff --git a/include/fruit/impl/component_functors.defn.h b/include/fruit/impl/component_functors.defn.h
index a2c6e8f..795eba5 100644
--- a/include/fruit/impl/component_functors.defn.h
+++ b/include/fruit/impl/component_functors.defn.h
@@ -4,9 +4,9 @@
* 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.
@@ -19,8 +19,8 @@
#include <fruit/component.h>
-#include <fruit/impl/injection_errors.h>
#include <fruit/impl/injection_debug_errors.h>
+#include <fruit/impl/injection_errors.h>
#include <fruit/impl/injector/injector_storage.h>
#include <memory>
@@ -91,9 +91,7 @@
return Eval<Op1>().numEntries() + Eval<Op2>().numEntries();
}
};
- using type = PropagateError(Op1,
- PropagateError(Op2,
- Op));
+ using type = PropagateError(Op1, PropagateError(Op2, Op));
};
};
};
@@ -103,7 +101,7 @@
// first Error).
struct ComposeFunctors {
template <typename... Functors>
- struct apply {
+ struct apply {
using type = Fold(Compose2ComponentFunctors, ComponentFunctorIdentity, Functors...);
};
};
@@ -119,12 +117,12 @@
struct apply {
using type = ComponentFunctorIdentity;
};
-
+
template <typename Functor>
struct apply<Functor> {
using type = Functor;
};
-
+
template <typename Functor, typename... Functors>
struct apply<Functor, Functors...> {
using type = Compose2ComponentFunctors(ReverseComposeFunctors(Functors...), Functor);
@@ -139,14 +137,11 @@
struct AddDeferredInterfaceBinding {
template <typename Comp, typename AnnotatedI, typename AnnotatedC>
struct apply {
- using Comp1 = ConsComp(typename Comp::RsSuperset,
- typename Comp::Ps,
- typename Comp::NonConstRsPs,
+ using Comp1 = ConsComp(typename Comp::RsSuperset, typename Comp::Ps, typename Comp::NonConstRsPs,
#ifndef FRUIT_NO_LOOP_CHECK
typename Comp::Deps,
#endif
- PushFront(typename Comp::InterfaceBindings,
- Pair<AnnotatedI, AnnotatedC>),
+ PushFront(typename Comp::InterfaceBindings, Pair<AnnotatedI, AnnotatedC>),
typename Comp::DeferredBindingFunctors);
struct Op {
// Note that we do NOT call AddProvidedType here. We'll only know the right required type
@@ -159,20 +154,16 @@
};
using I = RemoveAnnotations(AnnotatedI);
using C = RemoveAnnotations(AnnotatedC);
- using type = If(IsSame(I, C),
- ConstructError(InterfaceBindingToSelfErrorTag, C),
- If(Not(IsBaseOf(I, C)),
- ConstructError(NotABaseClassOfErrorTag, I, C),
- If(Not(IsSame(I, NormalizeType(I))),
- ConstructError(NonClassTypeErrorTag, I, NormalizeUntilStable(I)),
+ using type =
+ If(IsSame(I, C), ConstructError(InterfaceBindingToSelfErrorTag, C),
+ If(Not(IsBaseOf(I, C)), ConstructError(NotABaseClassOfErrorTag, I, C),
+ If(Not(IsSame(I, NormalizeType(I))), ConstructError(NonClassTypeErrorTag, I, NormalizeUntilStable(I)),
If(Not(IsSame(C, NormalizeType(C))),
// We handle this case too, just to be on the safe side, but this should never happen.
ConstructError(NonClassTypeErrorTag, C, NormalizeUntilStable(C)),
- If(IsInSet(AnnotatedI, typename Comp::Ps),
- ConstructError(TypeAlreadyBoundErrorTag, AnnotatedI),
- If(MapContainsKey(typename Comp::InterfaceBindings, AnnotatedI),
- ConstructError(TypeAlreadyBoundErrorTag, AnnotatedI),
- Op))))));
+ If(IsInSet(AnnotatedI, typename Comp::Ps), ConstructError(TypeAlreadyBoundErrorTag, AnnotatedI),
+ If(MapContainsKey(typename Comp::InterfaceBindings, AnnotatedI),
+ ConstructError(TypeAlreadyBoundErrorTag, AnnotatedI), Op))))));
};
};
@@ -180,19 +171,17 @@
template <typename Comp, typename AnnotatedI, typename AnnotatedC, typename NonConstBindingRequired>
struct apply {
using R = If(NonConstBindingRequired,
- AddProvidedTypeIgnoringInterfaceBindings(
- Comp, AnnotatedI, NonConstBindingRequired, Vector<AnnotatedC>, Vector<AnnotatedC>),
- AddProvidedTypeIgnoringInterfaceBindings(
- Comp, AnnotatedI, NonConstBindingRequired, Vector<AnnotatedC>, Vector<>));
+ AddProvidedTypeIgnoringInterfaceBindings(Comp, AnnotatedI, NonConstBindingRequired, Vector<AnnotatedC>,
+ Vector<AnnotatedC>),
+ AddProvidedTypeIgnoringInterfaceBindings(Comp, AnnotatedI, NonConstBindingRequired, Vector<AnnotatedC>,
+ Vector<>));
struct ConstOp {
// This must be here (and not in AddDeferredInterfaceBinding) because the binding might be
// used to bind functors instead, so we might never need to add C to the requirements.
using Result = Eval<R>;
void operator()(FixedSizeVector<ComponentStorageEntry>& entries) {
entries.push_back(
- InjectorStorage::createComponentStorageEntryForConstBind<
- UnwrapType<AnnotatedI>,
- UnwrapType<AnnotatedC>>());
+ InjectorStorage::createComponentStorageEntryForConstBind<UnwrapType<AnnotatedI>, UnwrapType<AnnotatedC>>());
};
std::size_t numEntries() {
@@ -205,19 +194,14 @@
using Result = Eval<R>;
void operator()(FixedSizeVector<ComponentStorageEntry>& entries) {
entries.push_back(
- InjectorStorage::createComponentStorageEntryForBind<
- UnwrapType<AnnotatedI>,
- UnwrapType<AnnotatedC>>());
+ InjectorStorage::createComponentStorageEntryForBind<UnwrapType<AnnotatedI>, UnwrapType<AnnotatedC>>());
};
std::size_t numEntries() {
return 1;
}
};
- using type = PropagateError(R,
- If(NonConstBindingRequired,
- NonConstOp,
- ConstOp));
+ using type = PropagateError(R, If(NonConstBindingRequired, NonConstOp, ConstOp));
};
};
@@ -230,22 +214,17 @@
struct Op {
using Result = Eval<R>;
void operator()(FixedSizeVector<ComponentStorageEntry>& entries) {
+ entries.push_back(InjectorStorage::createComponentStorageEntryForMultibinding<UnwrapType<AnnotatedI>,
+ UnwrapType<AnnotatedC>>());
entries.push_back(
- InjectorStorage::createComponentStorageEntryForMultibinding<
- UnwrapType<AnnotatedI>,
- UnwrapType<AnnotatedC>>());
- entries.push_back(
- InjectorStorage::createComponentStorageEntryForMultibindingVectorCreator<
- UnwrapType<AnnotatedI>>());
+ InjectorStorage::createComponentStorageEntryForMultibindingVectorCreator<UnwrapType<AnnotatedI>>());
};
std::size_t numEntries() {
return 2;
}
};
- using type = If(Not(IsBaseOf(I, C)),
- ConstructError(NotABaseClassOfErrorTag, I, C),
- Op);
+ using type = If(Not(IsBaseOf(I, C)), ConstructError(NotABaseClassOfErrorTag, I, C), Op);
};
};
@@ -259,11 +238,8 @@
struct PostProcessRegisterProviderHelper<AnnotatedSignature, Lambda, Type<AnnotatedI>> {
inline void operator()(FixedSizeVector<ComponentStorageEntry>& entries) {
entries.push_back(
- InjectorStorage::createComponentStorageEntryForCompressedProvider<
- AnnotatedSignature, Lambda, AnnotatedI>());
- entries.push_back(
- InjectorStorage::createComponentStorageEntryForProvider<
- AnnotatedSignature, Lambda>());
+ InjectorStorage::createComponentStorageEntryForCompressedProvider<AnnotatedSignature, Lambda, AnnotatedI>());
+ entries.push_back(InjectorStorage::createComponentStorageEntryForProvider<AnnotatedSignature, Lambda>());
}
std::size_t numEntries() {
@@ -274,9 +250,7 @@
template <typename AnnotatedSignature, typename Lambda>
struct PostProcessRegisterProviderHelper<AnnotatedSignature, Lambda, None> {
inline void operator()(FixedSizeVector<ComponentStorageEntry>& entries) {
- entries.push_back(
- InjectorStorage::createComponentStorageEntryForProvider<
- AnnotatedSignature, Lambda>());
+ entries.push_back(InjectorStorage::createComponentStorageEntryForProvider<AnnotatedSignature, Lambda>());
}
std::size_t numEntries() {
@@ -294,9 +268,8 @@
struct Op {
using Result = Comp;
- using Helper =
- PostProcessRegisterProviderHelper<
- UnwrapType<AnnotatedSignature>, UnwrapType<Lambda>, Eval<OptionalAnnotatedI>>;
+ using Helper = PostProcessRegisterProviderHelper<UnwrapType<AnnotatedSignature>, UnwrapType<Lambda>,
+ Eval<OptionalAnnotatedI>>;
void operator()(FixedSizeVector<ComponentStorageEntry>& entries) {
Helper()(entries);
}
@@ -313,21 +286,28 @@
struct apply {
using Signature = RemoveAnnotationsFromSignature(AnnotatedSignature);
using SignatureFromLambda = FunctionSignature(Lambda);
-
+
using AnnotatedC = NormalizeType(SignatureType(AnnotatedSignature));
using AnnotatedCDeps = NormalizeTypeVector(SignatureArgs(AnnotatedSignature));
- using R = AddProvidedType(Comp, AnnotatedC, Bool<true>, AnnotatedCDeps, Id<NormalizedNonConstTypesIn(SignatureArgs(AnnotatedSignature))>);
- using type = If(Not(IsSame(Signature, SignatureFromLambda)),
- ConstructError(AnnotatedSignatureDifferentFromLambdaSignatureErrorTag, Signature, SignatureFromLambda),
- PropagateError(CheckInjectableType(RemoveAnnotations(SignatureType(AnnotatedSignature))),
- PropagateError(CheckInjectableTypeVector(RemoveAnnotationsFromVector(AnnotatedCDeps)),
- PropagateError(CheckInjectableType(SignatureType(SignatureFromLambda)),
- PropagateError(CheckInjectableTypeVector(SignatureArgs(SignatureFromLambda)),
- If(And(IsPointer(SignatureType(SignatureFromLambda)),
- And(IsAbstract(RemovePointer(SignatureType(SignatureFromLambda))),
- Not(HasVirtualDestructor(RemovePointer(SignatureType(SignatureFromLambda)))))),
- ConstructError(ProviderReturningPointerToAbstractClassWithNoVirtualDestructorErrorTag, RemovePointer(SignatureType(SignatureFromLambda))),
- ComponentFunctorIdentity(R)))))));
+ using R = AddProvidedType(Comp, AnnotatedC, Bool<true>, AnnotatedCDeps,
+ Id<NormalizedNonConstTypesIn(SignatureArgs(AnnotatedSignature))>);
+ using type =
+ If(Not(IsSame(Signature, SignatureFromLambda)),
+ ConstructError(AnnotatedSignatureDifferentFromLambdaSignatureErrorTag, Signature, SignatureFromLambda),
+ PropagateError(
+ CheckInjectableType(RemoveAnnotations(SignatureType(AnnotatedSignature))),
+ PropagateError(
+ CheckInjectableTypeVector(RemoveAnnotationsFromVector(AnnotatedCDeps)),
+ PropagateError(
+ CheckInjectableType(SignatureType(SignatureFromLambda)),
+ PropagateError(
+ CheckInjectableTypeVector(SignatureArgs(SignatureFromLambda)),
+ If(And(IsPointer(SignatureType(SignatureFromLambda)),
+ And(IsAbstract(RemovePointer(SignatureType(SignatureFromLambda))),
+ Not(HasVirtualDestructor(RemovePointer(SignatureType(SignatureFromLambda)))))),
+ ConstructError(ProviderReturningPointerToAbstractClassWithNoVirtualDestructorErrorTag,
+ RemovePointer(SignatureType(SignatureFromLambda))),
+ ComponentFunctorIdentity(R)))))));
};
};
@@ -335,8 +315,7 @@
struct DeferredRegisterProviderWithAnnotations {
template <typename Comp, typename AnnotatedSignature, typename Lambda>
struct apply {
- using Comp1 = AddDeferredBinding(Comp,
- ComponentFunctor(PostProcessRegisterProvider, AnnotatedSignature, Lambda));
+ using Comp1 = AddDeferredBinding(Comp, ComponentFunctor(PostProcessRegisterProvider, AnnotatedSignature, Lambda));
using type = PreProcessRegisterProvider(Comp1, AnnotatedSignature, Lambda);
};
};
@@ -356,7 +335,7 @@
struct apply {
using Signature = RemoveAnnotationsFromSignature(AnnotatedSignature);
using SignatureFromLambda = FunctionSignature(Lambda);
-
+
using AnnotatedArgs = SignatureArgs(AnnotatedSignature);
using AnnotatedArgVector = NormalizeTypeVector(AnnotatedArgs);
using NonConstRequirements = NormalizedNonConstTypesIn(AnnotatedArgs);
@@ -365,33 +344,38 @@
using Result = Eval<R>;
void operator()(FixedSizeVector<ComponentStorageEntry>& entries) {
entries.push_back(
- InjectorStorage::createComponentStorageEntryForMultibindingProvider<
- UnwrapType<AnnotatedSignature>,
- UnwrapType<Lambda>>());
- entries.push_back(
- InjectorStorage::createComponentStorageEntryForMultibindingVectorCreator<
- UnwrapType<Eval<NormalizeType(SignatureType(AnnotatedSignature))>>>());
+ InjectorStorage::createComponentStorageEntryForMultibindingProvider<UnwrapType<AnnotatedSignature>,
+ UnwrapType<Lambda>>());
+ entries.push_back(InjectorStorage::createComponentStorageEntryForMultibindingVectorCreator<
+ UnwrapType<Eval<NormalizeType(SignatureType(AnnotatedSignature))>>>());
}
std::size_t numEntries() {
return 2;
}
};
- using type = If(Not(IsValidSignature(AnnotatedSignature)),
- ConstructError(NotASignatureErrorTag, AnnotatedSignature),
- PropagateError(CheckInjectableType(RemoveAnnotations(SignatureType(AnnotatedSignature))),
- PropagateError(CheckInjectableTypeVector(RemoveAnnotationsFromVector(SignatureArgs(AnnotatedSignature))),
- PropagateError(CheckInjectableType(SignatureType(SignatureFromLambda)),
- PropagateError(CheckInjectableTypeVector(SignatureArgs(SignatureFromLambda)),
- If(IsAbstract(RemoveAnnotations(SignatureType(AnnotatedSignature))),
- ConstructError(CannotConstructAbstractClassErrorTag, RemoveAnnotations(SignatureType(AnnotatedSignature))),
- If(Not(IsSame(Signature, SignatureFromLambda)),
- ConstructError(AnnotatedSignatureDifferentFromLambdaSignatureErrorTag, Signature, SignatureFromLambda),
- If(And(IsPointer(SignatureType(SignatureFromLambda)),
- And(IsAbstract(RemovePointer(SignatureType(SignatureFromLambda))),
- Not(HasVirtualDestructor(RemovePointer(SignatureType(SignatureFromLambda)))))),
- ConstructError(MultibindingProviderReturningPointerToAbstractClassWithNoVirtualDestructorErrorTag, RemovePointer(SignatureType(SignatureFromLambda))),
- PropagateError(R,
- Op)))))))));
+ using type = If(
+ Not(IsValidSignature(AnnotatedSignature)), ConstructError(NotASignatureErrorTag, AnnotatedSignature),
+ PropagateError(
+ CheckInjectableType(RemoveAnnotations(SignatureType(AnnotatedSignature))),
+ PropagateError(
+ CheckInjectableTypeVector(RemoveAnnotationsFromVector(SignatureArgs(AnnotatedSignature))),
+ PropagateError(
+ CheckInjectableType(SignatureType(SignatureFromLambda)),
+ PropagateError(
+ CheckInjectableTypeVector(SignatureArgs(SignatureFromLambda)),
+ If(IsAbstract(RemoveAnnotations(SignatureType(AnnotatedSignature))),
+ ConstructError(CannotConstructAbstractClassErrorTag,
+ RemoveAnnotations(SignatureType(AnnotatedSignature))),
+ If(Not(IsSame(Signature, SignatureFromLambda)),
+ ConstructError(AnnotatedSignatureDifferentFromLambdaSignatureErrorTag, Signature,
+ SignatureFromLambda),
+ If(And(IsPointer(SignatureType(SignatureFromLambda)),
+ And(IsAbstract(RemovePointer(SignatureType(SignatureFromLambda))),
+ Not(HasVirtualDestructor(RemovePointer(SignatureType(SignatureFromLambda)))))),
+ ConstructError(
+ MultibindingProviderReturningPointerToAbstractClassWithNoVirtualDestructorErrorTag,
+ RemovePointer(SignatureType(SignatureFromLambda))),
+ PropagateError(R, Op)))))))));
};
};
@@ -416,36 +400,30 @@
// Assisted case.
template <int numAssistedBefore, int numNonAssistedBefore, typename Arg>
struct GetAssistedArg<numAssistedBefore, numNonAssistedBefore, Assisted<Arg>> {
- template <typename InjectedArgsTuple, typename UserProvidedArgsTuple>
- inline Arg operator()(InjectedArgsTuple&, UserProvidedArgsTuple& user_provided_args) {
+ template <typename InjectedArgsTuple, typename UserProvidedArgsTuple>
+ inline Arg operator()(InjectedArgsTuple&, UserProvidedArgsTuple& user_provided_args) {
return std::get<numAssistedBefore>(user_provided_args);
}
};
struct RegisterFactoryHelper {
-
- template <typename Comp,
- typename DecoratedSignature,
- typename Lambda,
+
+ template <typename Comp, typename DecoratedSignature, typename Lambda,
// std::function<InjectedSignature> is the injected type (possibly with an Annotation<> wrapping it)
- typename InjectedSignature,
- typename RequiredLambdaSignature,
- typename InjectedAnnotatedArgs,
+ typename InjectedSignature, typename RequiredLambdaSignature, typename InjectedAnnotatedArgs,
// The types that are injected, unwrapped from any Annotation<>.
- typename InjectedArgs,
- typename IndexSequence>
+ typename InjectedArgs, typename IndexSequence>
struct apply;
-
- template <typename Comp, typename DecoratedSignature, typename Lambda, typename NakedC,
- typename... NakedUserProvidedArgs, typename... NakedAllArgs, typename... InjectedAnnotatedArgs,
- typename... NakedInjectedArgs, typename... Indexes>
- struct apply<Comp, DecoratedSignature, Lambda, Type<NakedC(NakedUserProvidedArgs...)>,
- Type<NakedC(NakedAllArgs...)>, Vector<InjectedAnnotatedArgs...>,
- Vector<Type<NakedInjectedArgs>...>, Vector<Indexes...>> {
+
+ template <typename Comp, typename DecoratedSignature, typename Lambda, typename NakedC,
+ typename... NakedUserProvidedArgs, typename... NakedAllArgs, typename... InjectedAnnotatedArgs,
+ typename... NakedInjectedArgs, typename... Indexes>
+ struct apply<Comp, DecoratedSignature, Lambda, Type<NakedC(NakedUserProvidedArgs...)>, Type<NakedC(NakedAllArgs...)>,
+ Vector<InjectedAnnotatedArgs...>, Vector<Type<NakedInjectedArgs>...>, Vector<Indexes...>> {
// Here we call "decorated" the types that might be wrapped in Annotated<> or Assisted<>,
// while we call "annotated" the ones that might only be wrapped in Annotated<> (but not Assisted<>).
using AnnotatedT = SignatureType(DecoratedSignature);
- using T = RemoveAnnotations(AnnotatedT);
+ using T = RemoveAnnotations(AnnotatedT);
using DecoratedArgs = SignatureArgs(DecoratedSignature);
using NakedInjectedSignature = NakedC(NakedUserProvidedArgs...);
using NakedRequiredSignature = NakedC(NakedAllArgs...);
@@ -462,24 +440,23 @@
auto injected_args = std::make_tuple(args...);
auto object_provider = [injected_args](NakedUserProvidedArgs... params) mutable {
auto user_provided_args = std::tie(params...);
- // These are unused if they are 0-arg tuples. Silence the unused-variable warnings anyway.
- (void) injected_args;
- (void) user_provided_args;
+ // These are unused if they are 0-arg tuples. Silence the unused-variable warnings anyway.
+ (void)injected_args;
+ (void)user_provided_args;
- return LambdaInvoker::invoke<UnwrapType<Lambda>, NakedAllArgs...>(
- GetAssistedArg<
- Eval<NumAssistedBefore(Indexes, DecoratedArgs)>::value,
- Indexes::value - Eval<NumAssistedBefore(Indexes, DecoratedArgs)>::value,
- // Note that the Assisted<> wrapper (if any) remains, we just remove any wrapping Annotated<>.
- UnwrapType<Eval<RemoveAnnotations(GetNthType(Indexes, DecoratedArgs))>>
- >()(injected_args, user_provided_args)...);
- };
+ return LambdaInvoker::invoke<UnwrapType<Lambda>, NakedAllArgs...>(
+ GetAssistedArg<
+ Eval<NumAssistedBefore(Indexes, DecoratedArgs)>::value,
+ Indexes::value - Eval<NumAssistedBefore(Indexes, DecoratedArgs)>::value,
+ // Note that the Assisted<> wrapper (if any) remains, we just remove any wrapping Annotated<>.
+ UnwrapType<Eval<RemoveAnnotations(GetNthType(Indexes, DecoratedArgs))>>>()(injected_args,
+ user_provided_args)...);
+ };
return NakedFunctor(object_provider);
};
- entries.push_back(
- InjectorStorage::createComponentStorageEntryForProvider<
- UnwrapType<Eval<ConsSignatureWithVector(AnnotatedFunctor, Vector<InjectedAnnotatedArgs...>)>>,
- decltype(function_provider)>());
+ entries.push_back(InjectorStorage::createComponentStorageEntryForProvider<
+ UnwrapType<Eval<ConsSignatureWithVector(AnnotatedFunctor, Vector<InjectedAnnotatedArgs...>)>>,
+ decltype(function_provider)>());
}
std::size_t numEntries() {
return 1;
@@ -488,11 +465,10 @@
// The first two IsValidSignature checks are a bit of a hack, they are needed to make the F2/RealF2 split
// work in the caller (we need to allow Lambda to be a function type).
using type = If(Not(IsSame(Type<NakedRequiredSignature>, FunctionSignature(Lambda))),
- ConstructError(FunctorSignatureDoesNotMatchErrorTag, Type<NakedRequiredSignature>, FunctionSignature(Lambda)),
- If(IsPointer(T),
- ConstructError(FactoryReturningPointerErrorTag, DecoratedSignature),
- PropagateError(R,
- Op)));
+ ConstructError(FunctorSignatureDoesNotMatchErrorTag, Type<NakedRequiredSignature>,
+ FunctionSignature(Lambda)),
+ If(IsPointer(T), ConstructError(FactoryReturningPointerErrorTag, DecoratedSignature),
+ PropagateError(R, Op)));
};
};
@@ -500,31 +476,36 @@
template <typename Comp, typename DecoratedSignature, typename Lambda>
struct apply {
using LambdaReturnType = SignatureType(FunctionSignature(Lambda));
- using type = If(Not(IsValidSignature(DecoratedSignature)),
- ConstructError(NotASignatureErrorTag, DecoratedSignature),
- PropagateError(CheckInjectableType(RemoveAnnotations(SignatureType(DecoratedSignature))),
- PropagateError(CheckInjectableTypeVector(RemoveAnnotationsFromVector(RemoveAssisted(SignatureArgs(DecoratedSignature)))),
- If(IsAbstract(RemoveAnnotations(SignatureType(DecoratedSignature))),
- // We error out early in this case. Calling RegisterFactoryHelper would also produce an error, but it'd be
- // much less user-friendly.
- ConstructError(CannotConstructAbstractClassErrorTag, RemoveAnnotations(SignatureType(DecoratedSignature))),
- If(Not(Or(IsEmpty(Lambda), IsValidSignature(Lambda))),
- ConstructError(LambdaWithCapturesErrorTag, Lambda),
- If(Not(Or(IsTriviallyCopyable(Lambda), IsValidSignature(Lambda))),
- ConstructError(NonTriviallyCopyableLambdaErrorTag, Lambda),
- If(And(IsUniquePtr(LambdaReturnType),
- And(IsAbstract(RemoveUniquePtr(LambdaReturnType)),
- Not(HasVirtualDestructor(RemoveUniquePtr(LambdaReturnType))))),
- ConstructError(RegisterFactoryForUniquePtrOfAbstractClassWithNoVirtualDestructorErrorTag, RemoveUniquePtr(LambdaReturnType)),
- RegisterFactoryHelper(Comp,
- DecoratedSignature,
- Lambda,
- InjectedSignatureForAssistedFactory(DecoratedSignature),
- RequiredLambdaSignatureForAssistedFactory(DecoratedSignature),
- RemoveAssisted(SignatureArgs(DecoratedSignature)),
- RemoveAnnotationsFromVector(RemoveAssisted(SignatureArgs(DecoratedSignature))),
- GenerateIntSequence(
- VectorSize(RequiredLambdaArgsForAssistedFactory(DecoratedSignature)))))))))));
+ using type =
+ If(Not(IsValidSignature(DecoratedSignature)), ConstructError(NotASignatureErrorTag, DecoratedSignature),
+ PropagateError(
+ CheckInjectableType(RemoveAnnotations(SignatureType(DecoratedSignature))),
+ PropagateError(
+ CheckInjectableTypeVector(
+ RemoveAnnotationsFromVector(RemoveAssisted(SignatureArgs(DecoratedSignature)))),
+ If(IsAbstract(RemoveAnnotations(SignatureType(DecoratedSignature))),
+ // We error out early in this case. Calling RegisterFactoryHelper would also produce an error, but
+ // it'd be
+ // much less user-friendly.
+ ConstructError(CannotConstructAbstractClassErrorTag,
+ RemoveAnnotations(SignatureType(DecoratedSignature))),
+ If(Not(Or(IsEmpty(Lambda), IsValidSignature(Lambda))),
+ ConstructError(LambdaWithCapturesErrorTag, Lambda),
+ If(Not(Or(IsTriviallyCopyable(Lambda), IsValidSignature(Lambda))),
+ ConstructError(NonTriviallyCopyableLambdaErrorTag, Lambda),
+ If(And(IsUniquePtr(LambdaReturnType),
+ And(IsAbstract(RemoveUniquePtr(LambdaReturnType)),
+ Not(HasVirtualDestructor(RemoveUniquePtr(LambdaReturnType))))),
+ ConstructError(RegisterFactoryForUniquePtrOfAbstractClassWithNoVirtualDestructorErrorTag,
+ RemoveUniquePtr(LambdaReturnType)),
+ RegisterFactoryHelper(
+ Comp, DecoratedSignature, Lambda,
+ InjectedSignatureForAssistedFactory(DecoratedSignature),
+ RequiredLambdaSignatureForAssistedFactory(DecoratedSignature),
+ RemoveAssisted(SignatureArgs(DecoratedSignature)),
+ RemoveAnnotationsFromVector(RemoveAssisted(SignatureArgs(DecoratedSignature))),
+ GenerateIntSequence(
+ VectorSize(RequiredLambdaArgsForAssistedFactory(DecoratedSignature)))))))))));
};
};
@@ -540,12 +521,8 @@
struct PostProcessRegisterConstructorHelper<AnnotatedSignature, Type<AnnotatedI>> {
inline void operator()(FixedSizeVector<ComponentStorageEntry>& entries) {
entries.push_back(
- InjectorStorage::createComponentStorageEntryForCompressedConstructor<
- AnnotatedSignature,
- AnnotatedI>());
- entries.push_back(
- InjectorStorage::createComponentStorageEntryForConstructor<
- AnnotatedSignature>());
+ InjectorStorage::createComponentStorageEntryForCompressedConstructor<AnnotatedSignature, AnnotatedI>());
+ entries.push_back(InjectorStorage::createComponentStorageEntryForConstructor<AnnotatedSignature>());
}
std::size_t numEntries() {
return 2;
@@ -555,9 +532,7 @@
template <typename AnnotatedSignature>
struct PostProcessRegisterConstructorHelper<AnnotatedSignature, None> {
inline void operator()(FixedSizeVector<ComponentStorageEntry>& entries) {
- entries.push_back(
- InjectorStorage::createComponentStorageEntryForConstructor<
- AnnotatedSignature>());
+ entries.push_back(InjectorStorage::createComponentStorageEntryForConstructor<AnnotatedSignature>());
}
std::size_t numEntries() {
return 1;
@@ -571,9 +546,8 @@
using AnnotatedC = NormalizeType(SignatureType(AnnotatedSignature));
using Result = Comp;
using Helper =
- PostProcessRegisterConstructorHelper<
- UnwrapType<AnnotatedSignature>,
- Eval<FindValueInMap(typename Comp::InterfaceBindings, AnnotatedC)>>;
+ PostProcessRegisterConstructorHelper<UnwrapType<AnnotatedSignature>,
+ Eval<FindValueInMap(typename Comp::InterfaceBindings, AnnotatedC)>>;
void operator()(FixedSizeVector<ComponentStorageEntry>& entries) {
Helper()(entries);
}
@@ -590,30 +564,29 @@
using Signature = RemoveAnnotationsFromSignature(AnnotatedSignature);
using C = SignatureType(Signature);
using Args = SignatureArgs(Signature);
- using AnnotatedT = SignatureType(AnnotatedSignature);
+ using AnnotatedT = SignatureType(AnnotatedSignature);
using AnnotatedArgs = SignatureArgs(AnnotatedSignature);
using AnnotatedC = NormalizeType(AnnotatedT);
using CDeps = NormalizeTypeVector(AnnotatedArgs);
using CNonConstDeps = NormalizedNonConstTypesIn(AnnotatedArgs);
using R = AddProvidedType(Comp, AnnotatedC, Bool<true>, CDeps, CNonConstDeps);
- using type = If(Not(IsValidSignature(AnnotatedSignature)),
- ConstructError(NotASignatureErrorTag, AnnotatedSignature),
- PropagateError(CheckInjectableType(RemoveAnnotations(C)),
- PropagateError(CheckInjectableTypeVector(RemoveAnnotationsFromVector(Args)),
- If(IsAbstract(RemoveAnnotations(SignatureType(AnnotatedSignature))),
- ConstructError(CannotConstructAbstractClassErrorTag, RemoveAnnotations(SignatureType(AnnotatedSignature))),
- If(Not(IsConstructibleWithVector(C, Args)),
- ConstructError(NoConstructorMatchingInjectSignatureErrorTag, C, Signature),
- PropagateError(R,
- ComponentFunctorIdentity(R)))))));
+ using type = If(
+ Not(IsValidSignature(AnnotatedSignature)), ConstructError(NotASignatureErrorTag, AnnotatedSignature),
+ PropagateError(CheckInjectableType(RemoveAnnotations(C)),
+ PropagateError(CheckInjectableTypeVector(RemoveAnnotationsFromVector(Args)),
+ If(IsAbstract(RemoveAnnotations(SignatureType(AnnotatedSignature))),
+ ConstructError(CannotConstructAbstractClassErrorTag,
+ RemoveAnnotations(SignatureType(AnnotatedSignature))),
+ If(Not(IsConstructibleWithVector(C, Args)),
+ ConstructError(NoConstructorMatchingInjectSignatureErrorTag, C, Signature),
+ PropagateError(R, ComponentFunctorIdentity(R)))))));
};
};
struct DeferredRegisterConstructor {
template <typename Comp, typename AnnotatedSignature>
struct apply {
- using Comp1 = AddDeferredBinding(Comp,
- ComponentFunctor(PostProcessRegisterConstructor, AnnotatedSignature));
+ using Comp1 = AddDeferredBinding(Comp, ComponentFunctor(PostProcessRegisterConstructor, AnnotatedSignature));
using type = PreProcessRegisterConstructor(Comp1, AnnotatedSignature);
};
};
@@ -629,28 +602,26 @@
return 0;
}
};
- using type = PropagateError(CheckNormalizedTypes(ConsVector(RemoveAnnotations(AnnotatedC))),
- PropagateError(CheckNormalizedTypes(ConsVector(C)),
- If(Not(IsSame(C, NormalizeType(C))),
- ConstructError(NonClassTypeErrorTag, C, NormalizeUntilStable(C)),
- If(Not(IsSame(RemoveAnnotations(AnnotatedC), NormalizeType(RemoveAnnotations(AnnotatedC)))),
- ConstructError(NonClassTypeErrorTag, RemoveAnnotations(AnnotatedC), NormalizeUntilStable(RemoveAnnotations(C))),
- // The IsSame check is not redundant because IsBaseOf returns false for non-class types (e.g. int).
- If(Not(Or(IsSame(RemoveAnnotations(AnnotatedC), C),
- IsBaseOf(RemoveAnnotations(AnnotatedC), C))),
- ConstructError(TypeMismatchInBindInstanceErrorTag, RemoveAnnotations(AnnotatedC), C),
- PropagateError(R,
- Op))))));
+ using type = PropagateError(
+ CheckNormalizedTypes(ConsVector(RemoveAnnotations(AnnotatedC))),
+ PropagateError(
+ CheckNormalizedTypes(ConsVector(C)),
+ If(Not(IsSame(C, NormalizeType(C))), ConstructError(NonClassTypeErrorTag, C, NormalizeUntilStable(C)),
+ If(Not(IsSame(RemoveAnnotations(AnnotatedC), NormalizeType(RemoveAnnotations(AnnotatedC)))),
+ ConstructError(NonClassTypeErrorTag, RemoveAnnotations(AnnotatedC),
+ NormalizeUntilStable(RemoveAnnotations(C))),
+ // The IsSame check is not redundant because IsBaseOf returns false for non-class types (e.g. int).
+ If(Not(Or(IsSame(RemoveAnnotations(AnnotatedC), C), IsBaseOf(RemoveAnnotations(AnnotatedC), C))),
+ ConstructError(TypeMismatchInBindInstanceErrorTag, RemoveAnnotations(AnnotatedC), C),
+ PropagateError(R, Op))))));
};
};
struct RegisterConstructorAsValueFactory {
- template<typename Comp,
- typename DecoratedSignature,
- typename RequiredSignature =
- Eval<RequiredLambdaSignatureForAssistedFactory(DecoratedSignature)>>
+ template <typename Comp, typename DecoratedSignature,
+ typename RequiredSignature = Eval<RequiredLambdaSignatureForAssistedFactory(DecoratedSignature)>>
struct apply;
-
+
template <typename Comp, typename DecoratedSignature, typename NakedT, typename... NakedArgs>
struct apply<Comp, DecoratedSignature, Type<NakedT(NakedArgs...)>> {
using RequiredSignature = Type<NakedT(NakedArgs...)>;
@@ -658,38 +629,29 @@
struct Op {
using Result = Eval<GetResult(Op1)>;
void operator()(FixedSizeVector<ComponentStorageEntry>& entries) {
- auto provider = [](NakedArgs... args) {
- return NakedT(std::forward<NakedArgs>(args)...);
- };
+ auto provider = [](NakedArgs... args) { return NakedT(std::forward<NakedArgs>(args)...); };
using RealOp = RegisterFactory(Comp, DecoratedSignature, Type<decltype(provider)>);
- FruitStaticAssert(IsSame(GetResult(Op1),
- GetResult(RealOp)));
+ FruitStaticAssert(IsSame(GetResult(Op1), GetResult(RealOp)));
Eval<RealOp>()(entries);
}
std::size_t numEntries() {
#ifdef FRUIT_EXTRA_DEBUG
- auto provider = [](NakedArgs... args) {
- return NakedT(std::forward<NakedArgs>(args)...);
- };
+ auto provider = [](NakedArgs... args) { return NakedT(std::forward<NakedArgs>(args)...); };
using RealOp = RegisterFactory(Comp, DecoratedSignature, Type<decltype(provider)>);
FruitAssert(Eval<Op1>().numEntries() == Eval<RealOp>().numEntries());
#endif
return Eval<Op1>().numEntries();
}
};
- using type = PropagateError(Op1,
- Op);
+ using type = PropagateError(Op1, Op);
};
};
-
struct RegisterConstructorAsUniquePtrFactory {
- template<typename Comp,
- typename DecoratedSignature,
- typename RequiredSignature =
- Eval<RequiredLambdaSignatureForAssistedFactory(DecoratedSignature)>>
+ template <typename Comp, typename DecoratedSignature,
+ typename RequiredSignature = Eval<RequiredLambdaSignatureForAssistedFactory(DecoratedSignature)>>
struct apply;
-
+
template <typename Comp, typename DecoratedSignature, typename NakedT, typename... NakedArgs>
struct apply<Comp, DecoratedSignature, Type<std::unique_ptr<NakedT>(NakedArgs...)>> {
using RequiredSignature = Type<std::unique_ptr<NakedT>(NakedArgs...)>;
@@ -701,8 +663,7 @@
return std::unique_ptr<NakedT>(new NakedT(std::forward<NakedArgs>(args)...));
};
using RealOp = RegisterFactory(Comp, DecoratedSignature, Type<decltype(provider)>);
- FruitStaticAssert(IsSame(GetResult(Op1),
- GetResult(RealOp)));
+ FruitStaticAssert(IsSame(GetResult(Op1), GetResult(RealOp)));
Eval<RealOp>()(entries);
};
std::size_t numEntries() {
@@ -716,34 +677,29 @@
return Eval<Op1>().numEntries();
}
};
-
- using type = PropagateError(Op1,
- Op);
+
+ using type = PropagateError(Op1, Op);
};
};
struct InstallComponent {
template <typename Comp, typename OtherComp>
struct apply {
- using new_RsSuperset = SetUnion(typename OtherComp::RsSuperset,
- typename Comp::RsSuperset);
- using new_Ps = SetUncheckedUnion(typename OtherComp::Ps,
- typename Comp::Ps);
- using new_NonConstRsPs = SetUnion(typename OtherComp::NonConstRsPs,
- typename Comp::NonConstRsPs);
+ using new_RsSuperset = SetUnion(typename OtherComp::RsSuperset, typename Comp::RsSuperset);
+ using new_Ps = SetUncheckedUnion(typename OtherComp::Ps, typename Comp::Ps);
+ using new_NonConstRsPs = SetUnion(typename OtherComp::NonConstRsPs, typename Comp::NonConstRsPs);
#ifndef FRUIT_NO_LOOP_CHECK
- using new_Deps = ConcatVectors(typename OtherComp::Deps,
- typename Comp::Deps);
+ using new_Deps = ConcatVectors(typename OtherComp::Deps, typename Comp::Deps);
#endif
FruitStaticAssert(IsSame(typename OtherComp::InterfaceBindings, Vector<>));
using new_InterfaceBindings = typename Comp::InterfaceBindings;
-
+
FruitStaticAssert(IsSame(typename OtherComp::DeferredBindingFunctors, EmptyList));
using new_DeferredBindingFunctors = typename Comp::DeferredBindingFunctors;
-
+
using R = ConsComp(new_RsSuperset, new_Ps, new_NonConstRsPs,
#ifndef FRUIT_NO_LOOP_CHECK
- new_Deps,
+ new_Deps,
#endif
new_InterfaceBindings, new_DeferredBindingFunctors);
struct Op {
@@ -755,8 +711,7 @@
};
using InterfacePs = VectorToSetUnchecked(GetMapKeys(typename Comp::InterfaceBindings));
using AllPs = SetUncheckedUnion(InterfacePs, typename Comp::Ps);
- using DuplicateTypes = SetIntersection(typename OtherComp::Ps,
- AllPs);
+ using DuplicateTypes = SetIntersection(typename OtherComp::Ps, AllPs);
using CompConstPs = SetDifference(typename Comp::Ps, typename Comp::NonConstRsPs);
using CompRs = SetDifference(typename Comp::RsSuperset, typename Comp::Ps);
using CompNonConstRs = SetIntersection(CompRs, typename Comp::NonConstRsPs);
@@ -766,15 +721,14 @@
using OtherCompNonConstRs = SetIntersection(OtherCompRs, typename OtherComp::NonConstRsPs);
using type = If(Not(IsDisjoint(typename OtherComp::Ps, AllPs)),
- ConstructErrorWithArgVector(DuplicateTypesInComponentErrorTag,
- SetToVector(DuplicateTypes)),
- If(Not(IsDisjoint(CompConstPs, OtherCompNonConstRs)),
- ConstructError(NonConstBindingRequiredButConstBindingProvidedErrorTag,
- GetArbitrarySetElement(SetIntersection(CompConstPs, OtherCompNonConstRs))),
- If(Not(IsDisjoint(CompNonConstRs, OtherCompConstPs)),
- ConstructError(NonConstBindingRequiredButConstBindingProvidedErrorTag,
- GetArbitrarySetElement(SetIntersection(CompNonConstRs, OtherCompConstPs))),
- Op)));
+ ConstructErrorWithArgVector(DuplicateTypesInComponentErrorTag, SetToVector(DuplicateTypes)),
+ If(Not(IsDisjoint(CompConstPs, OtherCompNonConstRs)),
+ ConstructError(NonConstBindingRequiredButConstBindingProvidedErrorTag,
+ GetArbitrarySetElement(SetIntersection(CompConstPs, OtherCompNonConstRs))),
+ If(Not(IsDisjoint(CompNonConstRs, OtherCompConstPs)),
+ ConstructError(NonConstBindingRequiredButConstBindingProvidedErrorTag,
+ GetArbitrarySetElement(SetIntersection(CompNonConstRs, OtherCompConstPs))),
+ Op)));
};
};
@@ -799,9 +753,9 @@
template <typename SourceComp, typename DestComp>
struct apply {
using SourcePs = typename SourceComp::Ps;
- using DestPs = typename DestComp::Ps;
+ using DestPs = typename DestComp::Ps;
using SourceRs = SetDifference(typename SourceComp::RsSuperset, typename SourceComp::Ps);
- using DestRs = SetDifference(typename DestComp::RsSuperset, typename DestComp::Ps);
+ using DestRs = SetDifference(typename DestComp::RsSuperset, typename DestComp::Ps);
using NonConstSourceRs = SetIntersection(SourceRs, typename SourceComp::NonConstRsPs);
using NonConstDestPs = SetIntersection(DestPs, typename DestComp::NonConstRsPs);
using NonConstDestRs = SetIntersection(DestRs, typename DestComp::NonConstRsPs);
@@ -815,30 +769,23 @@
// except:
// * The ones already provided by the old component (if they have the right constness).
// * The ones required by the new one (if they have the right constness).
- using ToRegister =
- SetUnion(
- // The types that we must provide and aren't currently provided
- SetDifference(SetUnion(DestPs, SourceRs),
- SetUnion(DestRs, SourcePs)),
- // And the ones that are currently provided as const but that we need to provide as non-const
- SetIntersection(SetUnion(NonConstDestPs, NonConstSourceRs),
- SetUnion(ConstDestRs, ConstSourcePs)));
- using NonConstTypesToRegister = SetIntersection(ToRegister,
- SetUnion(typename SourceComp::NonConstRsPs, typename DestComp::NonConstRsPs));
- using type = EnsureProvidedTypes(SourceComp, DestRs, NonConstDestRs, SetToVector(ToRegister), NonConstTypesToRegister);
-
- // Not needed, just double-checking.
- // Uses FruitStaticAssert instead of FruitDelegateCheck so that it's checked only in debug mode.
+ using ToRegister = SetUnion(
+ // The types that we must provide and aren't currently provided
+ SetDifference(SetUnion(DestPs, SourceRs), SetUnion(DestRs, SourcePs)),
+ // And the ones that are currently provided as const but that we need to provide as non-const
+ SetIntersection(SetUnion(NonConstDestPs, NonConstSourceRs), SetUnion(ConstDestRs, ConstSourcePs)));
+ using NonConstTypesToRegister = SetIntersection(ToRegister, SetUnion(typename SourceComp::NonConstRsPs,
+ typename DestComp::NonConstRsPs));
+ using type = EnsureProvidedTypes(SourceComp, DestRs, NonConstDestRs, SetToVector(ToRegister),
+ NonConstTypesToRegister);
+
+// Not needed, just double-checking.
+// Uses FruitStaticAssert instead of FruitDelegateCheck so that it's checked only in debug mode.
#ifdef FRUIT_EXTRA_DEBUG
FruitDelegateCheck(
- If(CatchAll(
- PropagateError(type,
- PropagateError(Id<GetResult(type)>,
- Bool<false>)),
- IsErrorExceptionHandler),
- // We're going to return an error soon anyway, we don't want to interfere by reporting this one.
- None,
- CheckComponentEntails(GetResult(type), DestComp)));
+ If(CatchAll(PropagateError(type, PropagateError(Id<GetResult(type)>, Bool<false>)), IsErrorExceptionHandler),
+ // We're going to return an error soon anyway, we don't want to interfere by reporting this one.
+ None, CheckComponentEntails(GetResult(type), DestComp)));
#endif // FRUIT_EXTRA_DEBUG
};
};
@@ -846,25 +793,24 @@
struct ProcessDeferredBindings {
template <typename Comp>
struct apply;
-
+
template <typename RsSupersetParam, typename PsParam, typename NonConstRsPsParam,
#ifndef FRUIT_NO_LOOP_CHECK
- typename DepsParam,
+ typename DepsParam,
#endif
typename InterfaceBindingsParam, typename DeferredBindingFunctors>
struct apply<Comp<RsSupersetParam, PsParam, NonConstRsPsParam,
#ifndef FRUIT_NO_LOOP_CHECK
- DepsParam,
+ DepsParam,
#endif
InterfaceBindingsParam, DeferredBindingFunctors>> {
// Comp1 is the same as Comp, but without the DeferredBindingFunctors.
using Comp1 = ConsComp(RsSupersetParam, PsParam, NonConstRsPsParam,
#ifndef FRUIT_NO_LOOP_CHECK
- DepsParam,
+ DepsParam,
#endif
InterfaceBindingsParam, EmptyList);
- using type = Call(FoldList(DeferredBindingFunctors, Compose2ComponentFunctors, ComponentFunctorIdentity),
- Comp1);
+ using type = Call(FoldList(DeferredBindingFunctors, Compose2ComponentFunctors, ComponentFunctorIdentity), Comp1);
};
};
@@ -877,136 +823,129 @@
template <typename T>
struct apply<Error<NoBindingFoundErrorTag, T>> {
- using type = If(IsSame(Type<T>, AnnotatedCFunctor),
- ConstructNoBindingFoundError(AnnotatedCUniquePtrFunctor),
+ using type = If(IsSame(Type<T>, AnnotatedCFunctor), ConstructNoBindingFoundError(AnnotatedCUniquePtrFunctor),
ConstructError(NoBindingFoundErrorTag, Type<T>));
};
template <typename T1, typename T2>
struct apply<Error<NoBindingFoundForAbstractClassErrorTag, T1, T2>> {
- using type = If(IsSame(Type<T1>, AnnotatedCFunctor),
- ConstructNoBindingFoundError(AnnotatedCUniquePtrFunctor),
+ using type = If(IsSame(Type<T1>, AnnotatedCFunctor), ConstructNoBindingFoundError(AnnotatedCUniquePtrFunctor),
ConstructError(NoBindingFoundForAbstractClassErrorTag, Type<T1>, Type<T2>));
};
};
struct AutoRegisterFactoryHelper {
-
+
// General case, no way to bind it.
- template <typename Comp,
- typename TargetRequirements,
- typename TargetNonConstRequirements,
- typename InterfaceBinding,
- typename has_inject_annotation,
- typename is_abstract,
- typename C,
- typename AnnotatedSignature,
+ template <typename Comp, typename TargetRequirements, typename TargetNonConstRequirements, typename InterfaceBinding,
+ typename has_inject_annotation, typename is_abstract, typename C, typename AnnotatedSignature,
typename... Args>
struct apply {
- using AnnotatedC = SignatureType(AnnotatedSignature);
- using CFunctor = ConsStdFunction(RemoveAnnotationsFromSignature(AnnotatedSignature));
+ using AnnotatedC = SignatureType(AnnotatedSignature);
+ using CFunctor = ConsStdFunction(RemoveAnnotationsFromSignature(AnnotatedSignature));
using AnnotatedCFunctor = CopyAnnotation(AnnotatedC, CFunctor);
- using type = If(IsAbstract(C),
- ConstructError(NoBindingFoundForAbstractClassErrorTag, AnnotatedCFunctor, C),
- ConstructError(NoBindingFoundErrorTag, AnnotatedCFunctor));
+ using type = If(IsAbstract(C), ConstructError(NoBindingFoundForAbstractClassErrorTag, AnnotatedCFunctor, C),
+ ConstructError(NoBindingFoundErrorTag, AnnotatedCFunctor));
};
// No way to bind it (we need this specialization too to ensure that the specialization below
// is not chosen for AnnotatedC=None).
- template <typename Comp, typename TargetRequirements, typename TargetNonConstRequirements, typename unused1, typename unused2,
- typename NakedI, typename AnnotatedSignature, typename... Args>
- struct apply<Comp, TargetRequirements, TargetNonConstRequirements, None, unused1, unused2, Type<std::unique_ptr<NakedI>>,
- AnnotatedSignature, Args...> {
- using AnnotatedC = SignatureType(AnnotatedSignature);
- using CFunctor = ConsStdFunction(RemoveAnnotationsFromSignature(AnnotatedSignature));
+ template <typename Comp, typename TargetRequirements, typename TargetNonConstRequirements, typename unused1,
+ typename unused2, typename NakedI, typename AnnotatedSignature, typename... Args>
+ struct apply<Comp, TargetRequirements, TargetNonConstRequirements, None, unused1, unused2,
+ Type<std::unique_ptr<NakedI>>, AnnotatedSignature, Args...> {
+ using AnnotatedC = SignatureType(AnnotatedSignature);
+ using CFunctor = ConsStdFunction(RemoveAnnotationsFromSignature(AnnotatedSignature));
using AnnotatedCFunctor = CopyAnnotation(AnnotatedC, CFunctor);
using type = If(IsAbstract(Type<NakedI>),
ConstructError(NoBindingFoundForAbstractClassErrorTag, AnnotatedCFunctor, Type<NakedI>),
- ConstructError(NoBindingFoundErrorTag, AnnotatedCFunctor));
+ ConstructError(NoBindingFoundErrorTag, AnnotatedCFunctor));
};
-
- // AnnotatedI has an interface binding, use it and look for a factory that returns the type that AnnotatedI is bound to.
- template <typename Comp, typename TargetRequirements, typename TargetNonConstRequirements, typename AnnotatedC, typename unused1, typename unused2,
- typename NakedI, typename AnnotatedSignature, typename... Args>
- struct apply<Comp, TargetRequirements, TargetNonConstRequirements, AnnotatedC, unused1, unused2, Type<std::unique_ptr<NakedI>>,
- AnnotatedSignature, Args...> {
- using I = Type<NakedI>;
- using AnnotatedI = CopyAnnotation(SignatureType(AnnotatedSignature), I);
- using C = RemoveAnnotations(AnnotatedC);
- using IFunctor = ConsStdFunction(ConsSignature(ConsUniquePtr(I), Args...));
- using CFunctor = ConsStdFunction(ConsSignature(ConsUniquePtr(C), Args...));
- using AnnotatedIFunctor = CopyAnnotation(AnnotatedI, IFunctor);
- using AnnotatedCFunctor = CopyAnnotation(AnnotatedC, CFunctor);
-
- using ProvidedSignature = ConsSignature(AnnotatedIFunctor, CopyAnnotation(AnnotatedC, ConsConstReference(CFunctor)));
- using LambdaSignature = ConsSignature(IFunctor, ConsConstReference(CFunctor));
-
- using F1 = ComponentFunctor(EnsureProvidedType,
- TargetRequirements, TargetNonConstRequirements, AnnotatedCFunctor, Bool<false>);
- using F2 = ComponentFunctor(PreProcessRegisterProvider, ProvidedSignature, LambdaSignature);
- using F3 = ComponentFunctor(PostProcessRegisterProvider, ProvidedSignature, LambdaSignature);
- using R = Call(ComposeFunctors(F1, F2, F3), Comp);
- struct Op {
- using Result = Eval<GetResult(R)>;
- void operator()(FixedSizeVector<ComponentStorageEntry>& entries) {
- using NakedC = UnwrapType<Eval<C>>;
- auto provider = [](const UnwrapType<Eval<CFunctor>>& fun) {
- return UnwrapType<Eval<IFunctor>>([=](typename TypeUnwrapper<Args>::type... args) {
- NakedC* c = fun(args...).release();
- NakedI* i = static_cast<NakedI*>(c);
- return std::unique_ptr<NakedI>(i);
- });
- };
- using RealF2 = ComponentFunctor(PreProcessRegisterProvider, ProvidedSignature, Type<decltype(provider)>);
- using RealF3 = ComponentFunctor(PostProcessRegisterProvider, ProvidedSignature, Type<decltype(provider)>);
- using RealOp = Call(ComposeFunctors(F1, RealF2, RealF3), Comp);
- FruitStaticAssert(IsSame(GetResult(RealOp), GetResult(R)));
- Eval<RealOp>()(entries);
- }
- std::size_t numEntries() {
+
+ // AnnotatedI has an interface binding, use it and look for a factory that returns the type that AnnotatedI is bound
+ // to.
+ template <typename Comp, typename TargetRequirements, typename TargetNonConstRequirements, typename AnnotatedC,
+ typename unused1, typename unused2, typename NakedI, typename AnnotatedSignature, typename... Args>
+ struct apply<Comp, TargetRequirements, TargetNonConstRequirements, AnnotatedC, unused1, unused2,
+ Type<std::unique_ptr<NakedI>>, AnnotatedSignature, Args...> {
+ using I = Type<NakedI>;
+ using AnnotatedI = CopyAnnotation(SignatureType(AnnotatedSignature), I);
+ using C = RemoveAnnotations(AnnotatedC);
+ using IFunctor = ConsStdFunction(ConsSignature(ConsUniquePtr(I), Args...));
+ using CFunctor = ConsStdFunction(ConsSignature(ConsUniquePtr(C), Args...));
+ using AnnotatedIFunctor = CopyAnnotation(AnnotatedI, IFunctor);
+ using AnnotatedCFunctor = CopyAnnotation(AnnotatedC, CFunctor);
+
+ using ProvidedSignature = ConsSignature(AnnotatedIFunctor,
+ CopyAnnotation(AnnotatedC, ConsConstReference(CFunctor)));
+ using LambdaSignature = ConsSignature(IFunctor, ConsConstReference(CFunctor));
+
+ using F1 = ComponentFunctor(EnsureProvidedType, TargetRequirements, TargetNonConstRequirements, AnnotatedCFunctor,
+ Bool<false>);
+ using F2 = ComponentFunctor(PreProcessRegisterProvider, ProvidedSignature, LambdaSignature);
+ using F3 = ComponentFunctor(PostProcessRegisterProvider, ProvidedSignature, LambdaSignature);
+ using R = Call(ComposeFunctors(F1, F2, F3), Comp);
+ struct Op {
+ using Result = Eval<GetResult(R)>;
+ void operator()(FixedSizeVector<ComponentStorageEntry>& entries) {
+ using NakedC = UnwrapType<Eval<C>>;
+ auto provider = [](const UnwrapType<Eval<CFunctor>>& fun) {
+ return UnwrapType<Eval<IFunctor>>([=](typename TypeUnwrapper<Args>::type... args) {
+ NakedC* c = fun(args...).release();
+ NakedI* i = static_cast<NakedI*>(c);
+ return std::unique_ptr<NakedI>(i);
+ });
+ };
+ using RealF2 = ComponentFunctor(PreProcessRegisterProvider, ProvidedSignature, Type<decltype(provider)>);
+ using RealF3 = ComponentFunctor(PostProcessRegisterProvider, ProvidedSignature, Type<decltype(provider)>);
+ using RealOp = Call(ComposeFunctors(F1, RealF2, RealF3), Comp);
+ FruitStaticAssert(IsSame(GetResult(RealOp), GetResult(R)));
+ Eval<RealOp>()(entries);
+ }
+ std::size_t numEntries() {
#ifdef FRUIT_EXTRA_DEBUG
- using NakedC = UnwrapType<Eval<C>>;
- auto provider = [](const UnwrapType<Eval<CFunctor>>& fun) {
- return UnwrapType<Eval<IFunctor>>([=](typename TypeUnwrapper<Args>::type... args) {
- NakedC* c = fun(args...).release();
- NakedI* i = static_cast<NakedI*>(c);
- return std::unique_ptr<NakedI>(i);
- });
- };
- using RealF2 = ComponentFunctor(PreProcessRegisterProvider, ProvidedSignature, Type<decltype(provider)>);
- using RealF3 = ComponentFunctor(PostProcessRegisterProvider, ProvidedSignature, Type<decltype(provider)>);
- using RealOp = Call(ComposeFunctors(F1, RealF2, RealF3), Comp);
- FruitAssert(Eval<R>().numEntries() == Eval<RealOp>().numEntries());
+ using NakedC = UnwrapType<Eval<C>>;
+ auto provider = [](const UnwrapType<Eval<CFunctor>>& fun) {
+ return UnwrapType<Eval<IFunctor>>([=](typename TypeUnwrapper<Args>::type... args) {
+ NakedC* c = fun(args...).release();
+ NakedI* i = static_cast<NakedI*>(c);
+ return std::unique_ptr<NakedI>(i);
+ });
+ };
+ using RealF2 = ComponentFunctor(PreProcessRegisterProvider, ProvidedSignature, Type<decltype(provider)>);
+ using RealF3 = ComponentFunctor(PostProcessRegisterProvider, ProvidedSignature, Type<decltype(provider)>);
+ using RealOp = Call(ComposeFunctors(F1, RealF2, RealF3), Comp);
+ FruitAssert(Eval<R>().numEntries() == Eval<RealOp>().numEntries());
#endif
- return Eval<R>().numEntries();
- }
- };
- using type = PropagateError(R,
- If(Not(HasVirtualDestructor(I)),
- ConstructError(FactoryBindingForUniquePtrOfClassWithNoVirtualDestructorErrorTag, IFunctor, CFunctor),
- Op));
+ return Eval<R>().numEntries();
+ }
+ };
+ using type = PropagateError(R, If(Not(HasVirtualDestructor(I)),
+ ConstructError(FactoryBindingForUniquePtrOfClassWithNoVirtualDestructorErrorTag,
+ IFunctor, CFunctor),
+ Op));
};
// C doesn't have an interface binding as interface, nor an INJECT annotation, and is not an abstract class.
// Bind std::function<unique_ptr<C>(Args...)> to std::function<C(Args...)> (possibly with annotations).
- template <typename Comp, typename TargetRequirements, typename TargetNonConstRequirements, typename NakedC, typename AnnotatedSignature,
- typename... Args>
+ template <typename Comp, typename TargetRequirements, typename TargetNonConstRequirements, typename NakedC,
+ typename AnnotatedSignature, typename... Args>
struct apply<Comp, TargetRequirements, TargetNonConstRequirements, None, Bool<false>, Bool<false>,
Type<std::unique_ptr<NakedC>>, AnnotatedSignature, Args...> {
using C = Type<NakedC>;
- using CFunctor = ConsStdFunction(ConsSignature(C, Args...));
+ using CFunctor = ConsStdFunction(ConsSignature(C, Args...));
using CUniquePtrFunctor = ConsStdFunction(ConsSignature(ConsUniquePtr(C), Args...));
- using AnnotatedCUniquePtr = SignatureType(AnnotatedSignature);
- using AnnotatedC = CopyAnnotation(AnnotatedCUniquePtr, C);
- using AnnotatedCFunctor = CopyAnnotation(AnnotatedCUniquePtr, CFunctor);
+ using AnnotatedCUniquePtr = SignatureType(AnnotatedSignature);
+ using AnnotatedC = CopyAnnotation(AnnotatedCUniquePtr, C);
+ using AnnotatedCFunctor = CopyAnnotation(AnnotatedCUniquePtr, CFunctor);
using AnnotatedCUniquePtrFunctor = CopyAnnotation(AnnotatedCUniquePtr, CUniquePtrFunctor);
- using AnnotatedCFunctorRef = CopyAnnotation(AnnotatedCUniquePtr, ConsConstReference(CFunctor));
-
+ using AnnotatedCFunctorRef = CopyAnnotation(AnnotatedCUniquePtr, ConsConstReference(CFunctor));
+
using ProvidedSignature = ConsSignature(AnnotatedCUniquePtrFunctor, AnnotatedCFunctorRef);
using LambdaSignature = ConsSignature(CUniquePtrFunctor, ConsConstReference(CFunctor));
-
- using F1 = ComponentFunctor(EnsureProvidedType,
- TargetRequirements, TargetNonConstRequirements, AnnotatedCFunctor, Bool<false>);
+
+ using F1 = ComponentFunctor(EnsureProvidedType, TargetRequirements, TargetNonConstRequirements, AnnotatedCFunctor,
+ Bool<false>);
using F2 = ComponentFunctor(PreProcessRegisterProvider, ProvidedSignature, LambdaSignature);
using F3 = ComponentFunctor(PostProcessRegisterProvider, ProvidedSignature, LambdaSignature);
using R = Call(ComposeFunctors(F1, F2, F3), Comp);
@@ -1041,21 +980,23 @@
return Eval<R>().numEntries();
}
};
-
- using ErrorHandler = AutoRegisterFactoryHelperErrorHandler<Eval<AnnotatedCFunctor>, Eval<AnnotatedCUniquePtrFunctor>>;
-
+
+ using ErrorHandler =
+ AutoRegisterFactoryHelperErrorHandler<Eval<AnnotatedCFunctor>, Eval<AnnotatedCUniquePtrFunctor>>;
+
// If we are about to report a NoBindingFound/NoBindingFoundForAbstractClass error for AnnotatedCFunctor,
// report one for std::function<std::unique_ptr<C>(Args...)> instead,
// otherwise we'd report an error about a type that the user doesn't expect.
- using type = PropagateError(Catch(Catch(R,
- NoBindingFoundErrorTag, ErrorHandler),
+ using type = PropagateError(Catch(Catch(R, NoBindingFoundErrorTag, ErrorHandler),
NoBindingFoundForAbstractClassErrorTag, ErrorHandler),
- Op);
+ Op);
};
// C has an Inject typedef, use it. unique_ptr case.
- template <typename Comp, typename TargetRequirements, typename TargetNonConstRequirements, typename unused, typename NakedC, typename AnnotatedSignature, typename... Args>
- struct apply<Comp, TargetRequirements, TargetNonConstRequirements, None, Bool<true>, unused, Type<std::unique_ptr<NakedC>>, AnnotatedSignature, Args...> {
+ template <typename Comp, typename TargetRequirements, typename TargetNonConstRequirements, typename unused,
+ typename NakedC, typename AnnotatedSignature, typename... Args>
+ struct apply<Comp, TargetRequirements, TargetNonConstRequirements, None, Bool<true>, unused,
+ Type<std::unique_ptr<NakedC>>, AnnotatedSignature, Args...> {
using AnnotatedCUniquePtr = SignatureType(AnnotatedSignature);
using AnnotatedC = CopyAnnotation(AnnotatedCUniquePtr, RemoveUniquePtr(RemoveAnnotations(AnnotatedCUniquePtr)));
using DecoratedSignatureReturningValue = GetInjectAnnotation(AnnotatedC);
@@ -1065,149 +1006,99 @@
using ActualSignatureInInjectionTypedef = ConsSignatureWithVector(SignatureType(DecoratedSignature),
RemoveNonAssisted(DecoratedSignatureArgs));
using NonAssistedArgs = RemoveAssisted(DecoratedSignatureArgs);
-
+
using F1 = ComponentFunctor(RegisterConstructorAsUniquePtrFactory, DecoratedSignature);
- using F2 = ComponentFunctor(EnsureProvidedTypes,
- TargetRequirements,
- TargetNonConstRequirements,
- NormalizeTypeVector(NonAssistedArgs),
- NormalizedNonConstTypesIn(NonAssistedArgs));
-
+ using F2 = ComponentFunctor(EnsureProvidedTypes, TargetRequirements, TargetNonConstRequirements,
+ NormalizeTypeVector(NonAssistedArgs), NormalizedNonConstTypesIn(NonAssistedArgs));
+
using type = If(Not(IsSame(AnnotatedSignature, ActualSignatureInInjectionTypedef)),
- ConstructError(FunctorSignatureDoesNotMatchErrorTag, AnnotatedSignature, ActualSignatureInInjectionTypedef),
- Call(ComposeFunctors(F1, F2), Comp));
+ ConstructError(FunctorSignatureDoesNotMatchErrorTag, AnnotatedSignature,
+ ActualSignatureInInjectionTypedef),
+ Call(ComposeFunctors(F1, F2), Comp));
};
// C has an Inject typedef, use it. Value (not unique_ptr) case.
- template <typename Comp, typename TargetRequirements, typename TargetNonConstRequirements, typename unused, typename NakedC, typename AnnotatedSignature, typename... Args>
- struct apply<Comp, TargetRequirements, TargetNonConstRequirements, None, Bool<true>, unused, Type<NakedC>, AnnotatedSignature, Args...> {
+ template <typename Comp, typename TargetRequirements, typename TargetNonConstRequirements, typename unused,
+ typename NakedC, typename AnnotatedSignature, typename... Args>
+ struct apply<Comp, TargetRequirements, TargetNonConstRequirements, None, Bool<true>, unused, Type<NakedC>,
+ AnnotatedSignature, Args...> {
using AnnotatedC = SignatureType(AnnotatedSignature);
using DecoratedSignature = GetInjectAnnotation(AnnotatedC);
using DecoratedSignatureArgs = SignatureArgs(DecoratedSignature);
using ActualSignatureInInjectionTypedef = ConsSignatureWithVector(SignatureType(DecoratedSignature),
RemoveNonAssisted(DecoratedSignatureArgs));
using NonAssistedArgs = RemoveAssisted(DecoratedSignatureArgs);
-
+
using F1 = ComponentFunctor(RegisterConstructorAsValueFactory, DecoratedSignature);
- using F2 = ComponentFunctor(EnsureProvidedTypes,
- TargetRequirements,
- TargetNonConstRequirements,
- NormalizeTypeVector(NonAssistedArgs),
- NormalizedNonConstTypesIn(NonAssistedArgs));
-
+ using F2 = ComponentFunctor(EnsureProvidedTypes, TargetRequirements, TargetNonConstRequirements,
+ NormalizeTypeVector(NonAssistedArgs), NormalizedNonConstTypesIn(NonAssistedArgs));
+
using type = If(Not(IsSame(AnnotatedSignature, ActualSignatureInInjectionTypedef)),
- ConstructError(FunctorSignatureDoesNotMatchErrorTag, AnnotatedSignature, ActualSignatureInInjectionTypedef),
- Call(ComposeFunctors(F1, F2), Comp));
+ ConstructError(FunctorSignatureDoesNotMatchErrorTag, AnnotatedSignature,
+ ActualSignatureInInjectionTypedef),
+ Call(ComposeFunctors(F1, F2), Comp));
};
};
struct AutoRegister {
// The types in TargetRequirements will not be auto-registered.
- template <typename Comp,
- typename TargetRequirements,
- typename TargetNonConstRequirements,
- typename AnnotatedC>
+ template <typename Comp, typename TargetRequirements, typename TargetNonConstRequirements, typename AnnotatedC>
struct apply;
// Tries to register C by looking for a typedef called Inject inside C.
- template <typename Comp,
- typename TargetRequirements,
- typename TargetNonConstRequirements,
- typename AnnotatedC>
+ template <typename Comp, typename TargetRequirements, typename TargetNonConstRequirements, typename AnnotatedC>
struct apply {
using CHasInjectAnnotation = HasInjectAnnotation(RemoveAnnotations(AnnotatedC));
using Inject = GetInjectAnnotation(AnnotatedC);
using CRequirements = NormalizeTypeVector(SignatureArgs(Inject));
using CNonConstRequirements = NormalizedNonConstTypesIn(SignatureArgs(Inject));
- using F = ComposeFunctors(
- ComponentFunctor(PreProcessRegisterConstructor, Inject),
- ComponentFunctor(PostProcessRegisterConstructor, Inject),
- ComponentFunctor(EnsureProvidedTypes,
- TargetRequirements, TargetNonConstRequirements, CRequirements, CNonConstRequirements));
- using type = If(CHasInjectAnnotation,
- Call(F, Comp),
- ConstructNoBindingFoundError(AnnotatedC));
+ using F = ComposeFunctors(ComponentFunctor(PreProcessRegisterConstructor, Inject),
+ ComponentFunctor(PostProcessRegisterConstructor, Inject),
+ ComponentFunctor(EnsureProvidedTypes, TargetRequirements, TargetNonConstRequirements,
+ CRequirements, CNonConstRequirements));
+ using type = If(CHasInjectAnnotation, Call(F, Comp), ConstructNoBindingFoundError(AnnotatedC));
};
- template <typename Comp,
- typename TargetRequirements,
- typename TargetNonConstRequirements,
- typename NakedC,
+ template <typename Comp, typename TargetRequirements, typename TargetNonConstRequirements, typename NakedC,
typename... NakedArgs>
- struct apply<Comp,
- TargetRequirements,
- TargetNonConstRequirements,
- Type<std::function<NakedC(NakedArgs...)>>> {
- using type = AutoRegisterFactoryHelper(Comp,
- TargetRequirements,
- TargetNonConstRequirements,
+ struct apply<Comp, TargetRequirements, TargetNonConstRequirements, Type<std::function<NakedC(NakedArgs...)>>> {
+ using type = AutoRegisterFactoryHelper(Comp, TargetRequirements, TargetNonConstRequirements,
FindInMap(typename Comp::InterfaceBindings, Type<NakedC>),
- HasInjectAnnotation(Type<NakedC>),
- IsAbstract(Type<NakedC>),
- Type<NakedC>,
- Type<NakedC(NakedArgs...)>,
- Id<RemoveAnnotations(Type<NakedArgs>)>...);
- };
+ HasInjectAnnotation(Type<NakedC>), IsAbstract(Type<NakedC>), Type<NakedC>,
+ Type<NakedC(NakedArgs...)>, Id<RemoveAnnotations(Type<NakedArgs>)>...);
+ };
- template <typename Comp,
- typename TargetRequirements,
- typename TargetNonConstRequirements,
- typename NakedC,
+ template <typename Comp, typename TargetRequirements, typename TargetNonConstRequirements, typename NakedC,
typename... NakedArgs>
- struct apply<Comp,
- TargetRequirements,
- TargetNonConstRequirements,
+ struct apply<Comp, TargetRequirements, TargetNonConstRequirements,
Type<std::function<std::unique_ptr<NakedC>(NakedArgs...)>>> {
- using type = AutoRegisterFactoryHelper(Comp,
- TargetRequirements,
- TargetNonConstRequirements,
+ using type = AutoRegisterFactoryHelper(Comp, TargetRequirements, TargetNonConstRequirements,
FindInMap(typename Comp::InterfaceBindings, Type<NakedC>),
- HasInjectAnnotation(Type<NakedC>),
- IsAbstract(Type<NakedC>),
- Type<std::unique_ptr<NakedC>>,
- Type<std::unique_ptr<NakedC>(NakedArgs...)>,
+ HasInjectAnnotation(Type<NakedC>), IsAbstract(Type<NakedC>),
+ Type<std::unique_ptr<NakedC>>, Type<std::unique_ptr<NakedC>(NakedArgs...)>,
Id<RemoveAnnotations(Type<NakedArgs>)>...);
};
- template <typename Comp,
- typename TargetRequirements,
- typename TargetNonConstRequirements,
- typename Annotation,
- typename NakedC,
- typename... NakedArgs>
- struct apply<Comp,
- TargetRequirements,
- TargetNonConstRequirements,
+ template <typename Comp, typename TargetRequirements, typename TargetNonConstRequirements, typename Annotation,
+ typename NakedC, typename... NakedArgs>
+ struct apply<Comp, TargetRequirements, TargetNonConstRequirements,
Type<fruit::Annotated<Annotation, std::function<NakedC(NakedArgs...)>>>> {
- using type = AutoRegisterFactoryHelper(Comp,
- TargetRequirements,
- TargetNonConstRequirements,
+ using type = AutoRegisterFactoryHelper(Comp, TargetRequirements, TargetNonConstRequirements,
FindInMap(typename Comp::InterfaceBindings,
Type<fruit::Annotated<Annotation, NakedC>>),
- HasInjectAnnotation(Type<NakedC>),
- IsAbstract(Type<NakedC>),
- Type<NakedC>,
+ HasInjectAnnotation(Type<NakedC>), IsAbstract(Type<NakedC>), Type<NakedC>,
Type<fruit::Annotated<Annotation, NakedC>(NakedArgs...)>,
Id<RemoveAnnotations(Type<NakedArgs>)>...);
- };
+ };
- template <typename Comp,
- typename TargetRequirements,
- typename TargetNonConstRequirements,
- typename Annotation,
- typename NakedC,
- typename... NakedArgs>
- struct apply<Comp,
- TargetRequirements,
- TargetNonConstRequirements,
+ template <typename Comp, typename TargetRequirements, typename TargetNonConstRequirements, typename Annotation,
+ typename NakedC, typename... NakedArgs>
+ struct apply<Comp, TargetRequirements, TargetNonConstRequirements,
Type<fruit::Annotated<Annotation, std::function<std::unique_ptr<NakedC>(NakedArgs...)>>>> {
- using type = AutoRegisterFactoryHelper(Comp,
- TargetRequirements,
- TargetNonConstRequirements,
+ using type = AutoRegisterFactoryHelper(Comp, TargetRequirements, TargetNonConstRequirements,
FindInMap(typename Comp::InterfaceBindings,
Type<fruit::Annotated<Annotation, NakedC>>),
- HasInjectAnnotation(Type<NakedC>),
- IsAbstract(Type<NakedC>),
+ HasInjectAnnotation(Type<NakedC>), IsAbstract(Type<NakedC>),
Type<std::unique_ptr<NakedC>>,
Type<fruit::Annotated<Annotation, std::unique_ptr<NakedC>>(NakedArgs...)>,
Id<RemoveAnnotations(Type<NakedArgs>)>...);
@@ -1237,70 +1128,62 @@
};
struct EnsureProvidedType {
- template <typename Comp,
- typename TargetRequirements,
- typename TargetNonConstRequirements,
- typename AnnotatedT,
+ template <typename Comp, typename TargetRequirements, typename TargetNonConstRequirements, typename AnnotatedT,
typename NonConstBindingRequired>
struct apply {
using AnnotatedC = NormalizeType(AnnotatedT);
using AnnotatedCImpl = FindInMap(typename Comp::InterfaceBindings, AnnotatedC);
using AutoRegisterResult = AutoRegister(Comp, TargetRequirements, TargetNonConstRequirements, AnnotatedC);
using ErrorHandler = EnsureProvidedTypeErrorHandler<AnnotatedT>;
- using type =
- If(IsInSet(AnnotatedC, typename Comp::Ps),
- If(And(NonConstBindingRequired, Not(IsInSet(AnnotatedC, typename Comp::NonConstRsPs))),
- ConstructError(NonConstBindingRequiredButConstBindingProvidedErrorTag, AnnotatedC),
- ComponentFunctorIdentity(Comp)),
+ using type = If(
+ IsInSet(AnnotatedC, typename Comp::Ps),
+ If(And(NonConstBindingRequired, Not(IsInSet(AnnotatedC, typename Comp::NonConstRsPs))),
+ ConstructError(NonConstBindingRequiredButConstBindingProvidedErrorTag, AnnotatedC),
+ ComponentFunctorIdentity(Comp)),
If(And(IsInSet(AnnotatedC, TargetRequirements),
Or(Not(NonConstBindingRequired), IsInSet(AnnotatedC, TargetNonConstRequirements))),
- // The type is already in the target requirements with the desired constness, nothing to do.
- ComponentFunctorIdentity(Comp),
- If(Not(IsNone(AnnotatedCImpl)),
- // Has an interface binding.
- Call(ComposeFunctors(ComponentFunctor(ProcessInterfaceBinding,
- AnnotatedC, AnnotatedCImpl, NonConstBindingRequired),
- ComponentFunctor(EnsureProvidedType,
- TargetRequirements, TargetNonConstRequirements, AnnotatedCImpl, NonConstBindingRequired)),
- Comp),
- // If we are about to report a NoBindingFound/NoBindingFoundForAbstractClass error for AnnotatedT and the target
- // component has a Required<const T>, we can report a more specific error (rather than the usual
- // "binding not found").
- If(And(NonConstBindingRequired, IsInSet(AnnotatedC, TargetRequirements)),
- Catch(Catch(AutoRegisterResult,
- NoBindingFoundErrorTag, ErrorHandler),
- NoBindingFoundForAbstractClassErrorTag, ErrorHandler),
- AutoRegisterResult))));
+ // The type is already in the target requirements with the desired constness, nothing to do.
+ ComponentFunctorIdentity(Comp),
+ If(Not(IsNone(AnnotatedCImpl)),
+ // Has an interface binding.
+ Call(ComposeFunctors(ComponentFunctor(ProcessInterfaceBinding, AnnotatedC, AnnotatedCImpl,
+ NonConstBindingRequired),
+ ComponentFunctor(EnsureProvidedType, TargetRequirements, TargetNonConstRequirements,
+ AnnotatedCImpl, NonConstBindingRequired)),
+ Comp),
+ // If we are about to report a NoBindingFound/NoBindingFoundForAbstractClass error for AnnotatedT and the
+ // target
+ // component has a Required<const T>, we can report a more specific error (rather than the usual
+ // "binding not found").
+ If(And(NonConstBindingRequired, IsInSet(AnnotatedC, TargetRequirements)),
+ Catch(Catch(AutoRegisterResult, NoBindingFoundErrorTag, ErrorHandler),
+ NoBindingFoundForAbstractClassErrorTag, ErrorHandler),
+ AutoRegisterResult))));
};
};
struct EnsureProvidedTypes {
- template <typename Comp,
- typename TargetRequirements,
- typename TargetNonConstRequirements,
- typename TypesToProvide,
+ template <typename Comp, typename TargetRequirements, typename TargetNonConstRequirements, typename TypesToProvide,
typename NonConstTypesToProvide>
struct apply {
struct Helper {
template <typename CurrentResult, typename T>
struct apply {
- using type =
- Compose2ComponentFunctors(
- ComponentFunctor(EnsureProvidedType,
- TargetRequirements, TargetNonConstRequirements, T, IsInSet(T, NonConstTypesToProvide)),
- CurrentResult);
- };
+ using type = Compose2ComponentFunctors(ComponentFunctor(EnsureProvidedType, TargetRequirements,
+ TargetNonConstRequirements, T,
+ IsInSet(T, NonConstTypesToProvide)),
+ CurrentResult);
+ };
};
-
- using type = Call(FoldVector(TypesToProvide, Helper, ComponentFunctorIdentity),
- Comp);
+
+ using type = Call(FoldVector(TypesToProvide, Helper, ComponentFunctorIdentity), Comp);
};
};
struct ProcessBinding {
template <typename Binding>
struct apply;
-
+
template <typename I, typename C>
struct apply<fruit::impl::Bind<I, C>> {
using type = ComponentFunctor(AddDeferredInterfaceBinding, Type<I>, Type<C>);
@@ -1376,5 +1259,4 @@
} // namespace impl
} // namespace fruit
-
#endif // FRUIT_COMPONENT_FUNCTORS_DEFN_H
diff --git a/include/fruit/impl/component_storage/binding_deps.defn.h b/include/fruit/impl/component_storage/binding_deps.defn.h
index 7e792fc..f7e63ef 100644
--- a/include/fruit/impl/component_storage/binding_deps.defn.h
+++ b/include/fruit/impl/component_storage/binding_deps.defn.h
@@ -4,9 +4,9 @@
* 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.
diff --git a/include/fruit/impl/component_storage/binding_deps.h b/include/fruit/impl/component_storage/binding_deps.h
index f27f2b5..5a18a83 100644
--- a/include/fruit/impl/component_storage/binding_deps.h
+++ b/include/fruit/impl/component_storage/binding_deps.h
@@ -4,9 +4,9 @@
* 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.
diff --git a/include/fruit/impl/component_storage/component_storage.defn.h b/include/fruit/impl/component_storage/component_storage.defn.h
index 9714dbd..c44efb9 100644
--- a/include/fruit/impl/component_storage/component_storage.defn.h
+++ b/include/fruit/impl/component_storage/component_storage.defn.h
@@ -4,9 +4,9 @@
* 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.
@@ -24,8 +24,7 @@
namespace impl {
inline ComponentStorage::ComponentStorage(FixedSizeVector<ComponentStorageEntry>&& entries)
- : entries(std::move(entries)) {
-}
+ : entries(std::move(entries)) {}
inline ComponentStorage::ComponentStorage(const ComponentStorage& other) {
*this = other;
diff --git a/include/fruit/impl/component_storage/component_storage.h b/include/fruit/impl/component_storage/component_storage.h
index 0ad5647..45e3f05 100644
--- a/include/fruit/impl/component_storage/component_storage.h
+++ b/include/fruit/impl/component_storage/component_storage.h
@@ -4,9 +4,9 @@
* 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.
@@ -17,8 +17,8 @@
#ifndef FRUIT_COMPONENT_STORAGE_H
#define FRUIT_COMPONENT_STORAGE_H
-#include <fruit/impl/fruit_internal_forward_decls.h>
#include <fruit/impl/data_structures/fixed_size_vector.h>
+#include <fruit/impl/fruit_internal_forward_decls.h>
namespace fruit {
namespace impl {
diff --git a/include/fruit/impl/component_storage/component_storage_entry.defn.h b/include/fruit/impl/component_storage/component_storage_entry.defn.h
index 97dbb34..a9d139c 100644
--- a/include/fruit/impl/component_storage/component_storage_entry.defn.h
+++ b/include/fruit/impl/component_storage/component_storage_entry.defn.h
@@ -4,9 +4,9 @@
* 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.
@@ -18,8 +18,8 @@
#define FRUIT_COMPONENT_STORAGE_ENTRY_DEFN_H
#include <fruit/impl/component_storage/component_storage_entry.h>
-#include <fruit/impl/util/hash_codes.h>
#include <fruit/impl/util/call_with_tuple.h>
+#include <fruit/impl/util/hash_codes.h>
namespace fruit {
namespace impl {
@@ -63,27 +63,23 @@
}
}
-inline ComponentStorageEntry::LazyComponentWithArgs::ComponentInterface::ComponentInterface(
- erased_fun_t erased_fun)
- : erased_fun(erased_fun) {
-}
+inline ComponentStorageEntry::LazyComponentWithArgs::ComponentInterface::ComponentInterface(erased_fun_t erased_fun)
+ : erased_fun(erased_fun) {}
template <typename Component, typename... Args>
class ComponentInterfaceImpl : public ComponentStorageEntry::LazyComponentWithArgs::ComponentInterface {
private:
using ComponentInterface = ComponentStorageEntry::LazyComponentWithArgs::ComponentInterface;
- using fun_t = Component(*)(Args...);
+ using fun_t = Component (*)(Args...);
std::tuple<Args...> args_tuple;
public:
inline ComponentInterfaceImpl(fun_t fun, std::tuple<Args...> args_tuple)
- : ComponentInterface(reinterpret_cast<erased_fun_t>(fun)),
- args_tuple(std::move(args_tuple)) {
- }
+ : ComponentInterface(reinterpret_cast<erased_fun_t>(fun)), args_tuple(std::move(args_tuple)) {}
- inline bool areParamsEqual(
- const ComponentStorageEntry::LazyComponentWithArgs::ComponentInterface& other) const final {
+ inline bool
+ areParamsEqual(const ComponentStorageEntry::LazyComponentWithArgs::ComponentInterface& other) const final {
if (getFunTypeId() != other.getFunTypeId()) {
return false;
}
@@ -108,15 +104,15 @@
}
inline TypeId getFunTypeId() const final {
- return fruit::impl::getTypeId<Component(*)(Args...)>();
+ return fruit::impl::getTypeId<Component (*)(Args...)>();
}
};
template <typename Component, typename... Args>
-inline ComponentStorageEntry ComponentStorageEntry::LazyComponentWithArgs::create(
- Component(*fun)(Args...), std::tuple<Args...> args_tuple) {
+inline ComponentStorageEntry ComponentStorageEntry::LazyComponentWithArgs::create(Component (*fun)(Args...),
+ std::tuple<Args...> args_tuple) {
ComponentStorageEntry result;
- result.type_id = getTypeId<Component(*)(Args...)>();
+ result.type_id = getTypeId<Component (*)(Args...)>();
result.kind = ComponentStorageEntry::Kind::LAZY_COMPONENT_WITH_ARGS;
result.lazy_component_with_args.component =
new ComponentInterfaceImpl<Component, Args...>(fun, std::move(args_tuple));
@@ -124,10 +120,11 @@
}
template <typename Component, typename... Args>
-inline ComponentStorageEntry ComponentStorageEntry::LazyComponentWithArgs::createReplacedComponentEntry(
- Component(*fun)(Args...), std::tuple<Args...> args_tuple) {
+inline ComponentStorageEntry
+ComponentStorageEntry::LazyComponentWithArgs::createReplacedComponentEntry(Component (*fun)(Args...),
+ std::tuple<Args...> args_tuple) {
ComponentStorageEntry result;
- result.type_id = getTypeId<Component(*)(Args...)>();
+ result.type_id = getTypeId<Component (*)(Args...)>();
result.kind = ComponentStorageEntry::Kind::REPLACED_LAZY_COMPONENT_WITH_ARGS;
result.lazy_component_with_args.component =
new ComponentInterfaceImpl<Component, Args...>(fun, std::move(args_tuple));
@@ -135,10 +132,11 @@
}
template <typename Component, typename... Args>
-inline ComponentStorageEntry ComponentStorageEntry::LazyComponentWithArgs::createReplacementComponentEntry(
- Component(*fun)(Args...), std::tuple<Args...> args_tuple) {
+inline ComponentStorageEntry
+ComponentStorageEntry::LazyComponentWithArgs::createReplacementComponentEntry(Component (*fun)(Args...),
+ std::tuple<Args...> args_tuple) {
ComponentStorageEntry result;
- result.type_id = getTypeId<Component(*)(Args...)>();
+ result.type_id = getTypeId<Component (*)(Args...)>();
result.kind = ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_ARGS;
result.lazy_component_with_args.component =
new ComponentInterfaceImpl<Component, Args...>(fun, std::move(args_tuple));
@@ -155,26 +153,24 @@
delete component;
}
-inline bool ComponentStorageEntry::LazyComponentWithArgs::ComponentInterface::operator==(
- const ComponentInterface& other) const {
+inline bool ComponentStorageEntry::LazyComponentWithArgs::ComponentInterface::
+operator==(const ComponentInterface& other) const {
return erased_fun == other.erased_fun && areParamsEqual(other);
}
template <typename Component>
-void ComponentStorageEntry::LazyComponentWithNoArgs::addBindings(
- erased_fun_t erased_fun, entry_vector_t& entries) {
- Component component = reinterpret_cast<Component(*)()>(erased_fun)();
+void ComponentStorageEntry::LazyComponentWithNoArgs::addBindings(erased_fun_t erased_fun, entry_vector_t& entries) {
+ Component component = reinterpret_cast<Component (*)()>(erased_fun)();
FixedSizeVector<ComponentStorageEntry> component_entries = std::move(component.storage).release();
entries.insert(entries.end(), component_entries.begin(), component_entries.end());
}
template <typename Component>
-inline ComponentStorageEntry
-ComponentStorageEntry::LazyComponentWithNoArgs::create(Component(*fun)()) {
+inline ComponentStorageEntry ComponentStorageEntry::LazyComponentWithNoArgs::create(Component (*fun)()) {
FruitAssert(fun != nullptr);
ComponentStorageEntry result;
result.kind = ComponentStorageEntry::Kind::LAZY_COMPONENT_WITH_NO_ARGS;
- result.type_id = getTypeId<Component(*)()>();
+ result.type_id = getTypeId<Component (*)()>();
result.lazy_component_with_no_args.erased_fun = reinterpret_cast<erased_fun_t>(fun);
result.lazy_component_with_no_args.add_bindings_fun = LazyComponentWithNoArgs::addBindings<Component>;
return result;
@@ -182,11 +178,11 @@
template <typename Component>
inline ComponentStorageEntry
-ComponentStorageEntry::LazyComponentWithNoArgs::createReplacedComponentEntry(Component(*fun)()) {
+ComponentStorageEntry::LazyComponentWithNoArgs::createReplacedComponentEntry(Component (*fun)()) {
FruitAssert(fun != nullptr);
ComponentStorageEntry result;
result.kind = ComponentStorageEntry::Kind::REPLACED_LAZY_COMPONENT_WITH_NO_ARGS;
- result.type_id = getTypeId<Component(*)()>();
+ result.type_id = getTypeId<Component (*)()>();
result.lazy_component_with_no_args.erased_fun = reinterpret_cast<erased_fun_t>(fun);
result.lazy_component_with_no_args.add_bindings_fun = LazyComponentWithNoArgs::addBindings<Component>;
return result;
@@ -194,11 +190,11 @@
template <typename Component>
inline ComponentStorageEntry
-ComponentStorageEntry::LazyComponentWithNoArgs::createReplacementComponentEntry(Component(*fun)()) {
+ComponentStorageEntry::LazyComponentWithNoArgs::createReplacementComponentEntry(Component (*fun)()) {
FruitAssert(fun != nullptr);
ComponentStorageEntry result;
result.kind = ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_NO_ARGS;
- result.type_id = getTypeId<Component(*)()>();
+ result.type_id = getTypeId<Component (*)()>();
result.lazy_component_with_no_args.erased_fun = reinterpret_cast<erased_fun_t>(fun);
result.lazy_component_with_no_args.add_bindings_fun = LazyComponentWithNoArgs::addBindings<Component>;
return result;
@@ -208,8 +204,8 @@
return erased_fun != nullptr;
}
-inline bool ComponentStorageEntry::LazyComponentWithNoArgs::operator==(
- const ComponentStorageEntry::LazyComponentWithNoArgs& other) const {
+inline bool ComponentStorageEntry::LazyComponentWithNoArgs::
+operator==(const ComponentStorageEntry::LazyComponentWithNoArgs& other) const {
if (erased_fun == other.erased_fun) {
// These must be equal in this case, no need to compare them.
FruitAssert(add_bindings_fun == other.add_bindings_fun);
@@ -220,8 +216,7 @@
}
}
-inline void ComponentStorageEntry::LazyComponentWithNoArgs::addBindings(
- entry_vector_t& entries) const {
+inline void ComponentStorageEntry::LazyComponentWithNoArgs::addBindings(entry_vector_t& entries) const {
FruitAssert(isValid());
add_bindings_fun(erased_fun, entries);
}
diff --git a/include/fruit/impl/component_storage/component_storage_entry.h b/include/fruit/impl/component_storage/component_storage_entry.h
index 0839a99..a320b49 100644
--- a/include/fruit/impl/component_storage/component_storage_entry.h
+++ b/include/fruit/impl/component_storage/component_storage_entry.h
@@ -4,9 +4,9 @@
* 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.
@@ -17,10 +17,10 @@
#ifndef FRUIT_COMPONENT_STORAGE_ENTRY_H
#define FRUIT_COMPONENT_STORAGE_ENTRY_H
-#include <fruit/impl/data_structures/semistatic_graph.h>
#include <fruit/impl/component_storage/binding_deps.h>
-#include <fruit/impl/fruit_internal_forward_decls.h>
#include <fruit/impl/data_structures/arena_allocator.h>
+#include <fruit/impl/data_structures/semistatic_graph.h>
+#include <fruit/impl/fruit_internal_forward_decls.h>
namespace fruit {
namespace impl {
@@ -69,7 +69,7 @@
#ifdef FRUIT_EXTRA_DEBUG
mutable
#endif
- Kind kind;
+ Kind kind;
// This is usually the TypeId for the bound type, except:
// * when kind==COMPRESSED_BINDING, this is the interface's TypeId
@@ -102,8 +102,7 @@
// This is a const pointer because this might be a const binding. If not, we'll cast this back to a non-const
// pointer when we need to.
using object_t = const void*;
- using create_t = object_t(*)(InjectorStorage&,
- SemistaticGraph<TypeId, NormalizedBinding>::node_iterator);
+ using create_t = object_t (*)(InjectorStorage&, SemistaticGraph<TypeId, NormalizedBinding>::node_iterator);
// The return value of this function is a pointer to the constructed object (guaranteed to be !=nullptr).
// Once the object is constructed (at injection time), the injector owns that object.
@@ -135,7 +134,7 @@
struct MultibindingForObjectToConstruct {
using object_t = void*;
- using create_t = object_t(*)(InjectorStorage&);
+ using create_t = object_t (*)(InjectorStorage&);
// The return value of this function is a pointer to the constructed object (guaranteed to be !=nullptr).
// Once the object is constructed (at injection time), the injector owns that object.
@@ -151,7 +150,7 @@
*/
struct MultibindingVectorCreator {
- using get_multibindings_vector_t = std::shared_ptr<char>(*)(InjectorStorage&);
+ using get_multibindings_vector_t = std::shared_ptr<char> (*)(InjectorStorage&);
// Returns the std::vector<T*> of instances, or nullptr if none.
// Caches the result in the `v' member of NormalizedMultibindingData.
@@ -164,7 +163,8 @@
// * There are no multibindings that directly depend on C
// The BindingData for C is BindingForObjectToConstruct(
// Then, taken create1, needs_reallocation such that the ComponentStorageEntry for c_type_id is
- // BindingForObjectToConstruct(createC, deps, needs_allocation), we can remove the binding for I and C and replace them
+ // BindingForObjectToConstruct(createC, deps, needs_allocation), we can remove the binding for I and C and replace
+ // them
// with just a binding for I, with BindingForObjectToConstruct(create, deps, needs_allocation).
struct CompressedBinding {
@@ -184,7 +184,7 @@
struct LazyComponentWithNoArgs {
// An arbitrary function type, used as type for the field `erased_fun`.
// Note that we can't use void* here, since data pointers might not have the same size as function pointers.
- using erased_fun_t = void(*)();
+ using erased_fun_t = void (*)();
// The function that will be invoked to create the Component.
// Here we don't know the type, it's only known at construction time.
@@ -193,20 +193,20 @@
using entry_vector_t = std::vector<ComponentStorageEntry, ArenaAllocator<ComponentStorageEntry>>;
// The function that allows to add this component's bindings to the given ComponentStorage.
- using add_bindings_fun_t = void(*)(erased_fun_t, entry_vector_t&);
+ using add_bindings_fun_t = void (*)(erased_fun_t, entry_vector_t&);
add_bindings_fun_t add_bindings_fun;
template <typename Component>
static void addBindings(erased_fun_t erased_fun, entry_vector_t& entries);
template <typename Component>
- static ComponentStorageEntry create(Component(*fun)());
+ static ComponentStorageEntry create(Component (*fun)());
template <typename Component>
- static ComponentStorageEntry createReplacedComponentEntry(Component(*fun)());
+ static ComponentStorageEntry createReplacedComponentEntry(Component (*fun)());
template <typename Component>
- static ComponentStorageEntry createReplacementComponentEntry(Component(*fun)());
+ static ComponentStorageEntry createReplacementComponentEntry(Component (*fun)());
bool operator==(const LazyComponentWithNoArgs&) const;
@@ -225,7 +225,7 @@
public:
// An arbitrary function type, used as type for the field `erased_fun`.
// Note that we can't use void* here, since data pointers might not have the same size as function pointers.
- using erased_fun_t = void(*)();
+ using erased_fun_t = void (*)();
// The function that will be invoked to create the Component.
// Here we don't know the type, it's only known to the LazyComponent implementation.
@@ -256,20 +256,22 @@
};
template <typename Component, typename... Args>
- static ComponentStorageEntry create(Component(*fun)(Args...), std::tuple<Args...> args_tuple);
+ static ComponentStorageEntry create(Component (*fun)(Args...), std::tuple<Args...> args_tuple);
template <typename Component, typename... Args>
- static ComponentStorageEntry createReplacedComponentEntry(Component(*fun)(Args...), std::tuple<Args...> args_tuple);
+ static ComponentStorageEntry createReplacedComponentEntry(Component (*fun)(Args...),
+ std::tuple<Args...> args_tuple);
template <typename Component, typename... Args>
- static ComponentStorageEntry createReplacementComponentEntry(
- Component(*fun)(Args...), std::tuple<Args...> args_tuple);
+ static ComponentStorageEntry createReplacementComponentEntry(Component (*fun)(Args...),
+ std::tuple<Args...> args_tuple);
LazyComponentWithArgs(LazyComponentWithArgs&&) = default;
LazyComponentWithArgs& operator=(LazyComponentWithArgs&&) = default;
// Note: we must allow these (and use the default implementations) since this class is used in a union so it must be
- // a POD. However when we need a real object we must call the other constructor above, and when we need a copy we must
+ // a POD. However when we need a real object we must call the other constructor above, and when we need a copy we
+ // must
// call copy() explicitly.
LazyComponentWithArgs() = default; // LCOV_EXCL_LINE
LazyComponentWithArgs(const LazyComponentWithArgs&) = default;
@@ -323,12 +325,10 @@
#ifndef FRUIT_EXTRA_DEBUG
// This is not required for correctness, but 4 64-bit words should be enough to hold this object, if not we'd end up
// using more memory/CPU than expected.
-static_assert(
- sizeof(ComponentStorageEntry) <= 4 * sizeof(std::uint64_t),
- "Error: a ComponentStorageEntry doesn't fit in 32 bytes as we expected");
+static_assert(sizeof(ComponentStorageEntry) <= 4 * sizeof(std::uint64_t),
+ "Error: a ComponentStorageEntry doesn't fit in 32 bytes as we expected");
#endif
-
} // namespace impl
} // namespace fruit
diff --git a/include/fruit/impl/component_storage/partial_component_storage.defn.h b/include/fruit/impl/component_storage/partial_component_storage.defn.h
index 774551e..09e0c66 100644
--- a/include/fruit/impl/component_storage/partial_component_storage.defn.h
+++ b/include/fruit/impl/component_storage/partial_component_storage.defn.h
@@ -4,9 +4,9 @@
* 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.
@@ -19,10 +19,10 @@
#include <fruit/impl/component_storage/partial_component_storage.h>
-#include <fruit/impl/util/type_info.h>
#include <fruit/impl/bindings.h>
#include <fruit/impl/injector/injector_storage.h>
#include <fruit/impl/util/call_with_tuple.h>
+#include <fruit/impl/util/type_info.h>
#include <utility>
namespace fruit {
@@ -40,7 +40,6 @@
}
};
-
template <typename I, typename C, typename... PreviousBindings>
class PartialComponentStorage<Bind<I, C>, PreviousBindings...> {
private:
@@ -48,9 +47,8 @@
public:
PartialComponentStorage(PartialComponentStorage<PreviousBindings...>& previous_storage)
- : previous_storage(previous_storage) {
- }
-
+ : previous_storage(previous_storage) {}
+
void addBindings(FixedSizeVector<ComponentStorageEntry>& entries) const {
previous_storage.addBindings(entries);
}
@@ -63,12 +61,11 @@
template <typename Signature, typename... PreviousBindings>
class PartialComponentStorage<RegisterConstructor<Signature>, PreviousBindings...> {
private:
- PartialComponentStorage<PreviousBindings...> &previous_storage;
+ PartialComponentStorage<PreviousBindings...>& previous_storage;
public:
PartialComponentStorage(PartialComponentStorage<PreviousBindings...>& previous_storage)
- : previous_storage(previous_storage) {
- }
+ : previous_storage(previous_storage) {}
void addBindings(FixedSizeVector<ComponentStorageEntry>& entries) const {
previous_storage.addBindings(entries);
@@ -82,15 +79,12 @@
template <typename C, typename C1, typename... PreviousBindings>
class PartialComponentStorage<BindInstance<C, C1>, PreviousBindings...> {
private:
- PartialComponentStorage<PreviousBindings...> &previous_storage;
- C &instance;
+ PartialComponentStorage<PreviousBindings...>& previous_storage;
+ C& instance;
public:
- PartialComponentStorage(
- PartialComponentStorage<PreviousBindings...>& previous_storage,
- C& instance)
- : previous_storage(previous_storage), instance(instance) {
- }
+ PartialComponentStorage(PartialComponentStorage<PreviousBindings...>& previous_storage, C& instance)
+ : previous_storage(previous_storage), instance(instance) {}
void addBindings(FixedSizeVector<ComponentStorageEntry>& entries) const {
entries.push_back(InjectorStorage::createComponentStorageEntryForBindInstance<C, C>(instance));
@@ -105,15 +99,12 @@
template <typename C, typename C1, typename... PreviousBindings>
class PartialComponentStorage<BindConstInstance<C, C1>, PreviousBindings...> {
private:
- PartialComponentStorage<PreviousBindings...> &previous_storage;
+ PartialComponentStorage<PreviousBindings...>& previous_storage;
const C& instance;
public:
- PartialComponentStorage(
- PartialComponentStorage<PreviousBindings...>& previous_storage,
- const C& instance)
- : previous_storage(previous_storage), instance(instance) {
- }
+ PartialComponentStorage(PartialComponentStorage<PreviousBindings...>& previous_storage, const C& instance)
+ : previous_storage(previous_storage), instance(instance) {}
void addBindings(FixedSizeVector<ComponentStorageEntry>& entries) const {
entries.push_back(InjectorStorage::createComponentStorageEntryForBindConstInstance<C, C>(instance));
@@ -128,15 +119,12 @@
template <typename C, typename Annotation, typename C1, typename... PreviousBindings>
class PartialComponentStorage<BindInstance<fruit::Annotated<Annotation, C>, C1>, PreviousBindings...> {
private:
- PartialComponentStorage<PreviousBindings...> &previous_storage;
- C &instance;
+ PartialComponentStorage<PreviousBindings...>& previous_storage;
+ C& instance;
public:
- PartialComponentStorage(
- PartialComponentStorage<PreviousBindings...>& previous_storage,
- C& instance)
- : previous_storage(previous_storage), instance(instance) {
- }
+ PartialComponentStorage(PartialComponentStorage<PreviousBindings...>& previous_storage, C& instance)
+ : previous_storage(previous_storage), instance(instance) {}
void addBindings(FixedSizeVector<ComponentStorageEntry>& entries) const {
entries.push_back(
@@ -152,15 +140,12 @@
template <typename C, typename Annotation, typename C1, typename... PreviousBindings>
class PartialComponentStorage<BindConstInstance<fruit::Annotated<Annotation, C>, C1>, PreviousBindings...> {
private:
- PartialComponentStorage<PreviousBindings...> &previous_storage;
+ PartialComponentStorage<PreviousBindings...>& previous_storage;
const C& instance;
public:
- PartialComponentStorage(
- PartialComponentStorage<PreviousBindings...>& previous_storage,
- const C& instance)
- : previous_storage(previous_storage), instance(instance) {
- }
+ PartialComponentStorage(PartialComponentStorage<PreviousBindings...>& previous_storage, const C& instance)
+ : previous_storage(previous_storage), instance(instance) {}
void addBindings(FixedSizeVector<ComponentStorageEntry>& entries) const {
entries.push_back(
@@ -176,12 +161,11 @@
template <typename... Params, typename... PreviousBindings>
class PartialComponentStorage<RegisterProvider<Params...>, PreviousBindings...> {
private:
- PartialComponentStorage<PreviousBindings...> &previous_storage;
+ PartialComponentStorage<PreviousBindings...>& previous_storage;
public:
PartialComponentStorage(PartialComponentStorage<PreviousBindings...>& previous_storage)
- : previous_storage(previous_storage) {
- }
+ : previous_storage(previous_storage) {}
void addBindings(FixedSizeVector<ComponentStorageEntry>& entries) const {
previous_storage.addBindings(entries);
@@ -195,19 +179,16 @@
template <typename C, typename... PreviousBindings>
class PartialComponentStorage<AddInstanceMultibinding<C>, PreviousBindings...> {
private:
- PartialComponentStorage<PreviousBindings...> &previous_storage;
+ PartialComponentStorage<PreviousBindings...>& previous_storage;
C& instance;
public:
PartialComponentStorage(PartialComponentStorage<PreviousBindings...>& previous_storage, C& instance)
- : previous_storage(previous_storage), instance(instance) {
- }
+ : previous_storage(previous_storage), instance(instance) {}
void addBindings(FixedSizeVector<ComponentStorageEntry>& entries) const {
- entries.push_back(
- InjectorStorage::createComponentStorageEntryForInstanceMultibinding<C, C>(instance));
- entries.push_back(
- InjectorStorage::createComponentStorageEntryForMultibindingVectorCreator<C>());
+ entries.push_back(InjectorStorage::createComponentStorageEntryForInstanceMultibinding<C, C>(instance));
+ entries.push_back(InjectorStorage::createComponentStorageEntryForMultibindingVectorCreator<C>());
previous_storage.addBindings(entries);
}
@@ -219,17 +200,17 @@
template <typename C, typename Annotation, typename... PreviousBindings>
class PartialComponentStorage<AddInstanceMultibinding<fruit::Annotated<Annotation, C>>, PreviousBindings...> {
private:
- PartialComponentStorage<PreviousBindings...> &previous_storage;
+ PartialComponentStorage<PreviousBindings...>& previous_storage;
C& instance;
public:
PartialComponentStorage(PartialComponentStorage<PreviousBindings...>& previous_storage, C& instance)
- : previous_storage(previous_storage), instance(instance) {
- }
+ : previous_storage(previous_storage), instance(instance) {}
void addBindings(FixedSizeVector<ComponentStorageEntry>& entries) const {
entries.push_back(
- InjectorStorage::createComponentStorageEntryForInstanceMultibinding<fruit::Annotated<Annotation, C>, C>(instance));
+ InjectorStorage::createComponentStorageEntryForInstanceMultibinding<fruit::Annotated<Annotation, C>, C>(
+ instance));
entries.push_back(
InjectorStorage::createComponentStorageEntryForMultibindingVectorCreator<fruit::Annotated<Annotation, C>>());
previous_storage.addBindings(entries);
@@ -243,44 +224,37 @@
template <typename C, typename... PreviousBindings>
class PartialComponentStorage<AddInstanceVectorMultibindings<C>, PreviousBindings...> {
private:
- PartialComponentStorage<PreviousBindings...> &previous_storage;
+ PartialComponentStorage<PreviousBindings...>& previous_storage;
std::vector<C>& instances;
public:
- PartialComponentStorage(
- PartialComponentStorage<PreviousBindings...>& previous_storage,
- std::vector<C>& instances)
- : previous_storage(previous_storage), instances(instances) {
- }
+ PartialComponentStorage(PartialComponentStorage<PreviousBindings...>& previous_storage, std::vector<C>& instances)
+ : previous_storage(previous_storage), instances(instances) {}
void addBindings(FixedSizeVector<ComponentStorageEntry>& entries) const {
for (auto i = instances.rbegin(), i_end = instances.rend(); i != i_end; ++i) {
// TODO: consider optimizing this so that we need just 1 MULTIBINDING_VECTOR_CREATOR entry (removing the
// assumption that each multibinding entry is always preceded by that).
entries.push_back(InjectorStorage::createComponentStorageEntryForInstanceMultibinding<C, C>(*i));
- entries.push_back(
- InjectorStorage::createComponentStorageEntryForMultibindingVectorCreator<C>());
+ entries.push_back(InjectorStorage::createComponentStorageEntryForMultibindingVectorCreator<C>());
}
previous_storage.addBindings(entries);
}
std::size_t numBindings() const {
- return previous_storage.numBindings() + instances.size()*2;
+ return previous_storage.numBindings() + instances.size() * 2;
}
};
template <typename C, typename Annotation, typename... PreviousBindings>
class PartialComponentStorage<AddInstanceVectorMultibindings<fruit::Annotated<Annotation, C>>, PreviousBindings...> {
private:
- PartialComponentStorage<PreviousBindings...> &previous_storage;
+ PartialComponentStorage<PreviousBindings...>& previous_storage;
std::vector<C>& instances;
public:
- PartialComponentStorage(
- PartialComponentStorage<PreviousBindings...>& previous_storage,
- std::vector<C>& instances)
- : previous_storage(previous_storage), instances(instances) {
- }
+ PartialComponentStorage(PartialComponentStorage<PreviousBindings...>& previous_storage, std::vector<C>& instances)
+ : previous_storage(previous_storage), instances(instances) {}
void addBindings(FixedSizeVector<ComponentStorageEntry>& entries) const {
for (auto i = instances.rbegin(), i_end = instances.rend(); i != i_end; ++i) {
@@ -295,19 +269,18 @@
}
std::size_t numBindings() const {
- return previous_storage.numBindings() + instances.size()*2;
+ return previous_storage.numBindings() + instances.size() * 2;
}
};
template <typename I, typename C, typename... PreviousBindings>
class PartialComponentStorage<AddMultibinding<I, C>, PreviousBindings...> {
private:
- PartialComponentStorage<PreviousBindings...> &previous_storage;
+ PartialComponentStorage<PreviousBindings...>& previous_storage;
public:
PartialComponentStorage(PartialComponentStorage<PreviousBindings...>& previous_storage)
- : previous_storage(previous_storage) {
- }
+ : previous_storage(previous_storage) {}
void addBindings(FixedSizeVector<ComponentStorageEntry>& entries) const {
previous_storage.addBindings(entries);
@@ -321,12 +294,11 @@
template <typename... Params, typename... PreviousBindings>
class PartialComponentStorage<AddMultibindingProvider<Params...>, PreviousBindings...> {
private:
- PartialComponentStorage<PreviousBindings...> &previous_storage;
+ PartialComponentStorage<PreviousBindings...>& previous_storage;
public:
PartialComponentStorage(PartialComponentStorage<PreviousBindings...>& previous_storage)
- : previous_storage(previous_storage) {
- }
+ : previous_storage(previous_storage) {}
void addBindings(FixedSizeVector<ComponentStorageEntry>& entries) const {
previous_storage.addBindings(entries);
@@ -340,12 +312,11 @@
template <typename DecoratedSignature, typename Lambda, typename... PreviousBindings>
class PartialComponentStorage<RegisterFactory<DecoratedSignature, Lambda>, PreviousBindings...> {
private:
- PartialComponentStorage<PreviousBindings...> &previous_storage;
+ PartialComponentStorage<PreviousBindings...>& previous_storage;
public:
PartialComponentStorage(PartialComponentStorage<PreviousBindings...>& previous_storage)
- : previous_storage(previous_storage) {
- }
+ : previous_storage(previous_storage) {}
void addBindings(FixedSizeVector<ComponentStorageEntry>& entries) const {
previous_storage.addBindings(entries);
@@ -359,17 +330,13 @@
template <typename OtherComponent, typename... PreviousBindings>
class PartialComponentStorage<InstallComponent<OtherComponent()>, PreviousBindings...> {
private:
- PartialComponentStorage<PreviousBindings...> &previous_storage;
- OtherComponent(*fun)();
+ PartialComponentStorage<PreviousBindings...>& previous_storage;
+ OtherComponent (*fun)();
public:
- PartialComponentStorage(
- PartialComponentStorage<PreviousBindings...>& previous_storage,
- OtherComponent(*fun1)(),
- std::tuple<>)
- : previous_storage(previous_storage),
- fun(fun1) {
- }
+ PartialComponentStorage(PartialComponentStorage<PreviousBindings...>& previous_storage, OtherComponent (*fun1)(),
+ std::tuple<>)
+ : previous_storage(previous_storage), fun(fun1) {}
void addBindings(FixedSizeVector<ComponentStorageEntry>& entries) const {
entries.push_back(ComponentStorageEntry::LazyComponentWithNoArgs::create(fun));
@@ -384,19 +351,14 @@
template <typename OtherComponent, typename... Args, typename... PreviousBindings>
class PartialComponentStorage<InstallComponent<OtherComponent(Args...)>, PreviousBindings...> {
private:
- PartialComponentStorage<PreviousBindings...> &previous_storage;
- OtherComponent(*fun)(Args...);
+ PartialComponentStorage<PreviousBindings...>& previous_storage;
+ OtherComponent (*fun)(Args...);
std::tuple<Args...> args_tuple;
public:
- PartialComponentStorage(
- PartialComponentStorage<PreviousBindings...>& previous_storage,
- OtherComponent(*fun1)(Args...),
- std::tuple<Args...> args_tuple)
- : previous_storage(previous_storage),
- fun(fun1),
- args_tuple(std::move(args_tuple)) {
- }
+ PartialComponentStorage(PartialComponentStorage<PreviousBindings...>& previous_storage,
+ OtherComponent (*fun1)(Args...), std::tuple<Args...> args_tuple)
+ : previous_storage(previous_storage), fun(fun1), args_tuple(std::move(args_tuple)) {}
void addBindings(FixedSizeVector<ComponentStorageEntry>& entries) {
entries.push_back(ComponentStorageEntry::LazyComponentWithArgs::create(fun, std::move(args_tuple)));
@@ -411,17 +373,13 @@
template <typename OtherComponent, typename... PreviousBindings>
class PartialComponentStorage<PartialReplaceComponent<OtherComponent()>, PreviousBindings...> {
private:
- PartialComponentStorage<PreviousBindings...> &previous_storage;
- OtherComponent(*fun)();
+ PartialComponentStorage<PreviousBindings...>& previous_storage;
+ OtherComponent (*fun)();
public:
- PartialComponentStorage(
- PartialComponentStorage<PreviousBindings...>& previous_storage,
- OtherComponent(*fun1)(),
- std::tuple<>)
- : previous_storage(previous_storage),
- fun(fun1) {
- }
+ PartialComponentStorage(PartialComponentStorage<PreviousBindings...>& previous_storage, OtherComponent (*fun1)(),
+ std::tuple<>)
+ : previous_storage(previous_storage), fun(fun1) {}
void addBindings(FixedSizeVector<ComponentStorageEntry>& entries) const {
entries.push_back(ComponentStorageEntry::LazyComponentWithNoArgs::createReplacedComponentEntry(fun));
@@ -434,27 +392,20 @@
};
template <typename OtherComponent, typename... ReplacedFunArgs, typename... PreviousBindings>
-class PartialComponentStorage<
- PartialReplaceComponent<OtherComponent(ReplacedFunArgs...)>,
- PreviousBindings...> {
+class PartialComponentStorage<PartialReplaceComponent<OtherComponent(ReplacedFunArgs...)>, PreviousBindings...> {
private:
- PartialComponentStorage<PreviousBindings...> &previous_storage;
- OtherComponent(*fun)(ReplacedFunArgs...);
+ PartialComponentStorage<PreviousBindings...>& previous_storage;
+ OtherComponent (*fun)(ReplacedFunArgs...);
std::tuple<ReplacedFunArgs...> args_tuple;
public:
- PartialComponentStorage(
- PartialComponentStorage<PreviousBindings...>& previous_storage,
- OtherComponent(*fun1)(ReplacedFunArgs...),
- std::tuple<ReplacedFunArgs...> args_tuple)
- : previous_storage(previous_storage),
- fun(fun1),
- args_tuple(std::move(args_tuple)) {
- }
+ PartialComponentStorage(PartialComponentStorage<PreviousBindings...>& previous_storage,
+ OtherComponent (*fun1)(ReplacedFunArgs...), std::tuple<ReplacedFunArgs...> args_tuple)
+ : previous_storage(previous_storage), fun(fun1), args_tuple(std::move(args_tuple)) {}
void addBindings(FixedSizeVector<ComponentStorageEntry>& entries) {
- entries.push_back(ComponentStorageEntry::LazyComponentWithArgs::createReplacedComponentEntry(
- fun, std::move(args_tuple)));
+ entries.push_back(
+ ComponentStorageEntry::LazyComponentWithArgs::createReplacedComponentEntry(fun, std::move(args_tuple)));
previous_storage.addBindings(entries);
}
@@ -464,26 +415,18 @@
};
template <typename OtherComponent, typename... PreviousBindings, typename... ReplacedFunArgs>
-class PartialComponentStorage<
- ReplaceComponent<OtherComponent(ReplacedFunArgs...), OtherComponent()>,
- PreviousBindings...> {
+class PartialComponentStorage<ReplaceComponent<OtherComponent(ReplacedFunArgs...), OtherComponent()>,
+ PreviousBindings...> {
private:
using previous_storage_t =
- PartialComponentStorage<
- PartialReplaceComponent<OtherComponent(ReplacedFunArgs...)>,
- PreviousBindings...>;
+ PartialComponentStorage<PartialReplaceComponent<OtherComponent(ReplacedFunArgs...)>, PreviousBindings...>;
previous_storage_t& previous_storage;
- OtherComponent(*fun)();
+ OtherComponent (*fun)();
public:
- PartialComponentStorage(
- previous_storage_t& previous_storage,
- OtherComponent(*fun1)(),
- std::tuple<>)
- : previous_storage(previous_storage),
- fun(fun1) {
- }
+ PartialComponentStorage(previous_storage_t& previous_storage, OtherComponent (*fun1)(), std::tuple<>)
+ : previous_storage(previous_storage), fun(fun1) {}
void addBindings(FixedSizeVector<ComponentStorageEntry>& entries) const {
entries.push_back(ComponentStorageEntry::LazyComponentWithNoArgs::createReplacementComponentEntry(fun));
@@ -495,33 +438,26 @@
}
};
-template <typename OtherComponent, typename... ReplacedFunArgs, typename... ReplacementFunArgs, typename... PreviousBindings>
+template <typename OtherComponent, typename... ReplacedFunArgs, typename... ReplacementFunArgs,
+ typename... PreviousBindings>
class PartialComponentStorage<
- ReplaceComponent<OtherComponent(ReplacedFunArgs...), OtherComponent(ReplacementFunArgs...)>,
- PreviousBindings...> {
+ ReplaceComponent<OtherComponent(ReplacedFunArgs...), OtherComponent(ReplacementFunArgs...)>, PreviousBindings...> {
private:
using previous_storage_t =
- PartialComponentStorage<
- PartialReplaceComponent<OtherComponent(ReplacedFunArgs...)>,
- PreviousBindings...>;
+ PartialComponentStorage<PartialReplaceComponent<OtherComponent(ReplacedFunArgs...)>, PreviousBindings...>;
previous_storage_t& previous_storage;
- OtherComponent(*fun)(ReplacementFunArgs...);
+ OtherComponent (*fun)(ReplacementFunArgs...);
std::tuple<ReplacementFunArgs...> args_tuple;
public:
- PartialComponentStorage(
- previous_storage_t& previous_storage,
- OtherComponent(*fun1)(ReplacementFunArgs...),
- std::tuple<ReplacementFunArgs...> args_tuple)
- : previous_storage(previous_storage),
- fun(fun1),
- args_tuple(std::move(args_tuple)) {
- }
+ PartialComponentStorage(previous_storage_t& previous_storage, OtherComponent (*fun1)(ReplacementFunArgs...),
+ std::tuple<ReplacementFunArgs...> args_tuple)
+ : previous_storage(previous_storage), fun(fun1), args_tuple(std::move(args_tuple)) {}
void addBindings(FixedSizeVector<ComponentStorageEntry>& entries) {
- entries.push_back(ComponentStorageEntry::LazyComponentWithArgs::createReplacementComponentEntry(
- fun, std::move(args_tuple)));
+ entries.push_back(
+ ComponentStorageEntry::LazyComponentWithArgs::createReplacementComponentEntry(fun, std::move(args_tuple)));
previous_storage.addBindings(entries);
}
@@ -530,7 +466,6 @@
}
};
-
} // namespace impl
} // namespace fruit
diff --git a/include/fruit/impl/component_storage/partial_component_storage.h b/include/fruit/impl/component_storage/partial_component_storage.h
index fa13682..7d7b6f3 100644
--- a/include/fruit/impl/component_storage/partial_component_storage.h
+++ b/include/fruit/impl/component_storage/partial_component_storage.h
@@ -4,9 +4,9 @@
* 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.
diff --git a/include/fruit/impl/data_structures/arena_allocator.defn.h b/include/fruit/impl/data_structures/arena_allocator.defn.h
index 57d3524..51a0adb 100644
--- a/include/fruit/impl/data_structures/arena_allocator.defn.h
+++ b/include/fruit/impl/data_structures/arena_allocator.defn.h
@@ -4,9 +4,9 @@
* 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.
@@ -23,15 +23,11 @@
namespace impl {
template <typename T>
-inline ArenaAllocator<T>::ArenaAllocator(MemoryPool& memory_pool)
- : pool(&memory_pool) {
-}
+inline ArenaAllocator<T>::ArenaAllocator(MemoryPool& memory_pool) : pool(&memory_pool) {}
template <typename T>
template <typename U>
-inline ArenaAllocator<T>::ArenaAllocator(const ArenaAllocator<U>& other)
- : pool(other.pool) {
-}
+inline ArenaAllocator<T>::ArenaAllocator(const ArenaAllocator<U>& other) : pool(other.pool) {}
template <typename T>
inline T* ArenaAllocator<T>::allocate(std::size_t n) {
@@ -53,7 +49,6 @@
return x.pool != y.pool;
}
-
} // namespace impl
} // namespace fruit
diff --git a/include/fruit/impl/data_structures/arena_allocator.h b/include/fruit/impl/data_structures/arena_allocator.h
index a791c69..3ba0521 100644
--- a/include/fruit/impl/data_structures/arena_allocator.h
+++ b/include/fruit/impl/data_structures/arena_allocator.h
@@ -4,9 +4,9 @@
* 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.
@@ -62,14 +62,12 @@
void deallocate(T* p, std::size_t);
};
-
template <class T, class U>
bool operator==(const ArenaAllocator<T>&, const ArenaAllocator<U>&);
template <class T, class U>
bool operator!=(const ArenaAllocator<T>&, const ArenaAllocator<U>&);
-
} // namespace impl
} // namespace fruit
diff --git a/include/fruit/impl/data_structures/fixed_size_allocator.defn.h b/include/fruit/impl/data_structures/fixed_size_allocator.defn.h
index 22cb85e..383b737 100644
--- a/include/fruit/impl/data_structures/fixed_size_allocator.defn.h
+++ b/include/fruit/impl/data_structures/fixed_size_allocator.defn.h
@@ -4,9 +4,9 @@
* 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/LITENSE-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 TONDITIONS OF ANY KIND, either express or implied.
@@ -63,11 +63,12 @@
}
template <typename AnnotatedT, typename... Args>
-FRUIT_ALWAYS_INLINE
-inline fruit::impl::meta::UnwrapType<fruit::impl::meta::Eval<fruit::impl::meta::RemoveAnnotations(fruit::impl::meta::Type<AnnotatedT>)>>*
+FRUIT_ALWAYS_INLINE inline fruit::impl::meta::UnwrapType<
+ fruit::impl::meta::Eval<fruit::impl::meta::RemoveAnnotations(fruit::impl::meta::Type<AnnotatedT>)>>*
FixedSizeAllocator::constructObject(Args&&... args) {
- using T = fruit::impl::meta::UnwrapType<fruit::impl::meta::Eval<fruit::impl::meta::RemoveAnnotations(fruit::impl::meta::Type<AnnotatedT>)>>;
-
+ using T = fruit::impl::meta::UnwrapType<
+ fruit::impl::meta::Eval<fruit::impl::meta::RemoveAnnotations(fruit::impl::meta::Type<AnnotatedT>)>>;
+
char* p = storage_last_used;
size_t misalignment = std::uintptr_t(p) % alignof(T);
#ifdef FRUIT_EXTRA_DEBUG
@@ -78,17 +79,16 @@
FruitAssert(std::uintptr_t(p) % alignof(T) == 0);
T* x = reinterpret_cast<T*>(p);
storage_last_used = p + sizeof(T) - 1;
-
+
// This runs arbitrary code (T's constructor), which might end up calling
// constructObject recursively. We must make sure all invariants are satisfied before
// calling this.
new (x) T(std::forward<Args>(args)...); // LCOV_EXCL_BR_LINE
-
+
// We still run this later though, since if T's constructor throws we don't want to
// destruct this object in FixedSizeAllocator's destructor.
if (!std::is_trivially_destructible<T>::value) {
- on_destruction.push_back(
- std::pair<destroy_t, void*>{destroyObject<T>, x});
+ on_destruction.push_back(std::pair<destroy_t, void*>{destroyObject<T>, x});
}
return x;
}
@@ -99,7 +99,7 @@
}
inline FixedSizeAllocator::FixedSizeAllocator(FixedSizeAllocatorData allocator_data)
- : on_destruction(allocator_data.num_types_to_destroy) {
+ : on_destruction(allocator_data.num_types_to_destroy) {
// The +1 is because we waste the first byte (storage_last_used points to the beginning of storage).
storage_begin = new char[allocator_data.total_size + 1];
storage_last_used = storage_begin;
@@ -113,8 +113,7 @@
#endif
}
-inline FixedSizeAllocator::FixedSizeAllocator(FixedSizeAllocator&& x)
- : FixedSizeAllocator() {
+inline FixedSizeAllocator::FixedSizeAllocator(FixedSizeAllocator&& x) : FixedSizeAllocator() {
std::swap(storage_begin, x.storage_begin);
std::swap(storage_last_used, x.storage_last_used);
std::swap(on_destruction, x.on_destruction);
@@ -136,5 +135,4 @@
} // namespace fruit
} // namespace impl
-
#endif // FRUIT_FIXED_SIZE_ALLOTATOR_DEFN_H
diff --git a/include/fruit/impl/data_structures/fixed_size_allocator.h b/include/fruit/impl/data_structures/fixed_size_allocator.h
index d9e6ad6..fa0480c 100644
--- a/include/fruit/impl/data_structures/fixed_size_allocator.h
+++ b/include/fruit/impl/data_structures/fixed_size_allocator.h
@@ -4,9 +4,9 @@
* 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.
@@ -17,9 +17,9 @@
#ifndef FRUIT_FIXED_SIZE_ALLOCATOR_H
#define FRUIT_FIXED_SIZE_ALLOCATOR_H
-#include <fruit/impl/util/type_info.h>
#include <fruit/impl/data_structures/fixed_size_vector.h>
#include <fruit/impl/meta/component.h>
+#include <fruit/impl/util/type_info.h>
#ifdef FRUIT_EXTRA_DEBUG
#include <unordered_map>
@@ -29,36 +29,37 @@
namespace impl {
/**
- * An allocator where the maximum total size is fixed at construction, and all memory is retained until the allocator object itself is destructed.
+ * An allocator where the maximum total size is fixed at construction, and all memory is retained until the allocator
+ * object itself is destructed.
*/
class FixedSizeAllocator {
public:
- using destroy_t = void(*)(void*);
-
+ using destroy_t = void (*)(void*);
+
private:
// A pointer to the last used byte in the allocated memory chunk starting at storage_begin.
char* storage_last_used = nullptr;
-
+
// The chunk of memory that will be used for all allocations.
char* storage_begin = nullptr;
-
+
#ifdef FRUIT_EXTRA_DEBUG
- std::unordered_map<TypeId, std::size_t> remaining_types;
+ std::unordered_map<TypeId, std::size_t> remaining_types;
#endif
-
+
// This vector contains the destroy operations that have to be performed at destruction, and
// the pointers that they must be invoked with. Allows destruction in the correct order.
// These must be called in reverse order.
FixedSizeVector<std::pair<destroy_t, void*>> on_destruction;
-
+
// Destroys an object previously created using constructObject().
template <typename C>
static void destroyObject(void* p);
-
+
// Calls delete on an object previously allocated using new.
template <typename C>
static void destroyExternalObject(void* p);
-
+
public:
// Data used to construct an allocator for a fixed set of types.
class FixedSizeAllocatorData {
@@ -68,42 +69,45 @@
#ifdef FRUIT_EXTRA_DEBUG
std::unordered_map<TypeId, std::size_t> types;
#endif
-
+
static std::size_t maximumRequiredSpace(TypeId type);
-
+
friend class FixedSizeAllocator;
-
+
public:
// Adds 1 `typeId' to the type set. Multiple copies of the same type are allowed.
// Each call to this method allows 1 constructObject<T>(...) call on the resulting allocator.
void addType(TypeId typeId);
-
- // Each call to this method with getTypeId<T>() allows 1 registerExternallyAllocatedType<T>(...) call on the resulting
+
+ // Each call to this method with getTypeId<T>() allows 1 registerExternallyAllocatedType<T>(...) call on the
+ // resulting
// allocator.
void addExternallyAllocatedType(TypeId typeId);
};
-
+
// Constructs an empty allocator (no allocations are allowed).
FixedSizeAllocator() = default;
-
+
// Constructs an allocator for the type set in FixedSizeAllocatorData.
FixedSizeAllocator(FixedSizeAllocatorData allocator_data);
-
+
FixedSizeAllocator(FixedSizeAllocator&&);
FixedSizeAllocator& operator=(FixedSizeAllocator&&);
-
+
FixedSizeAllocator(const FixedSizeAllocator&) = delete;
FixedSizeAllocator& operator=(const FixedSizeAllocator&) = delete;
-
+
// On destruction, all objects allocated with constructObject() and all externally-allocated objects registered with
// registerExternallyAllocatedObject() are destroyed.
~FixedSizeAllocator();
-
+
// Allocates an object of type T, constructing it with the specified arguments. Similar to:
// new C(args...)
template <typename AnnotatedT, typename... Args>
- fruit::impl::meta::UnwrapType<fruit::impl::meta::Eval<fruit::impl::meta::RemoveAnnotations(fruit::impl::meta::Type<AnnotatedT>)>>* constructObject(Args&&... args);
-
+ fruit::impl::meta::UnwrapType<
+ fruit::impl::meta::Eval<fruit::impl::meta::RemoveAnnotations(fruit::impl::meta::Type<AnnotatedT>)>>*
+ constructObject(Args&&... args);
+
template <typename T>
void registerExternallyAllocatedObject(T* p);
};
@@ -113,5 +117,4 @@
#include <fruit/impl/data_structures/fixed_size_allocator.defn.h>
-
#endif // FRUIT_FIXED_SIZE_ALLOCATOR_H
diff --git a/include/fruit/impl/data_structures/fixed_size_vector.defn.h b/include/fruit/impl/data_structures/fixed_size_vector.defn.h
index 8614ce7..79d0c97 100644
--- a/include/fruit/impl/data_structures/fixed_size_vector.defn.h
+++ b/include/fruit/impl/data_structures/fixed_size_vector.defn.h
@@ -4,9 +4,9 @@
* 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.
@@ -21,16 +21,16 @@
#include <fruit/impl/fruit_assert.h>
-#include <utility>
#include <cassert>
#include <cstring>
+#include <utility>
namespace fruit {
namespace impl {
template <typename T, typename Allocator>
inline FixedSizeVector<T, Allocator>::FixedSizeVector(std::size_t capacity, Allocator allocator)
- : capacity(capacity), allocator(allocator) {
+ : capacity(capacity), allocator(allocator) {
if (capacity == 0) { // LCOV_EXCL_BR_LINE
v_begin = 0;
} else {
@@ -48,8 +48,7 @@
}
template <typename T, typename Allocator>
-inline FixedSizeVector<T, Allocator>::FixedSizeVector(FixedSizeVector&& other)
- : FixedSizeVector() {
+inline FixedSizeVector<T, Allocator>::FixedSizeVector(FixedSizeVector&& other) : FixedSizeVector() {
swap(other);
}
@@ -79,7 +78,7 @@
template <typename T, typename Allocator>
inline void FixedSizeVector<T, Allocator>::swap(FixedSizeVector& x) {
std::swap(v_end, x.v_end);
- std::swap(v_begin, x.v_begin);
+ std::swap(v_begin, x.v_begin);
std::swap(capacity, x.capacity);
}
diff --git a/include/fruit/impl/data_structures/fixed_size_vector.h b/include/fruit/impl/data_structures/fixed_size_vector.h
index 3e150c2..7450bf1 100644
--- a/include/fruit/impl/data_structures/fixed_size_vector.h
+++ b/include/fruit/impl/data_structures/fixed_size_vector.h
@@ -4,9 +4,9 @@
* 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.
@@ -32,7 +32,7 @@
private:
// This is not yet implemented in libstdc++ (the STL implementation) shipped with GCC (checked until version 4.9.1).
// static_assert(std::is_trivially_copyable<T>::value, "T must be trivially copyable.");
-
+
// v_end is before v_begin here, because it's the most commonly accessed field.
T* v_end;
T* v_begin;
@@ -43,38 +43,38 @@
public:
using iterator = T*;
using const_iterator = const T*;
-
+
FixedSizeVector(std::size_t capacity = 0, Allocator allocator = Allocator());
// Creates a vector with the specified size (and equal capacity) initialized with the specified value.
FixedSizeVector(std::size_t size, const T& value, Allocator allocator = Allocator());
~FixedSizeVector();
-
+
// Copy construction is not allowed, you need to specify the capacity in order to construct the copy.
FixedSizeVector(const FixedSizeVector& other) = delete;
FixedSizeVector(const FixedSizeVector& other, std::size_t capacity);
-
+
FixedSizeVector(FixedSizeVector&& other);
-
+
FixedSizeVector& operator=(const FixedSizeVector& other) = delete;
FixedSizeVector& operator=(FixedSizeVector&& other);
-
+
std::size_t size() const;
-
+
T& operator[](std::size_t i);
const T& operator[](std::size_t i) const;
-
+
// This yields undefined behavior (instead of reallocating) if the vector's capacity is exceeded.
void push_back(T x);
-
+
void swap(FixedSizeVector& x);
-
+
// Removes all elements, so size() becomes 0 (but maintains the capacity).
void clear();
T* data();
iterator begin();
iterator end();
-
+
const T* data() const;
const_iterator begin() const;
const_iterator end() const;
diff --git a/include/fruit/impl/data_structures/fixed_size_vector.templates.h b/include/fruit/impl/data_structures/fixed_size_vector.templates.h
index ce7d0b1..5ce3959 100644
--- a/include/fruit/impl/data_structures/fixed_size_vector.templates.h
+++ b/include/fruit/impl/data_structures/fixed_size_vector.templates.h
@@ -4,9 +4,9 @@
* 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.
@@ -30,21 +30,21 @@
template <typename T, typename Allocator>
FixedSizeVector<T, Allocator>::FixedSizeVector(const FixedSizeVector& other, std::size_t capacity)
- : FixedSizeVector(capacity, other.allocator) {
+ : FixedSizeVector(capacity, other.allocator) {
FruitAssert(other.size() <= capacity);
// This is not just an optimization, we also want to make sure that other.capacity (and therefore
// also this.capacity) is >0, or we'd pass nullptr to memcpy (although with a size of 0).
if (other.size() != 0) {
FruitAssert(v_begin != nullptr);
FruitAssert(other.v_begin != nullptr);
- std::memcpy(v_begin, other.v_begin, other.size()*sizeof(T));
+ std::memcpy(v_begin, other.v_begin, other.size() * sizeof(T));
}
v_end = v_begin + other.size();
}
template <typename T, typename Allocator>
FixedSizeVector<T, Allocator>::FixedSizeVector(std::size_t size, const T& value, Allocator allocator)
- : FixedSizeVector(size, allocator) {
+ : FixedSizeVector(size, allocator) {
for (std::size_t i = 0; i < size; ++i) {
push_back(value);
}
diff --git a/include/fruit/impl/data_structures/memory_pool.defn.h b/include/fruit/impl/data_structures/memory_pool.defn.h
index 52e46fc..4d892d4 100644
--- a/include/fruit/impl/data_structures/memory_pool.defn.h
+++ b/include/fruit/impl/data_structures/memory_pool.defn.h
@@ -4,9 +4,9 @@
* 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.
@@ -18,22 +18,18 @@
#define FRUIT_MEMORY_POOL_DEFN_H
#include <fruit/impl/data_structures/memory_pool.h>
-#include <fruit/impl/fruit_assert.h>
#include <fruit/impl/fruit-config.h>
+#include <fruit/impl/fruit_assert.h>
#include <cstdint>
namespace fruit {
namespace impl {
-inline MemoryPool::MemoryPool()
- : first_free(nullptr), capacity(0) {
-}
+inline MemoryPool::MemoryPool() : first_free(nullptr), capacity(0) {}
inline MemoryPool::MemoryPool(MemoryPool&& other)
- : allocated_chunks(std::move(other.allocated_chunks)),
- first_free(other.first_free),
- capacity(other.capacity) {
+ : allocated_chunks(std::move(other.allocated_chunks)), first_free(other.first_free), capacity(other.capacity) {
// This is to be sure that we don't double-deallocate.
other.allocated_chunks.clear();
}
@@ -56,8 +52,7 @@
}
template <typename T>
-FRUIT_ALWAYS_INLINE
-inline T* MemoryPool::allocate(std::size_t n) {
+FRUIT_ALWAYS_INLINE inline T* MemoryPool::allocate(std::size_t n) {
#ifdef FRUIT_DISABLE_ARENA_ALLOCATION
void* p = operator new(n * sizeof(T));
allocated_chunks.push_back(p);
@@ -69,12 +64,12 @@
}
std::size_t misalignment = std::uintptr_t(first_free) % alignof(T);
std::size_t padding = alignof(T) - (sizeof(T) % alignof(T));
- std::size_t required_space = n*(sizeof(T) + padding);
+ std::size_t required_space = n * (sizeof(T) + padding);
std::size_t required_space_in_chunk = required_space + (alignof(T) - misalignment);
if (required_space_in_chunk > capacity) {
// This is to make sure that the push_back below won't throw.
if (allocated_chunks.size() == allocated_chunks.capacity()) {
- allocated_chunks.reserve(1 + 2*allocated_chunks.size());
+ allocated_chunks.reserve(1 + 2 * allocated_chunks.size());
}
void* p;
if (required_space > CHUNK_SIZE) {
diff --git a/include/fruit/impl/data_structures/memory_pool.h b/include/fruit/impl/data_structures/memory_pool.h
index 69b8575..05e4eff 100644
--- a/include/fruit/impl/data_structures/memory_pool.h
+++ b/include/fruit/impl/data_structures/memory_pool.h
@@ -4,9 +4,9 @@
* 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.
diff --git a/include/fruit/impl/data_structures/packed_pointer_and_bool.defn.h b/include/fruit/impl/data_structures/packed_pointer_and_bool.defn.h
index 8feee69..e5365fa 100644
--- a/include/fruit/impl/data_structures/packed_pointer_and_bool.defn.h
+++ b/include/fruit/impl/data_structures/packed_pointer_and_bool.defn.h
@@ -4,9 +4,9 @@
* 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/LITENSE-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 TONDITIONS OF ANY KIND, either express or implied.
@@ -29,7 +29,7 @@
template <typename T>
inline T* PackedPointerAndBool<T>::decodePointer(std::uintptr_t value) {
- return reinterpret_cast<T*>(value & ~ std::uintptr_t(1));
+ return reinterpret_cast<T*>(value & ~std::uintptr_t(1));
}
template <typename T>
@@ -75,5 +75,4 @@
} // namespace fruit
} // namespace impl
-
#endif // FRUIT_PACKED_POINTER_AND_BOOL_DEFN_H
diff --git a/include/fruit/impl/data_structures/packed_pointer_and_bool.h b/include/fruit/impl/data_structures/packed_pointer_and_bool.h
index e946fc1..8ac84de 100644
--- a/include/fruit/impl/data_structures/packed_pointer_and_bool.h
+++ b/include/fruit/impl/data_structures/packed_pointer_and_bool.h
@@ -4,9 +4,9 @@
* 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.
@@ -28,30 +28,30 @@
class PackedPointerAndBool {
private:
static_assert(alignof(T) >= 2, "alignof(T) must be at least 2 for the packing to be possible");
-
+
std::uintptr_t value;
-
+
static std::uintptr_t encode(T* p, bool b);
static T* decodePointer(std::uintptr_t value);
static bool decodeBool(std::uintptr_t value);
-
+
public:
PackedPointerAndBool(T* p, bool b);
-
+
PackedPointerAndBool() = default;
-
+
PackedPointerAndBool(const PackedPointerAndBool&) = default;
PackedPointerAndBool(PackedPointerAndBool&&) = default;
-
+
PackedPointerAndBool& operator=(const PackedPointerAndBool&) = default;
PackedPointerAndBool& operator=(PackedPointerAndBool&&) = default;
-
+
T* getPointer() const;
void setPointer(T* p);
-
+
bool getBool() const;
void setBool(bool b);
-
+
bool operator==(const PackedPointerAndBool<T>& other) const;
bool operator!=(const PackedPointerAndBool<T>& other) const;
};
@@ -61,5 +61,4 @@
#include <fruit/impl/data_structures/packed_pointer_and_bool.defn.h>
-
#endif // FRUIT_PACKED_POINTER_AND_BOOL_H
diff --git a/include/fruit/impl/data_structures/semistatic_graph.defn.h b/include/fruit/impl/data_structures/semistatic_graph.defn.h
index ccdcf21..0f589ee 100644
--- a/include/fruit/impl/data_structures/semistatic_graph.defn.h
+++ b/include/fruit/impl/data_structures/semistatic_graph.defn.h
@@ -4,9 +4,9 @@
* 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.
@@ -31,9 +31,7 @@
}
template <typename NodeId, typename Node>
-inline SemistaticGraph<NodeId, Node>::node_iterator::node_iterator(NodeData* itr)
- : itr(itr) {
-}
+inline SemistaticGraph<NodeId, Node>::node_iterator::node_iterator(NodeData* itr) : itr(itr) {}
template <typename NodeId, typename Node>
inline Node& SemistaticGraph<NodeId, Node>::node_iterator::getNode() {
@@ -59,9 +57,7 @@
}
template <typename NodeId, typename Node>
-inline SemistaticGraph<NodeId, Node>::const_node_iterator::const_node_iterator(const NodeData* itr)
- : itr(itr) {
-}
+inline SemistaticGraph<NodeId, Node>::const_node_iterator::const_node_iterator(const NodeData* itr) : itr(itr) {}
template <typename NodeId, typename Node>
inline const Node& SemistaticGraph<NodeId, Node>::const_node_iterator::getNode() {
@@ -80,22 +76,20 @@
return itr == other.itr;
}
-
template <typename NodeId, typename Node>
-inline typename SemistaticGraph<NodeId, Node>::edge_iterator SemistaticGraph<NodeId, Node>::node_iterator::neighborsBegin() {
+inline typename SemistaticGraph<NodeId, Node>::edge_iterator
+SemistaticGraph<NodeId, Node>::node_iterator::neighborsBegin() {
FruitAssert(itr->edges_begin != 0);
FruitAssert(itr->edges_begin != 1);
return edge_iterator{reinterpret_cast<InternalNodeId*>(itr->edges_begin)};
}
template <typename NodeId, typename Node>
-inline SemistaticGraph<NodeId, Node>::edge_iterator::edge_iterator(InternalNodeId* itr)
- : itr(itr) {
-}
+inline SemistaticGraph<NodeId, Node>::edge_iterator::edge_iterator(InternalNodeId* itr) : itr(itr) {}
template <typename NodeId, typename Node>
-inline typename SemistaticGraph<NodeId, Node>::node_iterator SemistaticGraph<NodeId, Node>::edge_iterator::getNodeIterator(
- node_iterator nodes_begin) {
+inline typename SemistaticGraph<NodeId, Node>::node_iterator
+SemistaticGraph<NodeId, Node>::edge_iterator::getNodeIterator(node_iterator nodes_begin) {
return node_iterator{nodeAtId(nodes_begin.itr, *itr)};
}
@@ -105,8 +99,8 @@
}
template <typename NodeId, typename Node>
-inline typename SemistaticGraph<NodeId, Node>::node_iterator SemistaticGraph<NodeId, Node>::edge_iterator::getNodeIterator(
- std::size_t i, node_iterator nodes_begin) {
+inline typename SemistaticGraph<NodeId, Node>::node_iterator
+SemistaticGraph<NodeId, Node>::edge_iterator::getNodeIterator(std::size_t i, node_iterator nodes_begin) {
itr += i;
return getNodeIterator(nodes_begin);
}
@@ -133,7 +127,8 @@
}
template <typename NodeId, typename Node>
-inline typename SemistaticGraph<NodeId, Node>::const_node_iterator SemistaticGraph<NodeId, Node>::find(NodeId nodeId) const {
+inline typename SemistaticGraph<NodeId, Node>::const_node_iterator
+SemistaticGraph<NodeId, Node>::find(NodeId nodeId) const {
const InternalNodeId* internalNodeIdPtr = node_index_map.find(nodeId);
if (internalNodeIdPtr == nullptr) {
return const_node_iterator{nodes.end()};
@@ -161,30 +156,36 @@
}
template <typename NodeId, typename Node>
-inline typename SemistaticGraph<NodeId, Node>::NodeData* SemistaticGraph<NodeId, Node>::nodeAtId(InternalNodeId internalNodeId) {
+inline typename SemistaticGraph<NodeId, Node>::NodeData*
+SemistaticGraph<NodeId, Node>::nodeAtId(InternalNodeId internalNodeId) {
return nodeAtId(nodes.data(), internalNodeId);
}
template <typename NodeId, typename Node>
-inline const typename SemistaticGraph<NodeId, Node>::NodeData* SemistaticGraph<NodeId, Node>::nodeAtId(InternalNodeId internalNodeId) const {
+inline const typename SemistaticGraph<NodeId, Node>::NodeData*
+SemistaticGraph<NodeId, Node>::nodeAtId(InternalNodeId internalNodeId) const {
return nodeAtId(nodes.data(), internalNodeId);
}
template <typename NodeId, typename Node>
-inline typename SemistaticGraph<NodeId, Node>::NodeData* SemistaticGraph<NodeId, Node>::nodeAtId(NodeData* nodes_begin, InternalNodeId internalNodeId) {
+inline typename SemistaticGraph<NodeId, Node>::NodeData*
+SemistaticGraph<NodeId, Node>::nodeAtId(NodeData* nodes_begin, InternalNodeId internalNodeId) {
FruitAssert(internalNodeId.id % sizeof(NodeData) == 0);
NodeData* p = reinterpret_cast<NodeData*>(reinterpret_cast<char*>(nodes_begin) + internalNodeId.id);
- // The code above is faster (the compiler doesn't have to worry about internalNodeId.id%sizeof(NodeData), that we know to be 0).
- FruitAssert(p == nodes_begin + internalNodeId.id/sizeof(NodeData));
+ // The code above is faster (the compiler doesn't have to worry about internalNodeId.id%sizeof(NodeData), that we know
+ // to be 0).
+ FruitAssert(p == nodes_begin + internalNodeId.id / sizeof(NodeData));
return p;
}
template <typename NodeId, typename Node>
-inline const typename SemistaticGraph<NodeId, Node>::NodeData* SemistaticGraph<NodeId, Node>::nodeAtId(const NodeData* nodes_begin, InternalNodeId internalNodeId) {
+inline const typename SemistaticGraph<NodeId, Node>::NodeData*
+SemistaticGraph<NodeId, Node>::nodeAtId(const NodeData* nodes_begin, InternalNodeId internalNodeId) {
FruitAssert(internalNodeId.id % sizeof(NodeData) == 0);
const NodeData* p = reinterpret_cast<const NodeData*>(reinterpret_cast<const char*>(nodes_begin) + internalNodeId.id);
- // The code above is faster (the compiler doesn't have to worry about internalNodeId.id%sizeof(NodeData), that we know to be 0).
- FruitAssert(p == nodes_begin + internalNodeId.id/sizeof(NodeData));
+ // The code above is faster (the compiler doesn't have to worry about internalNodeId.id%sizeof(NodeData), that we know
+ // to be 0).
+ FruitAssert(p == nodes_begin + internalNodeId.id / sizeof(NodeData));
return p;
}
diff --git a/include/fruit/impl/data_structures/semistatic_graph.h b/include/fruit/impl/data_structures/semistatic_graph.h
index 72ff35d..208144e 100644
--- a/include/fruit/impl/data_structures/semistatic_graph.h
+++ b/include/fruit/impl/data_structures/semistatic_graph.h
@@ -4,9 +4,9 @@
* 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.
@@ -17,8 +17,8 @@
#ifndef SEMISTATIC_GRAPH_H
#define SEMISTATIC_GRAPH_H
-#include <fruit/impl/data_structures/semistatic_map.h>
#include "memory_pool.h"
+#include <fruit/impl/data_structures/semistatic_map.h>
#ifdef FRUIT_EXTRA_DEBUG
#include <iostream>
@@ -31,136 +31,142 @@
struct alignas(2) alignas(alignof(std::size_t)) SemistaticGraphInternalNodeId {
// This stores the index in the vector times sizeof(NodeData).
std::size_t id;
-
+
bool operator==(const SemistaticGraphInternalNodeId& x) const;
bool operator<(const SemistaticGraphInternalNodeId& x) const;
};
/**
- * A direct graph implementation where most of the graph is fixed at construction time, but a few nodes and edges can be added
+ * A direct graph implementation where most of the graph is fixed at construction time, but a few nodes and edges can be
+ * added
* later.
- *
- * Also, nodes can either be normal nodes or terminal nodes. Terminal nodes can't have outgoing edges. Note that a node with no
+ *
+ * Also, nodes can either be normal nodes or terminal nodes. Terminal nodes can't have outgoing edges. Note that a node
+ * with no
* outgoing edges may or may not be marked as terminal.
- *
- * While insertion of elements after construction is supported, inserting or changing the neighbors of more than O(1) nodes
+ *
+ * While insertion of elements after construction is supported, inserting or changing the neighbors of more than O(1)
+ * nodes
* after construction will raise the cost of any further operations to more than O(1).
- *
- * Even though adding nodes/edges after construction is inefficient, it is efficient to turn non-terminal nodes into terminal ones
+ *
+ * Even though adding nodes/edges after construction is inefficient, it is efficient to turn non-terminal nodes into
+ * terminal ones
* (and therefore removing all the outgoing edges from the node) after construction.
- *
+ *
* NodeId and Node must be default constructible and trivially copyable.
*/
template <typename NodeId, typename Node>
class SemistaticGraph {
private:
using InternalNodeId = SemistaticGraphInternalNodeId;
-
+
// The node data for nodeId is in nodes[node_index_map.at(nodeId)/sizeof(NodeData)].
// To avoid hash table lookups, the edges in edges_storage are stored as indexes of `nodes' instead of as NodeIds.
- // node_index_map contains all known NodeIds, including ones known only due to an outgoing edge ending there from another node.
+ // node_index_map contains all known NodeIds, including ones known only due to an outgoing edge ending there from
+ // another node.
SemistaticMap<NodeId, InternalNodeId> node_index_map;
-
+
struct NodeData {
#ifdef FRUIT_EXTRA_DEBUG
NodeId key;
#endif
-
+
public:
// If edges_begin==0, this is a terminal node.
// If edges_begin==1, this node doesn't exist, it's just referenced by another node.
// Otherwise, reinterpret_cast<InternalNodeId*>(edges_begin) is the beginning of the edges range.
std::uintptr_t edges_begin;
-
- // An explicit "public" specifier here prevents the compiler from reordering the fields.
- // We want the edges_begin field to be stored first because that's what we're going to branch on.
+
+ // An explicit "public" specifier here prevents the compiler from reordering the fields.
+ // We want the edges_begin field to be stored first because that's what we're going to branch on.
public:
Node node;
};
-
+
std::size_t first_unused_index;
-
+
FixedSizeVector<NodeData> nodes;
-
+
// Stores vectors of edges as contiguous chunks of node IDs.
- // The NodeData elements in `nodes' contain indexes into this vector (stored as already multiplied by sizeof(NodeData)).
+ // The NodeData elements in `nodes' contain indexes into this vector (stored as already multiplied by
+ // sizeof(NodeData)).
// The first element is unused.
FixedSizeVector<InternalNodeId> edges_storage;
-
+
#ifdef FRUIT_EXTRA_DEBUG
template <typename NodeIter>
void printGraph(NodeIter first, NodeIter last);
#endif
-
+
NodeData* nodeAtId(InternalNodeId internalNodeId);
const NodeData* nodeAtId(InternalNodeId internalNodeId) const;
-
- static NodeData* nodeAtId(NodeData* nodes_begin, InternalNodeId internalNodeId);
+
+ static NodeData* nodeAtId(NodeData* nodes_begin, InternalNodeId internalNodeId);
static const NodeData* nodeAtId(const NodeData* nodes_begin, InternalNodeId internalNodeId);
-
+
public:
-
class edge_iterator;
-
+
class node_iterator {
private:
NodeData* itr;
-
+
friend class SemistaticGraph<NodeId, Node>;
-
+
node_iterator(NodeData* itr);
-
+
public:
Node& getNode();
-
+
bool isTerminal();
-
+
// Turns the node into a terminal node, also removing all the deps.
void setTerminal();
-
+
// Assumes !isTerminal().
- // neighborsEnd() is NOT provided/stored for efficiency, the client code is expected to know the number of neighbors.
+ // neighborsEnd() is NOT provided/stored for efficiency, the client code is expected to know the number of
+ // neighbors.
edge_iterator neighborsBegin();
-
+
bool operator==(const node_iterator&) const;
};
-
+
class const_node_iterator {
private:
const NodeData* itr;
-
+
friend class SemistaticGraph<NodeId, Node>;
-
+
const_node_iterator(const NodeData* itr);
-
+
public:
const Node& getNode();
-
+
bool isTerminal();
-
+
bool operator==(const const_node_iterator&) const;
};
-
+
class edge_iterator {
private:
// Iterator on edges_storage.
InternalNodeId* itr;
-
+
friend class SemistaticGraph<NodeId, Node>;
friend class SemistaticGraph<NodeId, Node>::node_iterator;
-
+
edge_iterator(InternalNodeId* itr);
public:
// getNodeIterator(graph.nodes.begin()) returns the first neighbor.
node_iterator getNodeIterator(node_iterator nodes_begin);
-
+
void operator++();
-
+
// Equivalent to i times operator++ followed by getNodeIterator(nodes_begin).
node_iterator getNodeIterator(std::size_t i, node_iterator nodes_begin);
};
-
+
// Constructs an *invalid* graph (as if this graph was just moved from).
SemistaticGraph() = default;
@@ -179,12 +185,13 @@
*/
template <typename NodeIter>
SemistaticGraph(NodeIter first, NodeIter last, MemoryPool& memory_pool);
-
+
SemistaticGraph(SemistaticGraph&&) = default;
SemistaticGraph(const SemistaticGraph&) = delete;
/**
- * Creates a copy of x with the additional nodes in [first, last). The requirements on NodeIter as the same as for the 2-arg
+ * Creates a copy of x with the additional nodes in [first, last). The requirements on NodeIter as the same as for the
+ * 2-arg
* constructor.
* The nodes in [first, last) must NOT be already in x, but can be neighbors of nodes in x.
* The new graph will share data with `x', so must be destroyed before `x' is destroyed.
@@ -194,27 +201,28 @@
*/
template <typename NodeIter>
SemistaticGraph(const SemistaticGraph& x, NodeIter first, NodeIter last, MemoryPool& memory_pool);
-
+
~SemistaticGraph();
-
+
SemistaticGraph& operator=(const SemistaticGraph&) = delete;
SemistaticGraph& operator=(SemistaticGraph&&) = default;
-
- // The result is unspecified. The only guarantee is that it's the right value to pass to edge_iterator's getNodeIterator() methods.
+
+ // The result is unspecified. The only guarantee is that it's the right value to pass to edge_iterator's
+ // getNodeIterator() methods.
node_iterator begin();
-
+
node_iterator end();
const_node_iterator end() const;
-
+
// Precondition: `nodeId' must exist in the graph.
// Unlike std::map::at(), this yields undefined behavior if the precondition isn't satisfied (instead of throwing).
node_iterator at(NodeId nodeId);
-
+
// Prefer using at() when possible, this is slightly slower.
// Returns end() if the node ID was not found.
node_iterator find(NodeId nodeId);
const_node_iterator find(NodeId nodeId) const;
-
+
#ifdef FRUIT_EXTRA_DEBUG
// Emits a runtime error if some node was not created but there is an edge pointing to it.
void checkFullyConstructed();
@@ -226,6 +234,7 @@
#include <fruit/impl/data_structures/semistatic_graph.defn.h>
-// semistatic_graph.templates.h is not included here to limit the transitive includes. Include it explicitly (in .cpp files).
+// semistatic_graph.templates.h is not included here to limit the transitive includes. Include it explicitly (in .cpp
+// files).
#endif // SEMISTATIC_GRAPH_H
diff --git a/include/fruit/impl/data_structures/semistatic_graph.templates.h b/include/fruit/impl/data_structures/semistatic_graph.templates.h
index 52e0d7f..e55be4c 100644
--- a/include/fruit/impl/data_structures/semistatic_graph.templates.h
+++ b/include/fruit/impl/data_structures/semistatic_graph.templates.h
@@ -4,9 +4,9 @@
* 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.
@@ -21,12 +21,12 @@
#error "Fruit .template.h file included in non-cpp file."
#endif
+#include <fruit/impl/data_structures/arena_allocator.h>
+#include <fruit/impl/data_structures/fixed_size_vector.templates.h>
+#include <fruit/impl/data_structures/memory_pool.h>
#include <fruit/impl/data_structures/semistatic_graph.h>
#include <fruit/impl/data_structures/semistatic_map.templates.h>
#include <fruit/impl/util/hash_helpers.h>
-#include <fruit/impl/data_structures/fixed_size_vector.templates.h>
-#include <fruit/impl/data_structures/memory_pool.h>
-#include <fruit/impl/data_structures/arena_allocator.h>
#ifdef FRUIT_EXTRA_DEBUG
#include <iostream>
@@ -39,12 +39,12 @@
struct indexing_iterator {
Iter iter;
std::size_t index;
-
+
void operator++() {
++iter;
index += index_increment;
}
-
+
auto operator*() -> decltype(std::make_pair(*iter, SemistaticGraphInternalNodeId{index})) {
return std::make_pair(*iter, SemistaticGraphInternalNodeId{index});
}
@@ -70,7 +70,7 @@
std::cerr << "}";
}
std::cerr << std::endl;
- }
+ }
std::cerr << std::endl;
}
#endif // FRUIT_EXTRA_DEBUG
@@ -90,30 +90,26 @@
}
}
}
-
+
using itr_t = typename HashSetWithArenaAllocator<NodeId>::iterator;
- node_index_map =
- SemistaticMap<NodeId, InternalNodeId>(
- indexing_iterator<itr_t, sizeof(NodeData)>{node_ids.begin(), 0},
- node_ids.size(),
- memory_pool);
-
+ node_index_map = SemistaticMap<NodeId, InternalNodeId>(
+ indexing_iterator<itr_t, sizeof(NodeData)>{node_ids.begin(), 0}, node_ids.size(), memory_pool);
+
first_unused_index = node_ids.size();
-
+
// Step 2: fill `nodes' and edges_storage.
-
+
// Note that not all of these will be assigned in the loop below.
nodes = FixedSizeVector<NodeData>(first_unused_index, NodeData{
#ifdef FRUIT_EXTRA_DEBUG
- NodeId(),
+ NodeId(),
#endif
- 1,
- Node()});
-
+ 1, Node()});
+
// edges_storage[0] is unused, that's the reason for the +1
edges_storage = FixedSizeVector<InternalNodeId>(num_edges + 1);
edges_storage.push_back(InternalNodeId());
-
+
for (NodeIter i = first; i != last; ++i) {
NodeData& nodeData = *nodeAtId(node_index_map.at(i->getId()));
nodeData.node = i->getValue();
@@ -127,29 +123,28 @@
}
}
}
-
+
#ifdef FRUIT_EXTRA_DEBUG
printGraph(first, last);
-#endif
+#endif
}
template <typename NodeId, typename Node>
template <typename NodeIter>
-SemistaticGraph<NodeId, Node>::SemistaticGraph(
- const SemistaticGraph& x, NodeIter first, NodeIter last, MemoryPool& memory_pool)
- : first_unused_index(x.first_unused_index) {
-
+SemistaticGraph<NodeId, Node>::SemistaticGraph(const SemistaticGraph& x, NodeIter first, NodeIter last,
+ MemoryPool& memory_pool)
+ : first_unused_index(x.first_unused_index) {
+
// TODO: The code below is very similar to the other constructor, extract the common parts in separate functions.
-
+
std::size_t num_new_edges = 0;
-
+
// Step 1: assign IDs to new nodes, fill `node_index_map' and update `first_unused_index'.
-
+
// Step 1a: collect all new node IDs.
using node_ids_elem_t = std::pair<NodeId, InternalNodeId>;
using node_ids_t = std::vector<node_ids_elem_t, ArenaAllocator<node_ids_elem_t>>;
- node_ids_t node_ids =
- node_ids_t(ArenaAllocator<node_ids_elem_t>(memory_pool));
+ node_ids_t node_ids = node_ids_t(ArenaAllocator<node_ids_elem_t>(memory_pool));
for (NodeIter i = first; i != last; ++i) {
if (x.node_index_map.find(i->getId()) == nullptr) {
node_ids.push_back(std::make_pair(i->getId(), InternalNodeId()));
@@ -163,20 +158,20 @@
}
}
}
-
+
// Step 1b: remove duplicates.
std::sort(node_ids.begin(), node_ids.end());
node_ids.erase(std::unique(node_ids.begin(), node_ids.end()), node_ids.end());
-
+
// Step 1c: assign new IDs.
for (auto& p : node_ids) {
- p.second = InternalNodeId{first_unused_index*sizeof(NodeData)};
+ p.second = InternalNodeId{first_unused_index * sizeof(NodeData)};
++first_unused_index;
}
-
+
// Step 1d: actually populate node_index_map.
node_index_map = SemistaticMap<NodeId, InternalNodeId>(x.node_index_map, std::move(node_ids));
-
+
// Step 2: fill `nodes' and `edges_storage'
nodes = FixedSizeVector<NodeData>(x.nodes, first_unused_index);
// Note that the loop below does not necessarily assign all of these.
@@ -185,14 +180,13 @@
#ifdef FRUIT_EXTRA_DEBUG
NodeId(),
#endif
- 1,
- Node()});
+ 1, Node()});
}
-
+
// edges_storage[0] is unused, that's the reason for the +1
edges_storage = FixedSizeVector<InternalNodeId>(num_new_edges + 1);
edges_storage.push_back(InternalNodeId());
-
+
for (NodeIter i = first; i != last; ++i) {
NodeData& nodeData = *nodeAtId(node_index_map.at(i->getId()));
nodeData.node = i->getValue();
@@ -205,11 +199,11 @@
edges_storage.push_back(otherNodeId);
}
}
- }
-
+ }
+
#ifdef FRUIT_EXTRA_DEBUG
printGraph(first, last);
-#endif
+#endif
}
#ifdef FRUIT_EXTRA_DEBUG
@@ -226,8 +220,7 @@
// This is here so that we don't have to include fixed_size_vector.templates.h in fruit.h.
template <typename NodeId, typename Node>
-SemistaticGraph<NodeId, Node>::~SemistaticGraph() {
-}
+SemistaticGraph<NodeId, Node>::~SemistaticGraph() {}
} // namespace impl
} // namespace fruit
diff --git a/include/fruit/impl/data_structures/semistatic_map.defn.h b/include/fruit/impl/data_structures/semistatic_map.defn.h
index bda44a9..7170f23 100644
--- a/include/fruit/impl/data_structures/semistatic_map.defn.h
+++ b/include/fruit/impl/data_structures/semistatic_map.defn.h
@@ -4,9 +4,9 @@
* 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.
@@ -23,15 +23,13 @@
namespace impl {
template <typename Key, typename Value>
-inline SemistaticMap<Key, Value>::HashFunction::HashFunction()
- : a(0), shift(0) {
-}
-
+inline SemistaticMap<Key, Value>::HashFunction::HashFunction() : a(0), shift(0) {}
+
template <typename Key, typename Value>
inline typename SemistaticMap<Key, Value>::Unsigned SemistaticMap<Key, Value>::HashFunction::hash(Unsigned x) const {
return (Unsigned)(a * x) >> shift;
}
-
+
template <typename Key, typename Value>
inline typename SemistaticMap<Key, Value>::Unsigned SemistaticMap<Key, Value>::hash(const Key& key) const {
return hash_function.hash(std::hash<typename std::remove_cv<Key>::type>()(key));
diff --git a/include/fruit/impl/data_structures/semistatic_map.h b/include/fruit/impl/data_structures/semistatic_map.h
index 498f063..aa5bf3a 100644
--- a/include/fruit/impl/data_structures/semistatic_map.h
+++ b/include/fruit/impl/data_structures/semistatic_map.h
@@ -4,9 +4,9 @@
* 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.
@@ -19,12 +19,12 @@
#include <fruit/impl/data_structures/fixed_size_vector.h>
-#include <vector>
-#include <limits>
+#include "arena_allocator.h"
+#include "memory_pool.h"
#include <climits>
#include <cstdint>
-#include "memory_pool.h"
-#include "arena_allocator.h"
+#include <limits>
+#include <vector>
namespace fruit {
namespace impl {
@@ -33,7 +33,7 @@
* Provides a subset of the interface of std::map, and also has these additional assumptions:
* - Key must be default constructible and trivially copyable
* - Value must be default constructible and trivially copyable
- *
+ *
* Also, while insertion of elements after construction is supported, inserting more than O(1) elements
* after construction will raise the cost of any further lookups to more than O(1).
*/
@@ -43,45 +43,49 @@
using Unsigned = std::uintptr_t;
using NumBits = unsigned char;
using value_type = std::pair<Key, Value>;
-
+
static constexpr unsigned char beta = 4;
-
- static_assert(std::numeric_limits<NumBits>::max() >= sizeof(Unsigned)*CHAR_BIT,
- "An unsigned char is not enough to contain the number of bits in your platform. Please report this issue.");
-
+
+ static_assert(
+ std::numeric_limits<NumBits>::max() >= sizeof(Unsigned) * CHAR_BIT,
+ "An unsigned char is not enough to contain the number of bits in your platform. Please report this issue.");
+
struct HashFunction {
Unsigned a;
NumBits shift; // shift==(sizeof(Unsigned)*CHAR_BIT - num_bits)
-
+
HashFunction();
-
+
Unsigned hash(Unsigned x) const;
};
-
+
static NumBits pickNumBits(std::size_t n);
-
+
struct CandidateValuesRange {
value_type* begin;
value_type* end;
};
HashFunction hash_function;
- // Given a key x, if p=lookup_table[hash_function.hash(x)] the candidate places for x are [p.first, p.second). These pointers
- // point to the values[] vector, but it might be either the one of this object or the one of an object that was shallow-copied
+ // Given a key x, if p=lookup_table[hash_function.hash(x)] the candidate places for x are [p.first, p.second). These
+ // pointers
+ // point to the values[] vector, but it might be either the one of this object or the one of an object that was
+ // shallow-copied
// into this one.
FixedSizeVector<CandidateValuesRange> lookup_table;
FixedSizeVector<value_type> values;
-
+
Unsigned hash(const Key& key) const;
-
+
// Inserts a range [elems_begin, elems_end) of new (key,value) pairs with hash h. The keys must not exist in the map.
- // Before calling this, ensure that the capacity of `values' is sufficient to contain the new values without re-allocating.
+ // Before calling this, ensure that the capacity of `values' is sufficient to contain the new values without
+ // re-allocating.
void insert(std::size_t h, const value_type* elems_begin, const value_type* elems_end);
-
+
public:
// Constructs an *invalid* map (as if this map was just moved from).
SemistaticMap() = default;
-
+
/**
* Iter must be a forward iterator with value type std::pair<Key, Value>.
*
@@ -89,28 +93,27 @@
*/
template <typename Iter>
SemistaticMap(Iter begin, std::size_t num_values, MemoryPool& memory_pool);
-
+
// Creates a shallow copy of `map' with the additional elements in new_elements.
// The keys in new_elements must be unique and must not be present in `map'.
// The new map will share data with `map', so must be destroyed before `map' is destroyed.
// NOTE: If more than O(1) elements are added, calls to at() and find() on the result will *not* be O(1).
// This is O(new_elements.size()*log(new_elements.size())).
- SemistaticMap(
- const SemistaticMap<Key, Value>& map,
- std::vector<value_type, ArenaAllocator<value_type>>&& new_elements);
-
+ SemistaticMap(const SemistaticMap<Key, Value>& map,
+ std::vector<value_type, ArenaAllocator<value_type>>&& new_elements);
+
SemistaticMap(SemistaticMap&&) = default;
SemistaticMap(const SemistaticMap&) = delete;
-
+
~SemistaticMap();
-
+
SemistaticMap& operator=(SemistaticMap&&) = default;
SemistaticMap& operator=(const SemistaticMap&) = delete;
-
+
// Precondition: `key' must exist in the map.
// Unlike std::map::at(), this yields undefined behavior if the precondition isn't satisfied (instead of throwing).
const Value& at(Key key) const;
-
+
// Prefer using at() when possible, this is slightly slower.
// Returns nullptr if the key was not found.
const Value* find(Key key) const;
@@ -121,6 +124,7 @@
#include <fruit/impl/data_structures/semistatic_map.defn.h>
-// semistatic_map.templates.h is NOT included here to reduce the transitive includes. Include it when needed (in .cpp files).
+// semistatic_map.templates.h is NOT included here to reduce the transitive includes. Include it when needed (in .cpp
+// files).
#endif // SEMISTATIC_MAP_H
diff --git a/include/fruit/impl/data_structures/semistatic_map.templates.h b/include/fruit/impl/data_structures/semistatic_map.templates.h
index d77da03..f9034c3 100644
--- a/include/fruit/impl/data_structures/semistatic_map.templates.h
+++ b/include/fruit/impl/data_structures/semistatic_map.templates.h
@@ -4,9 +4,9 @@
* 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.
@@ -31,9 +31,9 @@
#include <fruit/impl/data_structures/semistatic_map.h>
-#include <fruit/impl/fruit_assert.h>
-#include <fruit/impl/data_structures/fixed_size_vector.templates.h>
#include <fruit/impl/data_structures/arena_allocator.h>
+#include <fruit/impl/data_structures/fixed_size_vector.templates.h>
+#include <fruit/impl/fruit_assert.h>
namespace fruit {
namespace impl {
@@ -43,19 +43,20 @@
SemistaticMap<Key, Value>::SemistaticMap(Iter values_begin, std::size_t num_values, MemoryPool& memory_pool) {
NumBits num_bits = pickNumBits(num_values);
std::size_t num_buckets = size_t(1) << num_bits;
-
+
FixedSizeVector<Unsigned, ArenaAllocator<Unsigned>> count(num_buckets, 0, ArenaAllocator<Unsigned>(memory_pool));
-
- hash_function.shift = (sizeof(Unsigned)*CHAR_BIT - num_bits);
-
- // The cast is a no-op in some systems (e.g. GCC and Clang under Linux 64bit) but it's needed in other systems (e.g. MSVC).
- unsigned seed = (unsigned) std::chrono::system_clock::now().time_since_epoch().count();
+
+ hash_function.shift = (sizeof(Unsigned) * CHAR_BIT - num_bits);
+
+ // The cast is a no-op in some systems (e.g. GCC and Clang under Linux 64bit) but it's needed in other systems (e.g.
+ // MSVC).
+ unsigned seed = (unsigned)std::chrono::system_clock::now().time_since_epoch().count();
std::default_random_engine random_generator(seed);
std::uniform_int_distribution<Unsigned> random_distribution;
-
+
while (1) {
hash_function.a = random_distribution(random_generator);
-
+
Iter itr = values_begin;
for (std::size_t i = 0; i < num_values; ++i, ++itr) {
Unsigned& this_count = count[hash((*itr).first)];
@@ -65,24 +66,24 @@
}
}
break;
-
-pick_another:
+
+ pick_another:
for (std::size_t i = 0; i < num_buckets; ++i) {
count[i] = 0;
}
}
-
+
values = FixedSizeVector<value_type>(num_values, value_type());
-
+
std::partial_sum(count.begin(), count.end(), count.begin());
lookup_table = FixedSizeVector<CandidateValuesRange>(count.size());
for (Unsigned n : count) {
lookup_table.push_back(CandidateValuesRange{values.data() + n, values.data() + n});
}
-
+
// At this point lookup_table[h] is the number of keys in [first, last) that have a hash <=h.
// Note that even though we ensure this after construction, it is not maintained by insert() so it's not an invariant.
-
+
Iter itr = values_begin;
for (std::size_t i = 0; i < num_values; ++i, ++itr) {
value_type*& first_value_ptr = lookup_table[hash((*itr).first)].begin;
@@ -96,13 +97,12 @@
template <typename Key, typename Value>
SemistaticMap<Key, Value>::SemistaticMap(const SemistaticMap<Key, Value>& map,
std::vector<value_type, ArenaAllocator<value_type>>&& new_elements)
- : hash_function(map.hash_function), lookup_table(map.lookup_table, map.lookup_table.size()) {
-
+ : hash_function(map.hash_function), lookup_table(map.lookup_table, map.lookup_table.size()) {
+
// Sort by hash.
- std::sort(new_elements.begin(), new_elements.end(), [this](const value_type& x, const value_type& y) {
- return hash(x.first) < hash(y.first);
- });
-
+ std::sort(new_elements.begin(), new_elements.end(),
+ [this](const value_type& x, const value_type& y) { return hash(x.first) < hash(y.first); });
+
std::size_t num_additional_values = new_elements.size();
// Add the space needed to store copies of the old buckets.
for (auto itr = new_elements.begin(), itr_end = new_elements.end(); itr != itr_end; /* no increment */) {
@@ -112,9 +112,9 @@
for (; itr != itr_end && hash(itr->first) == h; ++itr) {
}
}
-
+
values = FixedSizeVector<value_type>(num_additional_values);
-
+
// Now actually perform the insertions.
if (new_elements.empty()) {
@@ -122,8 +122,7 @@
// empty vector causes undefined behavior (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59829).
return;
}
- for (value_type *itr = new_elements.data(), *itr_end = new_elements.data() + new_elements.size();
- itr != itr_end;
+ for (value_type *itr = new_elements.data(), *itr_end = new_elements.data() + new_elements.size(); itr != itr_end;
/* no increment */) {
Unsigned h = hash(itr->first);
auto p = map.lookup_table[h];
@@ -138,25 +137,26 @@
template <typename Key, typename Value>
void SemistaticMap<Key, Value>::insert(std::size_t h, const value_type* elems_begin, const value_type* elems_end) {
-
+
value_type* old_bucket_begin = lookup_table[h].begin;
value_type* old_bucket_end = lookup_table[h].end;
-
+
lookup_table[h].begin = values.data() + values.size();
-
+
// Step 1: re-insert all keys with the same hash at the end (if any).
for (value_type* p = old_bucket_begin; p != old_bucket_end; ++p) {
values.push_back(*p);
}
-
+
// Step 2: also insert the new keys and values
for (auto itr = elems_begin; itr != elems_end; ++itr) {
values.push_back(*itr);
}
-
+
lookup_table[h].end = values.data() + values.size();
-
- // The old sequence is no longer pointed to by any index in the lookup table, but recompacting the vectors would be too slow.
+
+ // The old sequence is no longer pointed to by any index in the lookup table, but recompacting the vectors would be
+ // too slow.
}
template <typename Key, typename Value>
@@ -192,8 +192,7 @@
// This is here so that we don't have to include fixed_size_vector.templates.h in fruit.h.
template <typename Key, typename Value>
-SemistaticMap<Key, Value>::~SemistaticMap() {
-}
+SemistaticMap<Key, Value>::~SemistaticMap() {}
} // namespace impl
} // namespace fruit
diff --git a/include/fruit/impl/fruit-config.h b/include/fruit/impl/fruit-config.h
index 3468a30..f9c3b28 100644
--- a/include/fruit/impl/fruit-config.h
+++ b/include/fruit/impl/fruit-config.h
@@ -4,9 +4,9 @@
* 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.
@@ -21,13 +21,15 @@
#if FRUIT_HAS_STD_IS_TRIVIALLY_COPYABLE
#if FRUIT_HAS_STD_IS_TRIVIALLY_COPY_CONSTRUCTIBLE
-#define FRUIT_IS_TRIVIALLY_COPYABLE(T) (std::is_trivially_copyable<T>::value || (std::is_empty<T>::value && std::is_trivially_copy_constructible<T>::value))
+#define FRUIT_IS_TRIVIALLY_COPYABLE(T) \
+ (std::is_trivially_copyable<T>::value || (std::is_empty<T>::value && std::is_trivially_copy_constructible<T>::value))
#else // !FRUIT_HAS_STD_IS_TRIVIALLY_COPY_CONSTRUCTIBLE
#define FRUIT_IS_TRIVIALLY_COPYABLE(T) (std::is_trivially_copyable<T>::value)
#endif // FRUIT_HAS_STD_IS_TRIVIALLY_COPY_CONSTRUCTIBLE
#elif FRUIT_HAS_IS_TRIVIALLY_COPYABLE
#if FRUIT_HAS_STD_IS_TRIVIALLY_COPY_CONSTRUCTIBLE
-#define FRUIT_IS_TRIVIALLY_COPYABLE(T) (__is_trivially_copyable(T) || (std::is_empty<T>::value && std::is_trivially_copy_constructible<T>::value))
+#define FRUIT_IS_TRIVIALLY_COPYABLE(T) \
+ (__is_trivially_copyable(T) || (std::is_empty<T>::value && std::is_trivially_copy_constructible<T>::value))
#else // !FRUIT_HAS_STD_IS_TRIVIALLY_COPY_CONSTRUCTIBLE
#define FRUIT_IS_TRIVIALLY_COPYABLE(T) (__is_trivially_copyable(T))
#endif // FRUIT_HAS_STD_IS_TRIVIALLY_COPY_CONSTRUCTIBLE
@@ -35,14 +37,16 @@
// The compiler doesn't support __is_trivially_copyable (nor is std::is_trivially_copyable
// supported by the library). We use this check as a proxy, but it's not exactly the same thing.
#if FRUIT_HAS_STD_IS_TRIVIALLY_COPY_CONSTRUCTIBLE
-#define FRUIT_IS_TRIVIALLY_COPYABLE(T) (__has_trivial_copy(T) || (std::is_empty<T>::value && std::is_trivially_copy_constructible<T>::value))
+#define FRUIT_IS_TRIVIALLY_COPYABLE(T) \
+ (__has_trivial_copy(T) || (std::is_empty<T>::value && std::is_trivially_copy_constructible<T>::value))
#else // !FRUIT_HAS_STD_IS_TRIVIALLY_COPY_CONSTRUCTIBLE
#define FRUIT_IS_TRIVIALLY_COPYABLE(T) (__has_trivial_copy(T))
#endif // FRUIT_HAS_STD_IS_TRIVIALLY_COPY_CONSTRUCTIBLE
#else
// We use the standard one, but most likely it won't work.
#if FRUIT_HAS_STD_IS_TRIVIALLY_COPY_CONSTRUCTIBLE
-#define FRUIT_IS_TRIVIALLY_COPYABLE(T) (std::is_trivially_copyable<T>::value || (std::is_empty<T>::value && std::is_trivially_copy_constructible<T>::value))
+#define FRUIT_IS_TRIVIALLY_COPYABLE(T) \
+ (std::is_trivially_copyable<T>::value || (std::is_empty<T>::value && std::is_trivially_copy_constructible<T>::value))
#else // !FRUIT_HAS_STD_IS_TRIVIALLY_COPY_CONSTRUCTIBLE
#define FRUIT_IS_TRIVIALLY_COPYABLE(T) (std::is_trivially_copyable<T>::value)
#endif // FRUIT_HAS_STD_IS_TRIVIALLY_COPY_CONSTRUCTIBLE
@@ -63,7 +67,8 @@
#elif FRUIT_HAS_DECLSPEC_DEPRECATED
#define FRUIT_DEPRECATED_DECLARATION(...) __declspec(deprecated) __VA_ARGS__
#define FRUIT_DEPRECATED_DEFINITION(...) __declspec(deprecated) __VA_ARGS__
-// We use this only if the above two are not supported, because some compilers "support" this syntax (i.e., it compiles) but they just ignore the attribute.
+// We use this only if the above two are not supported, because some compilers "support" this syntax (i.e., it compiles)
+// but they just ignore the attribute.
#elif FRUIT_HAS_ATTRIBUTE_DEPRECATED
#define FRUIT_DEPRECATED_DECLARATION(...) [[deprecated]] __VA_ARGS__
#define FRUIT_DEPRECATED_DEFINITION(...) [[deprecated]] __VA_ARGS__
@@ -73,9 +78,13 @@
#endif
#if FRUIT_HAS_MSVC_ASSUME
-#define FRUIT_UNREACHABLE FruitAssert(false); __assume(0)
+#define FRUIT_UNREACHABLE \
+ FruitAssert(false); \
+ __assume(0)
#elif FRUIT_HAS_BUILTIN_UNREACHABLE
-#define FRUIT_UNREACHABLE FruitAssert(false); __builtin_unreachable()
+#define FRUIT_UNREACHABLE \
+ FruitAssert(false); \
+ __builtin_unreachable()
#endif
#endif // FRUIT_CONFIG_H
diff --git a/include/fruit/impl/fruit_assert.h b/include/fruit/impl/fruit_assert.h
index e971c29..b2b4b0d 100644
--- a/include/fruit/impl/fruit_assert.h
+++ b/include/fruit/impl/fruit_assert.h
@@ -4,9 +4,9 @@
* 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.
@@ -34,5 +34,4 @@
#define FruitDelegateCheck(...) static_assert(true || sizeof(fruit::impl::meta::Eval<__VA_ARGS__>), "")
#define FruitDisplayErrorForType(...) static_assert(false && sizeof(fruit::impl::meta::Eval<__VA_ARGS__>), "")
-
#endif // FRUIT_ASSERT_H
diff --git a/include/fruit/impl/fruit_internal_forward_decls.h b/include/fruit/impl/fruit_internal_forward_decls.h
index f6c3699..4883470 100644
--- a/include/fruit/impl/fruit_internal_forward_decls.h
+++ b/include/fruit/impl/fruit_internal_forward_decls.h
@@ -4,9 +4,9 @@
* 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.
diff --git a/include/fruit/impl/injection_debug_errors.h b/include/fruit/impl/injection_debug_errors.h
index 76ff026..3efdc5e 100644
--- a/include/fruit/impl/injection_debug_errors.h
+++ b/include/fruit/impl/injection_debug_errors.h
@@ -4,9 +4,9 @@
* 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.
@@ -107,5 +107,4 @@
} // namespace impl
} // namespace fruit
-
#endif // FRUIT_INJECTION_DEBUG_ERRORS
diff --git a/include/fruit/impl/injection_errors.h b/include/fruit/impl/injection_errors.h
index ac3180b..06a0344 100644
--- a/include/fruit/impl/injection_errors.h
+++ b/include/fruit/impl/injection_errors.h
@@ -4,9 +4,9 @@
* 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.
@@ -17,8 +17,8 @@
#ifndef FRUIT_INJECTION_ERRORS
#define FRUIT_INJECTION_ERRORS
-#include <fruit/impl/meta/set.h>
#include <fruit/impl/fruit_assert.h>
+#include <fruit/impl/meta/set.h>
namespace fruit {
namespace impl {
@@ -30,117 +30,98 @@
template <typename T>
struct NoBindingFoundError {
- static_assert(
- AlwaysFalse<T>::value,
- "No explicit binding nor C::Inject definition was found for T.");
+ static_assert(AlwaysFalse<T>::value, "No explicit binding nor C::Inject definition was found for T.");
};
template <typename T, typename C>
struct NoBindingFoundForAbstractClassError {
- static_assert(
- AlwaysFalse<T>::value,
- "No explicit binding was found for T, and note that C is an abstract class (so Fruit can't auto-inject this type, "
- "even if it has an Inject typedef or an INJECT annotation that will be ignored).");
+ static_assert(AlwaysFalse<T>::value,
+ "No explicit binding was found for T, and note that C is an abstract class (so Fruit can't auto-inject "
+ "this type, "
+ "even if it has an Inject typedef or an INJECT annotation that will be ignored).");
};
template <typename... Ts>
struct RepeatedTypesError {
- static_assert(
- AlwaysFalse<Ts...>::value,
- "A type was specified more than once. Requirements and provided types should be unique.");
+ static_assert(AlwaysFalse<Ts...>::value,
+ "A type was specified more than once. Requirements and provided types should be unique.");
};
template <typename... TypesInLoop>
struct SelfLoopError {
- static_assert(
- AlwaysFalse<TypesInLoop...>::value,
- "Found a loop in the dependencies! The types in TypesInLoop all depend on the next, and the "
- "last one depends on the first.");
+ static_assert(AlwaysFalse<TypesInLoop...>::value,
+ "Found a loop in the dependencies! The types in TypesInLoop all depend on the next, and the "
+ "last one depends on the first.");
};
template <typename T, typename C>
struct NonClassTypeError {
- static_assert(
- AlwaysFalse<T>::value,
- "A non-class type T was specified. Use C instead.");
+ static_assert(AlwaysFalse<T>::value, "A non-class type T was specified. Use C instead.");
};
template <typename AnnotatedT, typename T>
struct AnnotatedTypeError {
- static_assert(
- AlwaysFalse<T>::value,
- "An annotated type was specified where a non-annotated type was expected.");
+ static_assert(AlwaysFalse<T>::value, "An annotated type was specified where a non-annotated type was expected.");
};
template <typename C>
struct TypeAlreadyBoundError {
- static_assert(
- AlwaysFalse<C>::value,
- "Trying to bind C but it is already bound.");
+ static_assert(AlwaysFalse<C>::value, "Trying to bind C but it is already bound.");
};
template <typename RequiredSignature, typename SignatureInInjectTypedef>
struct RequiredFactoryWithDifferentSignatureError {
- static_assert(
- AlwaysFalse<RequiredSignature>::value,
- "The required C factory doesn't have the same signature as the Inject annotation in C.");
+ static_assert(AlwaysFalse<RequiredSignature>::value,
+ "The required C factory doesn't have the same signature as the Inject annotation in C.");
};
template <typename Signature, typename SignatureInLambda>
struct AnnotatedSignatureDifferentFromLambdaSignatureError {
- static_assert(
- AlwaysFalse<Signature>::value,
- "The annotated signature specified is not the same as the lambda's signature (after removing "
- "annotations).");
+ static_assert(AlwaysFalse<Signature>::value,
+ "The annotated signature specified is not the same as the lambda's signature (after removing "
+ "annotations).");
};
template <typename... DuplicatedTypes>
struct DuplicateTypesInComponentError {
- static_assert(
- AlwaysFalse<DuplicatedTypes...>::value,
- "The installed component provides some types that are already provided by the current "
- "component.");
+ static_assert(AlwaysFalse<DuplicatedTypes...>::value,
+ "The installed component provides some types that are already provided by the current "
+ "component.");
};
template <typename... Requirements>
struct InjectorWithRequirementsError {
- static_assert(
- AlwaysFalse<Requirements...>::value,
- "Injectors can't have requirements. If you want Fruit to try auto-resolving the requirements "
- "in the injector's scope, cast the component to a component with no requirements before "
- "constructing the injector with it.");
+ static_assert(AlwaysFalse<Requirements...>::value,
+ "Injectors can't have requirements. If you want Fruit to try auto-resolving the requirements "
+ "in the injector's scope, cast the component to a component with no requirements before "
+ "constructing the injector with it.");
};
template <typename C, typename CandidateSignature>
struct InjectTypedefNotASignatureError {
- static_assert(
- AlwaysFalse<C>::value,
- "C::Inject should be a typedef to a signature, e.g. C(int)");
+ static_assert(AlwaysFalse<C>::value, "C::Inject should be a typedef to a signature, e.g. C(int)");
};
template <typename C, typename SignatureReturnType>
struct InjectTypedefForWrongClassError {
- static_assert(
- AlwaysFalse<C>::value,
- "C::Inject is a signature, but does not return a C. Maybe the class C has no Inject typedef "
- "and inherited the base class' one? If that's not the case, make sure it returns just C, not "
- "C* or other types.");
+ static_assert(AlwaysFalse<C>::value,
+ "C::Inject is a signature, but does not return a C. Maybe the class C has no Inject typedef "
+ "and inherited the base class' one? If that's not the case, make sure it returns just C, not "
+ "C* or other types.");
};
template <typename C>
struct InjectTypedefWithAnnotationError {
- static_assert(
- AlwaysFalse<C>::value,
- "C::Inject is a signature that returns an annotated type. The annotation must be removed, "
- "Fruit will deduce the correct annotation based on how the required binding.");
+ static_assert(AlwaysFalse<C>::value,
+ "C::Inject is a signature that returns an annotated type. The annotation must be removed, "
+ "Fruit will deduce the correct annotation based on how the required binding.");
};
template <typename CandidateSignature>
struct NotASignatureError {
- static_assert(
- AlwaysFalse<CandidateSignature>::value,
- "CandidateSignature was specified as parameter, but it's not a signature. Signatures are of "
- "the form MyClass(int, float).");
+ static_assert(AlwaysFalse<CandidateSignature>::value,
+ "CandidateSignature was specified as parameter, but it's not a signature. Signatures are of "
+ "the form MyClass(int, float).");
};
template <typename CandidateLambda>
@@ -151,117 +132,113 @@
template <typename Signature>
struct ConstructorDoesNotExistError {
- static_assert(
- AlwaysFalse<Signature>::value,
- "The specified constructor does not exist.");
+ static_assert(AlwaysFalse<Signature>::value, "The specified constructor does not exist.");
};
template <typename I, typename C>
struct NotABaseClassOfError {
- static_assert(
- AlwaysFalse<I>::value,
- "I is not a base class of C.");
+ static_assert(AlwaysFalse<I>::value, "I is not a base class of C.");
};
template <typename ProviderType>
struct FunctorUsedAsProviderError {
- static_assert(
- AlwaysFalse<ProviderType>::value,
- "A stateful lambda or a non-lambda functor was used as provider. Only functions and stateless "
- "lambdas can be used as providers.");
+ static_assert(AlwaysFalse<ProviderType>::value,
+ "A stateful lambda or a non-lambda functor was used as provider. Only functions and stateless "
+ "lambdas can be used as providers.");
};
template <typename... ComponentRequirements>
struct ComponentWithRequirementsInInjectorError {
- static_assert(
- AlwaysFalse<ComponentRequirements...>::value,
- "When using the two-argument constructor of Injector, the component used as second parameter "
- "must not have requirements (while the normalized component can), but the specified component "
- "requires ComponentRequirements.");
+ static_assert(AlwaysFalse<ComponentRequirements...>::value,
+ "When using the two-argument constructor of Injector, the component used as second parameter "
+ "must not have requirements (while the normalized component can), but the specified component "
+ "requires ComponentRequirements.");
};
template <typename... UnsatisfiedRequirements>
struct UnsatisfiedRequirementsInNormalizedComponentError {
- static_assert(
- AlwaysFalse<UnsatisfiedRequirements...>::value,
- "The requirements in UnsatisfiedRequirements are required by the NormalizedComponent but are "
- "not provided by the Component (second parameter of the Injector constructor).");
+ static_assert(AlwaysFalse<UnsatisfiedRequirements...>::value,
+ "The requirements in UnsatisfiedRequirements are required by the NormalizedComponent but are "
+ "not provided by the Component (second parameter of the Injector constructor).");
};
template <typename... TypesNotProvided>
struct TypesInInjectorNotProvidedError {
- static_assert(
- AlwaysFalse<TypesNotProvided...>::value,
- "The types in TypesNotProvided are declared as provided by the injector, but none of the two "
- "components passed to the Injector constructor provides them.");
+ static_assert(AlwaysFalse<TypesNotProvided...>::value,
+ "The types in TypesNotProvided are declared as provided by the injector, but none of the two "
+ "components passed to the Injector constructor provides them.");
};
template <typename... TypesProvidedAsConstOnly>
struct TypesInInjectorProvidedAsConstOnlyError {
static_assert(
- AlwaysFalse<TypesProvidedAsConstOnly...>::value,
- "The types in TypesProvidedAsConstOnly are declared as non-const provided types by the injector, but the "
- "components passed to the Injector constructor provide them as const only. You should mark them as const in the "
- "injector (e.g., switching from Injector<T> to Injector<const T>) or mark them as non-const in the "
- "Component/NormalizedComponent (e.g. switching from [Normalized]Component<const T> to [Normalized]Component<T>).");
+ AlwaysFalse<TypesProvidedAsConstOnly...>::value,
+ "The types in TypesProvidedAsConstOnly are declared as non-const provided types by the injector, but the "
+ "components passed to the Injector constructor provide them as const only. You should mark them as const in the "
+ "injector (e.g., switching from Injector<T> to Injector<const T>) or mark them as non-const in the "
+ "Component/NormalizedComponent (e.g. switching from [Normalized]Component<const T> to "
+ "[Normalized]Component<T>).");
};
template <typename T>
struct TypeNotProvidedError {
- static_assert(
- AlwaysFalse<T>::value,
- "Trying to get an instance of T, but it is not provided by this Provider/Injector.");
+ static_assert(AlwaysFalse<T>::value,
+ "Trying to get an instance of T, but it is not provided by this Provider/Injector.");
};
template <typename T>
struct TypeProvidedAsConstOnlyError {
static_assert(
- AlwaysFalse<T>::value,
- "Trying to get an instance of T, but it is only provided as a constant by this Provider/Injector and a non-const "
- "pointer/reference/Provider was requested. You should either switch to injecting a const value (e.g. switching from"
- " injecting T*, T&, std::unique_ptr<T> or Provider<T> to injecting a T, const T*, const T& or Provider<const T>) "
- "or get the value from an Injector/Provider that provides it as a non-const type (e.g. switching from calling get "
- "on an Injector<const T> or on a Provider<const T> to calling get on an Injector<T> or a Provider<T>).");
+ AlwaysFalse<T>::value,
+ "Trying to get an instance of T, but it is only provided as a constant by this Provider/Injector and a non-const "
+ "pointer/reference/Provider was requested. You should either switch to injecting a const value (e.g. switching "
+ "from"
+ " injecting T*, T&, std::unique_ptr<T> or Provider<T> to injecting a T, const T*, const T& or Provider<const T>) "
+ "or get the value from an Injector/Provider that provides it as a non-const type (e.g. switching from calling "
+ "get "
+ "on an Injector<const T> or on a Provider<const T> to calling get on an Injector<T> or a Provider<T>).");
};
template <typename T>
struct NonConstBindingRequiredButConstBindingProvidedError {
static_assert(
- AlwaysFalse<T>::value,
- "The type T was provided as constant, however one of the constructors/providers/factories in this component "
- "requires it as a non-constant (or this Component declares it as a non-const provided/required type). "
- "If you want to only have a const binding for this type, you should change the places that use the type to inject "
- "a constant value (e.g. T, const T*, const T& and Provider<const T> are ok while you should avoid injecting T*, T&,"
- " std::unique_ptr<T> and Provider<T>) and if the type is in Component<...> make sure that it's marked as const there"
- " (e.g. Component<const T> and Component<Required<const T>> are ok while Component<T> and Component<Required<T>> are "
- "not. "
- "On the other hand, if you want to have a non-const binding for this type, you should switch to a non-const "
- "bindInstance (if you're binding an instance) or changing any installed component functions to declare the type as "
- "non-const, e.g. Component<T> or Component<Required<T>> instead of Component<const T> and "
- "Component<Required<const T>>.");
+ AlwaysFalse<T>::value,
+ "The type T was provided as constant, however one of the constructors/providers/factories in this component "
+ "requires it as a non-constant (or this Component declares it as a non-const provided/required type). "
+ "If you want to only have a const binding for this type, you should change the places that use the type to "
+ "inject "
+ "a constant value (e.g. T, const T*, const T& and Provider<const T> are ok while you should avoid injecting T*, "
+ "T&,"
+ " std::unique_ptr<T> and Provider<T>) and if the type is in Component<...> make sure that it's marked as const "
+ "there"
+ " (e.g. Component<const T> and Component<Required<const T>> are ok while Component<T> and Component<Required<T>> "
+ "are "
+ "not. "
+ "On the other hand, if you want to have a non-const binding for this type, you should switch to a non-const "
+ "bindInstance (if you're binding an instance) or changing any installed component functions to declare the type "
+ "as "
+ "non-const, e.g. Component<T> or Component<Required<T>> instead of Component<const T> and "
+ "Component<Required<const T>>.");
};
template <typename C, typename InjectSignature>
struct NoConstructorMatchingInjectSignatureError {
- static_assert(
- AlwaysFalse<C>::value,
- "C contains an Inject typedef but it's not constructible with the specified types");
+ static_assert(AlwaysFalse<C>::value,
+ "C contains an Inject typedef but it's not constructible with the specified types");
};
template <typename ExpectedSignature, typename FunctorSignature>
struct FunctorSignatureDoesNotMatchError {
- static_assert(
- AlwaysFalse<ExpectedSignature>::value,
- "Unexpected functor signature (it should be the same as ExpectedSignature minus any Assisted "
- "types).");
+ static_assert(AlwaysFalse<ExpectedSignature>::value,
+ "Unexpected functor signature (it should be the same as ExpectedSignature minus any Assisted "
+ "types).");
};
template <typename Signature>
struct FactoryReturningPointerError {
- static_assert(
- AlwaysFalse<Signature>::value,
- "The specified factory returns a pointer. This is not supported; return a value or an "
- "std::unique_ptr instead.");
+ static_assert(AlwaysFalse<Signature>::value,
+ "The specified factory returns a pointer. This is not supported; return a value or an "
+ "std::unique_ptr instead.");
};
template <typename Lambda>
@@ -271,9 +248,7 @@
// conforming C++ compilers. If this error happens for a lambda with no captures, please file a
// bug at https://github.com/google/fruit/issues and indicate the compiler (with version) that
// you're using.
- static_assert(
- AlwaysFalse<Lambda>::value,
- "Only lambdas with no captures are supported.");
+ static_assert(AlwaysFalse<Lambda>::value, "Only lambdas with no captures are supported.");
};
template <typename Lambda>
@@ -283,115 +258,114 @@
// work in all conforming C++ compilers. If this error happens for a lambda with no captures,
// please file a bug at https://github.com/google/fruit/issues and indicate the compiler (with
// version) that you're using.
- static_assert(
- AlwaysFalse<Lambda>::value,
- "Only trivially copyable lambdas are supported. Make sure that your lambda has no captures.");
+ static_assert(AlwaysFalse<Lambda>::value,
+ "Only trivially copyable lambdas are supported. Make sure that your lambda has no captures.");
};
template <typename C>
struct CannotConstructAbstractClassError {
- static_assert(
- AlwaysFalse<C>::value,
- "The specified class can't be constructed because it's an abstract class.");
+ static_assert(AlwaysFalse<C>::value, "The specified class can't be constructed because it's an abstract class.");
};
template <typename C>
struct InterfaceBindingToSelfError {
- static_assert(
- AlwaysFalse<C>::value,
- "The type C was bound to itself. If this was intentional, to \"tell Fruit to inject the type"
- " C\", this binding is unnecessary, just remove it. bind<I,C>() is to tell Fruit about"
- " base-derived class relationships.");
+ static_assert(AlwaysFalse<C>::value,
+ "The type C was bound to itself. If this was intentional, to \"tell Fruit to inject the type"
+ " C\", this binding is unnecessary, just remove it. bind<I,C>() is to tell Fruit about"
+ " base-derived class relationships.");
};
template <typename TypeParameter, typename TypeOfValue>
struct TypeMismatchInBindInstanceError {
- static_assert(
- AlwaysFalse<TypeParameter>::value,
- "A type parameter was specified in bindInstance() but it doesn't match the value type"
- " (even after removing the fruit::Annotation<>, if any). Please change the type parameter"
- " to be the same as the type of the value (or a subclass).");
+ static_assert(AlwaysFalse<TypeParameter>::value,
+ "A type parameter was specified in bindInstance() but it doesn't match the value type"
+ " (even after removing the fruit::Annotation<>, if any). Please change the type parameter"
+ " to be the same as the type of the value (or a subclass).");
};
template <typename RequiredType>
struct RequiredTypesInComponentArgumentsError {
- static_assert(
- AlwaysFalse<RequiredType>::value,
- "A Required<...> type was passed as a non-first template parameter to fruit::Component or "
- "fruit::NormalizedComponent. "
- "All required types (if any) should be passed together as a single Required<> type passed as the first "
- "type argument of fruit::Component (and fruit::NormalizedComponent). For example, write "
- "fruit::Component<fruit::Required<Foo, Bar>, Baz> instead of "
- "fruit::Component<fruit::Required<Foo>, fruit::Required<Bar>, Baz>.");
+ static_assert(AlwaysFalse<RequiredType>::value,
+ "A Required<...> type was passed as a non-first template parameter to fruit::Component or "
+ "fruit::NormalizedComponent. "
+ "All required types (if any) should be passed together as a single Required<> type passed as the first "
+ "type argument of fruit::Component (and fruit::NormalizedComponent). For example, write "
+ "fruit::Component<fruit::Required<Foo, Bar>, Baz> instead of "
+ "fruit::Component<fruit::Required<Foo>, fruit::Required<Bar>, Baz>.");
};
template <typename T>
struct NonInjectableTypeError {
static_assert(
- AlwaysFalse<T>::value,
- "The type T is not injectable. Injectable types are of the form X, X*, X&, const X, const X*, const X&, "
- "std::shared_ptr<X>, or Provider<X> where X is a fundamental type (excluding void), a class, a struct or "
- "an enum.");
+ AlwaysFalse<T>::value,
+ "The type T is not injectable. Injectable types are of the form X, X*, X&, const X, const X*, const X&, "
+ "std::shared_ptr<X>, or Provider<X> where X is a fundamental type (excluding void), a class, a struct or "
+ "an enum.");
};
template <typename T>
struct ConstBindingDeclaredAsRequiredButNonConstBindingRequiredError {
static_assert(
- AlwaysFalse<T>::value,
- "The type T was declared as a const Required type in the returned Component, however a non-const binding is "
- "required. You should either change all the usages of this type so that they no longer require a non-const binding "
- "(i.e., you shouldn't inject T*, T& or std::shared_ptr<T>) or you should remove the 'const' in the type of the "
- "returned Component, e.g. changing fruit::Component<fruit::Required<const T, ...>, ...> to "
- "fruit::Component<fruit::Required<T, ...>, ...>.");
+ AlwaysFalse<T>::value,
+ "The type T was declared as a const Required type in the returned Component, however a non-const binding is "
+ "required. You should either change all the usages of this type so that they no longer require a non-const "
+ "binding "
+ "(i.e., you shouldn't inject T*, T& or std::shared_ptr<T>) or you should remove the 'const' in the type of the "
+ "returned Component, e.g. changing fruit::Component<fruit::Required<const T, ...>, ...> to "
+ "fruit::Component<fruit::Required<T, ...>, ...>.");
};
template <typename T>
struct ProviderReturningPointerToAbstractClassWithNoVirtualDestructorError {
static_assert(
- AlwaysFalse<T>::value,
- "registerProvider() was called with a lambda that returns a pointer to T, but T is an abstract class with no "
- "virtual destructor so when the injector is deleted Fruit will be unable to call the right destructor (the one of "
- "the concrete class that was then casted to T). You must either add a virtual destructor to T or change the "
- "registerProvider() call to return a pointer to the concrete class (and then add a bind<T, TImpl>() so that T is "
- "bound).");
+ AlwaysFalse<T>::value,
+ "registerProvider() was called with a lambda that returns a pointer to T, but T is an abstract class with no "
+ "virtual destructor so when the injector is deleted Fruit will be unable to call the right destructor (the one "
+ "of "
+ "the concrete class that was then casted to T). You must either add a virtual destructor to T or change the "
+ "registerProvider() call to return a pointer to the concrete class (and then add a bind<T, TImpl>() so that T is "
+ "bound).");
};
template <typename T>
struct MultibindingProviderReturningPointerToAbstractClassWithNoVirtualDestructorError {
static_assert(
- AlwaysFalse<T>::value,
- "registerMultibindingProvider() was called with a lambda that returns a pointer to T, but T is an abstract class "
- "with no virtual destructor so when the injector is deleted Fruit will be unable to call the right destructor (the "
- "one of the concrete class that was then casted to T). You must add a virtual destructor to T or replace the "
- "registerMultibindingProvider() with a registerProvider() for the concrete class and an addMultibinding() for T. "
- "Note that with the latter, if you end up with multiple addMultibinding() calls for the same concrete class, "
- "there will be only one instance of the concrete class in the injector, not one per addMultibdinding() call; if "
- "you want separate instances you might want to use annotated injection for the concrete class (so that there's one "
- "instance per annotation).");
+ AlwaysFalse<T>::value,
+ "registerMultibindingProvider() was called with a lambda that returns a pointer to T, but T is an abstract class "
+ "with no virtual destructor so when the injector is deleted Fruit will be unable to call the right destructor "
+ "(the "
+ "one of the concrete class that was then casted to T). You must add a virtual destructor to T or replace the "
+ "registerMultibindingProvider() with a registerProvider() for the concrete class and an addMultibinding() for T. "
+ "Note that with the latter, if you end up with multiple addMultibinding() calls for the same concrete class, "
+ "there will be only one instance of the concrete class in the injector, not one per addMultibdinding() call; if "
+ "you want separate instances you might want to use annotated injection for the concrete class (so that there's "
+ "one "
+ "instance per annotation).");
};
template <typename T>
struct RegisterFactoryForUniquePtrOfAbstractClassWithNoVirtualDestructorError {
- static_assert(
- AlwaysFalse<T>::value,
- "registerFactory() was called with a lambda that returns a std::unique_ptr<T>, but T is an abstract class with no "
- "virtual destructor so when the returned std::unique_ptr<T> object is deleted the wrong destructor will be called "
- "(T's destructor instead of the one of the concrete class that was then casted to T). You must add a "
- "virtual destructor to T.");
+ static_assert(AlwaysFalse<T>::value,
+ "registerFactory() was called with a lambda that returns a std::unique_ptr<T>, but T is an abstract "
+ "class with no "
+ "virtual destructor so when the returned std::unique_ptr<T> object is deleted the wrong destructor "
+ "will be called "
+ "(T's destructor instead of the one of the concrete class that was then casted to T). You must add a "
+ "virtual destructor to T.");
};
template <typename BaseFactory, typename DerivedFactory>
struct FactoryBindingForUniquePtrOfClassWithNoVirtualDestructorError {
static_assert(
- AlwaysFalse<BaseFactory>::value,
- "Fruit was trying to bind BaseFactory to DerivedFactory but the return type of BaseFactory is a std::unique_ptr of "
- "a class with no virtual destructor, so when the std::unique_ptr object is destroyed the wrong destructor would be "
- "called (the one in the base class instead of the derived class). To avoid this, you must add a virtual "
- "destructor to the base class.");
+ AlwaysFalse<BaseFactory>::value,
+ "Fruit was trying to bind BaseFactory to DerivedFactory but the return type of BaseFactory is a std::unique_ptr "
+ "of "
+ "a class with no virtual destructor, so when the std::unique_ptr object is destroyed the wrong destructor would "
+ "be "
+ "called (the one in the base class instead of the derived class). To avoid this, you must add a virtual "
+ "destructor to the base class.");
};
-
-
struct LambdaWithCapturesErrorTag {
template <typename Lambda>
using apply = LambdaWithCapturesError<Lambda>;
@@ -597,9 +571,7 @@
using apply = FactoryBindingForUniquePtrOfClassWithNoVirtualDestructorError<BaseFactory, DerivedFactory>;
};
-
} // namespace impl
} // namespace fruit
-
#endif // FRUIT_INJECTION_ERRORS
diff --git a/include/fruit/impl/injector.defn.h b/include/fruit/impl/injector.defn.h
index ee7bb0d..4d1acab 100644
--- a/include/fruit/impl/injector.defn.h
+++ b/include/fruit/impl/injector.defn.h
@@ -4,9 +4,9 @@
* 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.
@@ -26,21 +26,16 @@
template <typename... P>
template <typename... FormalArgs, typename... Args>
-inline Injector<P...>::Injector(Component<P...>(*getComponent)(FormalArgs...), Args&&... args) {
+inline Injector<P...>::Injector(Component<P...> (*getComponent)(FormalArgs...), Args&&... args) {
Component<P...> component = fruit::createComponent().install(getComponent, std::forward<Args>(args)...);
fruit::impl::MemoryPool memory_pool;
using exposed_types_t = std::vector<fruit::impl::TypeId, fruit::impl::ArenaAllocator<fruit::impl::TypeId>>;
exposed_types_t exposed_types =
- exposed_types_t(
- std::initializer_list<fruit::impl::TypeId>{fruit::impl::getTypeId<P>()...},
- fruit::impl::ArenaAllocator<fruit::impl::TypeId>(memory_pool));
- storage =
- std::unique_ptr<fruit::impl::InjectorStorage>(
- new fruit::impl::InjectorStorage(
- std::move(component.storage),
- exposed_types,
- memory_pool));
+ exposed_types_t(std::initializer_list<fruit::impl::TypeId>{fruit::impl::getTypeId<P>()...},
+ fruit::impl::ArenaAllocator<fruit::impl::TypeId>(memory_pool));
+ storage = std::unique_ptr<fruit::impl::InjectorStorage>(
+ new fruit::impl::InjectorStorage(std::move(component.storage), exposed_types, memory_pool));
}
namespace impl {
@@ -48,47 +43,46 @@
template <typename... P>
struct InjectorImplHelper {
-
- // This performs all checks needed in the constructor of Injector that takes NormalizedComponent.
+
+ // This performs all checks needed in the constructor of Injector that takes NormalizedComponent.
template <typename NormalizedComp, typename Comp>
struct CheckConstructionFromNormalizedComponent {
using Op = InstallComponent(Comp, NormalizedComp);
-
+
// The calculation of MergedComp will also do some checks, e.g. multiple bindings for the same type.
using MergedComp = GetResult(Op);
-
- using TypesNotProvided = SetDifference(RemoveConstFromTypes(Vector<Type<P>...>),
- GetComponentPs(MergedComp));
- using MergedCompRs = SetDifference(GetComponentRsSuperset(MergedComp),
- GetComponentPs(MergedComp));
-
- using type = Eval<
- If(Not(IsEmptySet(GetComponentRsSuperset(Comp))),
- ConstructErrorWithArgVector(ComponentWithRequirementsInInjectorErrorTag, SetToVector(GetComponentRsSuperset(Comp))),
+
+ using TypesNotProvided = SetDifference(RemoveConstFromTypes(Vector<Type<P>...>), GetComponentPs(MergedComp));
+ using MergedCompRs = SetDifference(GetComponentRsSuperset(MergedComp), GetComponentPs(MergedComp));
+
+ using type = Eval<If(
+ Not(IsEmptySet(GetComponentRsSuperset(Comp))),
+ ConstructErrorWithArgVector(ComponentWithRequirementsInInjectorErrorTag,
+ SetToVector(GetComponentRsSuperset(Comp))),
If(Not(IsEmptySet(MergedCompRs)),
ConstructErrorWithArgVector(UnsatisfiedRequirementsInNormalizedComponentErrorTag, SetToVector(MergedCompRs)),
- If(Not(IsContained(VectorToSetUnchecked(RemoveConstFromTypes(Vector<Type<P>...>)), GetComponentPs(MergedComp))),
- ConstructErrorWithArgVector(TypesInInjectorNotProvidedErrorTag, SetToVector(TypesNotProvided)),
- If(Not(IsContained(VectorToSetUnchecked(RemoveConstTypes(Vector<Type<P>...>)),
- GetComponentNonConstRsPs(MergedComp))),
- ConstructErrorWithArgVector(TypesInInjectorProvidedAsConstOnlyErrorTag,
- SetToVector(SetDifference(VectorToSetUnchecked(RemoveConstTypes(Vector<Type<P>...>)),
- GetComponentNonConstRsPs(MergedComp)))),
- None))))>;
+ If(Not(IsContained(VectorToSetUnchecked(RemoveConstFromTypes(Vector<Type<P>...>)),
+ GetComponentPs(MergedComp))),
+ ConstructErrorWithArgVector(TypesInInjectorNotProvidedErrorTag, SetToVector(TypesNotProvided)),
+ If(Not(IsContained(VectorToSetUnchecked(RemoveConstTypes(Vector<Type<P>...>)),
+ GetComponentNonConstRsPs(MergedComp))),
+ ConstructErrorWithArgVector(
+ TypesInInjectorProvidedAsConstOnlyErrorTag,
+ SetToVector(SetDifference(VectorToSetUnchecked(RemoveConstTypes(Vector<Type<P>...>)),
+ GetComponentNonConstRsPs(MergedComp)))),
+ None))))>;
};
-
+
template <typename T>
struct CheckGet {
using Comp = ConstructComponentImpl(Type<P>...);
- using type = Eval<
- PropagateError(CheckInjectableType(RemoveAnnotations(Type<T>)),
- If(Not(IsInSet(NormalizeType(Type<T>), GetComponentPs(Comp))),
- ConstructError(TypeNotProvidedErrorTag, Type<T>),
- If(And(TypeInjectionRequiresNonConstBinding(Type<T>),
- Not(IsInSet(NormalizeType(Type<T>), GetComponentNonConstRsPs(Comp)))),
- ConstructError(TypeProvidedAsConstOnlyErrorTag, Type<T>),
- None)))>;
+ using type = Eval<PropagateError(CheckInjectableType(RemoveAnnotations(Type<T>)),
+ If(Not(IsInSet(NormalizeType(Type<T>), GetComponentPs(Comp))),
+ ConstructError(TypeNotProvidedErrorTag, Type<T>),
+ If(And(TypeInjectionRequiresNonConstBinding(Type<T>),
+ Not(IsInSet(NormalizeType(Type<T>), GetComponentNonConstRsPs(Comp)))),
+ ConstructError(TypeProvidedAsConstOnlyErrorTag, Type<T>), None)))>;
};
};
@@ -98,23 +92,23 @@
template <typename... P>
template <typename... NormalizedComponentParams, typename... ComponentParams, typename... FormalArgs, typename... Args>
inline Injector<P...>::Injector(const NormalizedComponent<NormalizedComponentParams...>& normalized_component,
- Component<ComponentParams...>(*getComponent)(FormalArgs...), Args&&... args) {
+ Component<ComponentParams...> (*getComponent)(FormalArgs...), Args&&... args) {
Component<ComponentParams...> component = fruit::createComponent().install(getComponent, std::forward<Args>(args)...);
fruit::impl::MemoryPool memory_pool;
- storage =
- std::unique_ptr<fruit::impl::InjectorStorage>(
- new fruit::impl::InjectorStorage(
- *(normalized_component.storage.storage),
- std::move(component.storage),
- memory_pool));
+ storage = std::unique_ptr<fruit::impl::InjectorStorage>(new fruit::impl::InjectorStorage(
+ *(normalized_component.storage.storage), std::move(component.storage), memory_pool));
- using NormalizedComp = fruit::impl::meta::ConstructComponentImpl(fruit::impl::meta::Type<NormalizedComponentParams>...);
+ using NormalizedComp =
+ fruit::impl::meta::ConstructComponentImpl(fruit::impl::meta::Type<NormalizedComponentParams>...);
using Comp1 = fruit::impl::meta::ConstructComponentImpl(fruit::impl::meta::Type<ComponentParams>...);
- // We don't check whether the construction of NormalizedComp or Comp resulted in errors here; if they did, the instantiation
- // of NormalizedComponent<NormalizedComponentParams...> or Component<ComponentParams...> would have resulted in an error already.
-
- using E = typename fruit::impl::meta::InjectorImplHelper<P...>::template CheckConstructionFromNormalizedComponent<NormalizedComp, Comp1>::type;
+ // We don't check whether the construction of NormalizedComp or Comp resulted in errors here; if they did, the
+ // instantiation
+ // of NormalizedComponent<NormalizedComponentParams...> or Component<ComponentParams...> would have resulted in an
+ // error already.
+
+ using E = typename fruit::impl::meta::InjectorImplHelper<P...>::template CheckConstructionFromNormalizedComponent<
+ NormalizedComp, Comp1>::type;
(void)typename fruit::impl::meta::CheckIfError<E>::type();
}
@@ -135,14 +129,11 @@
template <typename... P>
template <typename AnnotatedC>
-inline const std::vector<
- typename fruit::Injector<P...>::template RemoveAnnotationsHelper<AnnotatedC>::type
- *>& Injector<P...>::getMultibindings() {
+inline const std::vector<typename fruit::Injector<P...>::template RemoveAnnotationsHelper<AnnotatedC>::type*>&
+Injector<P...>::getMultibindings() {
- using Op = fruit::impl::meta::Eval<
- fruit::impl::meta::CheckNormalizedTypes(
- fruit::impl::meta::Vector<
- fruit::impl::meta::Type<AnnotatedC>>)>;
+ using Op = fruit::impl::meta::Eval<fruit::impl::meta::CheckNormalizedTypes(
+ fruit::impl::meta::Vector<fruit::impl::meta::Type<AnnotatedC>>)>;
(void)typename fruit::impl::meta::CheckIfError<Op>::type();
return storage->template getMultibindings<AnnotatedC>();
@@ -151,13 +142,14 @@
template <typename... P>
inline void Injector<P...>::eagerlyInjectAll() {
// Eagerly inject normal bindings.
- void* unused[] = {reinterpret_cast<void*>(storage->template get<fruit::impl::meta::UnwrapType<fruit::impl::meta::Eval<fruit::impl::meta::AddPointerInAnnotatedType(fruit::impl::meta::Type<P>)>>>())...};
+ void* unused[] = {reinterpret_cast<void*>(
+ storage->template get<fruit::impl::meta::UnwrapType<
+ fruit::impl::meta::Eval<fruit::impl::meta::AddPointerInAnnotatedType(fruit::impl::meta::Type<P>)>>>())...};
(void)unused;
-
+
storage->eagerlyInjectMultibindings();
}
} // namespace fruit
-
#endif // FRUIT_INJECTOR_DEFN_H
diff --git a/include/fruit/impl/injector/injector_accessor_for_tests.defn.h b/include/fruit/impl/injector/injector_accessor_for_tests.defn.h
index 15183b8..c74c930 100644
--- a/include/fruit/impl/injector/injector_accessor_for_tests.defn.h
+++ b/include/fruit/impl/injector/injector_accessor_for_tests.defn.h
@@ -4,9 +4,9 @@
* 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.
@@ -23,17 +23,13 @@
namespace impl {
template <typename AnnotatedC, typename... Params>
-const typename fruit::Injector<Params...>::template RemoveAnnotations<AnnotatedC>* InjectorAccessorForTests::unsafeGet(
- fruit::Injector<Params...>& injector) {
- using Op = fruit::impl::meta::Eval<
- fruit::impl::meta::CheckNormalizedTypes(
- fruit::impl::meta::Vector<
- fruit::impl::meta::Type<AnnotatedC>>)>;
+const typename fruit::Injector<Params...>::template RemoveAnnotations<AnnotatedC>*
+InjectorAccessorForTests::unsafeGet(fruit::Injector<Params...>& injector) {
+ using Op = fruit::impl::meta::Eval<fruit::impl::meta::CheckNormalizedTypes(
+ fruit::impl::meta::Vector<fruit::impl::meta::Type<AnnotatedC>>)>;
(void)typename fruit::impl::meta::CheckIfError<Op>::type();
return injector.storage->template unsafeGet<AnnotatedC>();
}
-
-
}
}
diff --git a/include/fruit/impl/injector/injector_accessor_for_tests.h b/include/fruit/impl/injector/injector_accessor_for_tests.h
index ea03d32..b2c106c 100644
--- a/include/fruit/impl/injector/injector_accessor_for_tests.h
+++ b/include/fruit/impl/injector/injector_accessor_for_tests.h
@@ -4,9 +4,9 @@
* 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.
@@ -39,16 +39,16 @@
* Note that this doesn't trigger auto-bindings: so even if the constructor of C was visible to some get*Component
* function (or to the place where unsafeGet is called), in order to successfully get an instance with this method
* you need all the following to be true:
- * * C was explicitly bound in a component, or C was a dependency (direct or indirect) of a type that was explicitly bound
+ * * C was explicitly bound in a component, or C was a dependency (direct or indirect) of a type that was explicitly
+ * bound
* * C was not bound to any interface (note however that if C was bound to I, you can do unsafeGet<I>() instead).
*
* Otherwise this method will return nullptr.
*/
template <typename C, typename... Params>
- static const typename fruit::Injector<Params...>::template RemoveAnnotations<C>* unsafeGet(
- fruit::Injector<Params...>& injector);
+ static const typename fruit::Injector<Params...>::template RemoveAnnotations<C>*
+ unsafeGet(fruit::Injector<Params...>& injector);
};
-
}
}
diff --git a/include/fruit/impl/injector/injector_storage.defn.h b/include/fruit/impl/injector/injector_storage.defn.h
index abfe720..b40c5de 100644
--- a/include/fruit/impl/injector/injector_storage.defn.h
+++ b/include/fruit/impl/injector/injector_storage.defn.h
@@ -17,13 +17,13 @@
#ifndef FRUIT_INJECTOR_STORAGE_DEFN_H
#define FRUIT_INJECTOR_STORAGE_DEFN_H
-#include <fruit/impl/util/demangle_type_name.h>
-#include <fruit/impl/util/type_info.h>
-#include <fruit/impl/util/lambda_invoker.h>
-#include <fruit/impl/fruit_assert.h>
-#include <fruit/impl/meta/vector.h>
-#include <fruit/impl/meta/component.h>
#include <fruit/impl/component_storage/component_storage_entry.h>
+#include <fruit/impl/fruit_assert.h>
+#include <fruit/impl/meta/component.h>
+#include <fruit/impl/meta/vector.h>
+#include <fruit/impl/util/demangle_type_name.h>
+#include <fruit/impl/util/lambda_invoker.h>
+#include <fruit/impl/util/type_info.h>
#include <cassert>
@@ -71,10 +71,10 @@
inline bool InjectorStorage::BindingDataNodeIter::isTerminal() {
#ifdef FRUIT_EXTRA_DEBUG
- if (itr->kind != ComponentStorageEntry::Kind::BINDING_FOR_CONSTRUCTED_OBJECT
- && itr->kind != ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_ALLOCATION
- && itr->kind != ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION
- && itr->kind != ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_WITH_UNKNOWN_ALLOCATION) {
+ if (itr->kind != ComponentStorageEntry::Kind::BINDING_FOR_CONSTRUCTED_OBJECT &&
+ itr->kind != ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_ALLOCATION &&
+ itr->kind != ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION &&
+ itr->kind != ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_WITH_UNKNOWN_ALLOCATION) {
std::cerr << "Unexpected binding kind: " << (std::size_t)itr->kind << std::endl;
FruitAssert(false);
}
@@ -83,16 +83,16 @@
}
inline const TypeId* InjectorStorage::BindingDataNodeIter::getEdgesBegin() {
- FruitAssert(itr->kind == ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_ALLOCATION
- || itr->kind == ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION
- || itr->kind == ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_WITH_UNKNOWN_ALLOCATION);
+ FruitAssert(itr->kind == ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_ALLOCATION ||
+ itr->kind == ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION ||
+ itr->kind == ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_WITH_UNKNOWN_ALLOCATION);
return itr->binding_for_object_to_construct.deps->deps;
}
inline const TypeId* InjectorStorage::BindingDataNodeIter::getEdgesEnd() {
- FruitAssert(itr->kind == ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_ALLOCATION
- || itr->kind == ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION
- || itr->kind == ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_WITH_UNKNOWN_ALLOCATION);
+ FruitAssert(itr->kind == ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_ALLOCATION ||
+ itr->kind == ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION ||
+ itr->kind == ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_WITH_UNKNOWN_ALLOCATION);
return itr->binding_for_object_to_construct.deps->deps + itr->binding_for_object_to_construct.deps->num_deps;
}
@@ -162,8 +162,7 @@
};
template <typename Annotation, typename T>
-struct GetFirstStage<fruit::Annotated<Annotation, T>> : public GetFirstStage<T> {
-};
+struct GetFirstStage<fruit::Annotated<Annotation, T>> : public GetFirstStage<T> {};
template <typename AnnotatedT>
struct GetSecondStage;
@@ -228,8 +227,7 @@
};
template <typename Annotation, typename T>
-struct GetSecondStage<fruit::Annotated<Annotation, T>> : public GetSecondStage<T> {
-};
+struct GetSecondStage<fruit::Annotated<Annotation, T>> : public GetSecondStage<T> {};
template <typename AnnotatedT>
inline InjectorStorage::RemoveAnnotations<AnnotatedT> InjectorStorage::get() {
@@ -238,7 +236,8 @@
template <typename T>
inline T InjectorStorage::get(InjectorStorage::Graph::node_iterator node_iterator) {
- FruitStaticAssert(fruit::impl::meta::IsSame(fruit::impl::meta::Type<T>, fruit::impl::meta::RemoveAnnotations(fruit::impl::meta::Type<T>)));
+ FruitStaticAssert(fruit::impl::meta::IsSame(fruit::impl::meta::Type<T>,
+ fruit::impl::meta::RemoveAnnotations(fruit::impl::meta::Type<T>)));
return GetSecondStage<T>()(GetFirstStage<T>()(*this, node_iterator));
}
@@ -248,7 +247,8 @@
}
template <typename AnnotatedC>
-inline InjectorStorage::Graph::node_iterator InjectorStorage::lazyGetPtr(Graph::edge_iterator deps, std::size_t dep_index, Graph::node_iterator bindings_begin) {
+inline InjectorStorage::Graph::node_iterator
+InjectorStorage::lazyGetPtr(Graph::edge_iterator deps, std::size_t dep_index, Graph::node_iterator bindings_begin) {
Graph::node_iterator itr = deps.getNodeIterator(dep_index, bindings_begin);
FruitAssert(bindings.find(getTypeId<AnnotatedC>()) == itr);
FruitAssert(!(bindings.end() == itr));
@@ -257,7 +257,8 @@
template <typename C>
inline const C* InjectorStorage::getPtr(Graph::node_iterator itr) {
- FruitStaticAssert(fruit::impl::meta::IsSame(fruit::impl::meta::Type<C>, fruit::impl::meta::NormalizeType(fruit::impl::meta::Type<C>)));
+ FruitStaticAssert(fruit::impl::meta::IsSame(fruit::impl::meta::Type<C>,
+ fruit::impl::meta::NormalizeType(fruit::impl::meta::Type<C>)));
const void* p = getPtrInternal(itr);
return reinterpret_cast<const C*>(p);
}
@@ -316,7 +317,8 @@
TypeId type = getTypeId<AnnotatedC>();
NormalizedMultibindingSet* multibinding_set = storage.getNormalizedMultibindingSet(type);
- // This method is only called if there was at least 1 multibinding (otherwise the would-be caller would have returned nullptr
+ // This method is only called if there was at least 1 multibinding (otherwise the would-be caller would have returned
+ // nullptr
// instead of calling this).
FruitAssert(multibinding_set != nullptr);
@@ -343,8 +345,9 @@
}
template <typename I, typename C, typename AnnotatedC>
-InjectorStorage::const_object_ptr_t InjectorStorage::createInjectedObjectForBind(
- InjectorStorage& injector, InjectorStorage::Graph::node_iterator node_itr) {
+InjectorStorage::const_object_ptr_t
+InjectorStorage::createInjectedObjectForBind(InjectorStorage& injector,
+ InjectorStorage::Graph::node_iterator node_itr) {
InjectorStorage::Graph::node_iterator bindings_begin = injector.bindings.begin();
const C* cPtr = injector.get<const C*>(injector.lazyGetPtr<AnnotatedC>(node_itr.neighborsBegin(), 0, bindings_begin));
@@ -422,72 +425,70 @@
// The inner operator() takes an InjectorStorage& and a Graph::edge_iterator (the type's deps) and
// returns the injected object as a C*.
// This takes care of move-constructing a C into the injector's own allocator if needed.
-template <typename AnnotatedSignature,
- typename Lambda,
- bool lambda_returns_pointer,
- typename AnnotatedT = InjectorStorage::SignatureType<AnnotatedSignature>,
- typename AnnotatedArgVector = fruit::impl::meta::Eval<fruit::impl::meta::SignatureArgs(fruit::impl::meta::Type<AnnotatedSignature>)>,
- typename Indexes = fruit::impl::meta::Eval<
- fruit::impl::meta::GenerateIntSequence(fruit::impl::meta::VectorSize(
- fruit::impl::meta::SignatureArgs(fruit::impl::meta::Type<AnnotatedSignature>)))
- >>
+template <typename AnnotatedSignature, typename Lambda, bool lambda_returns_pointer,
+ typename AnnotatedT = InjectorStorage::SignatureType<AnnotatedSignature>,
+ typename AnnotatedArgVector =
+ fruit::impl::meta::Eval<fruit::impl::meta::SignatureArgs(fruit::impl::meta::Type<AnnotatedSignature>)>,
+ typename Indexes =
+ fruit::impl::meta::Eval<fruit::impl::meta::GenerateIntSequence(fruit::impl::meta::VectorSize(
+ fruit::impl::meta::SignatureArgs(fruit::impl::meta::Type<AnnotatedSignature>)))>>
struct InvokeLambdaWithInjectedArgVector;
// AnnotatedT is of the form C* or Annotated<Annotation, C*>
-template <typename AnnotatedSignature, typename Lambda, typename AnnotatedT, typename... AnnotatedArgs, typename... Indexes>
-struct InvokeLambdaWithInjectedArgVector<AnnotatedSignature, Lambda, true /* lambda_returns_pointer */, AnnotatedT, fruit::impl::meta::Vector<AnnotatedArgs...>, fruit::impl::meta::Vector<Indexes...>> {
+template <typename AnnotatedSignature, typename Lambda, typename AnnotatedT, typename... AnnotatedArgs,
+ typename... Indexes>
+struct InvokeLambdaWithInjectedArgVector<AnnotatedSignature, Lambda, true /* lambda_returns_pointer */, AnnotatedT,
+ fruit::impl::meta::Vector<AnnotatedArgs...>,
+ fruit::impl::meta::Vector<Indexes...>> {
using CPtr = InjectorStorage::RemoveAnnotations<AnnotatedT>;
using AnnotatedC = InjectorStorage::NormalizeType<AnnotatedT>;
FRUIT_ALWAYS_INLINE
CPtr operator()(InjectorStorage& injector, FixedSizeAllocator& allocator) {
- // `injector' *is* used below, but when there are no AnnotatedArgs some compilers report it as unused.
- (void)injector;
- CPtr cPtr = LambdaInvoker::invoke<
- Lambda,
- typename InjectorStorage::AnnotationRemover<
- typename fruit::impl::meta::TypeUnwrapper<AnnotatedArgs>::type
- >::type...
- >(injector.get<fruit::impl::meta::UnwrapType<AnnotatedArgs>>()...);
+ // `injector' *is* used below, but when there are no AnnotatedArgs some compilers report it as unused.
+ (void)injector;
+ CPtr cPtr =
+ LambdaInvoker::invoke<Lambda, typename InjectorStorage::AnnotationRemover<
+ typename fruit::impl::meta::TypeUnwrapper<AnnotatedArgs>::type>::type...>(
+ injector.get<fruit::impl::meta::UnwrapType<AnnotatedArgs>>()...);
- allocator.registerExternallyAllocatedObject(cPtr);
+ allocator.registerExternallyAllocatedObject(cPtr);
- // This can happen if the user-supplied provider returns nullptr.
- if (cPtr == nullptr) {
- InjectorStorage::fatal("attempting to get an instance for the type " + std::string(getTypeId<AnnotatedC>()) + " but the provider returned nullptr");
- FRUIT_UNREACHABLE; // LCOV_EXCL_LINE
+ // This can happen if the user-supplied provider returns nullptr.
+ if (cPtr == nullptr) {
+ InjectorStorage::fatal("attempting to get an instance for the type " + std::string(getTypeId<AnnotatedC>()) +
+ " but the provider returned nullptr");
+ FRUIT_UNREACHABLE; // LCOV_EXCL_LINE
+ }
+
+ return cPtr;
}
- return cPtr;
-}
-
- // This is not inlined in outerConstructHelper so that when get<> needs to construct an object more complex than a pointer
+ // This is not inlined in outerConstructHelper so that when get<> needs to construct an object more complex than a
+ // pointer
// (e.g. a shared_ptr), that happens as late as possible so that it's easier for the optimizer to optimize out some
// operations (e.g. the increment/decrement/check of shared_ptr's reference count).
template <typename... GetFirstStageResults>
- FRUIT_ALWAYS_INLINE
- CPtr innerConstructHelper(InjectorStorage& injector, GetFirstStageResults... getFirstStageResults) {
+ FRUIT_ALWAYS_INLINE CPtr innerConstructHelper(InjectorStorage& injector,
+ GetFirstStageResults... getFirstStageResults) {
// `injector' *is* used below, but when there are no AnnotatedArgs some compilers report it as unused.
(void)injector;
- return LambdaInvoker::invoke<
- Lambda,
- typename InjectorStorage::AnnotationRemover<
- typename fruit::impl::meta::TypeUnwrapper<AnnotatedArgs>::type
- >::type...
- >(GetSecondStage<InjectorStorage::RemoveAnnotations<fruit::impl::meta::UnwrapType<AnnotatedArgs>>>()(getFirstStageResults)...);
+ return LambdaInvoker::invoke<Lambda, typename InjectorStorage::AnnotationRemover<
+ typename fruit::impl::meta::TypeUnwrapper<AnnotatedArgs>::type>::type...>(
+ GetSecondStage<InjectorStorage::RemoveAnnotations<fruit::impl::meta::UnwrapType<AnnotatedArgs>>>()(
+ getFirstStageResults)...);
}
// This is not inlined in operator() so that all the lazyGetPtr() calls happen first (instead of being interleaved
// with the get() calls). The lazyGetPtr() calls don't branch, while the get() calls branch on the result of the
// lazyGetPtr()s, so it's faster to execute them in this order.
template <typename... NodeItrs>
- FRUIT_ALWAYS_INLINE
- CPtr outerConstructHelper(InjectorStorage& injector, NodeItrs... nodeItrs) {
+ FRUIT_ALWAYS_INLINE CPtr outerConstructHelper(InjectorStorage& injector, NodeItrs... nodeItrs) {
// `injector' *is* used below, but when there are no AnnotatedArgs some compilers report it as unused.
(void)injector;
- return innerConstructHelper(injector,
- GetFirstStage<InjectorStorage::RemoveAnnotations<fruit::impl::meta::UnwrapType<AnnotatedArgs>>>()(injector, nodeItrs)
- ...);
+ return innerConstructHelper(
+ injector, GetFirstStage<InjectorStorage::RemoveAnnotations<fruit::impl::meta::UnwrapType<AnnotatedArgs>>>()(
+ injector, nodeItrs)...);
}
FRUIT_ALWAYS_INLINE
@@ -498,15 +499,17 @@
InjectorStorage::Graph::node_iterator bindings_begin = bindings.begin();
// `bindings_begin' *is* used below, but when there are no AnnotatedArgs some compilers report it as unused.
- (void) bindings_begin;
- CPtr cPtr = outerConstructHelper(injector,
- injector.lazyGetPtr<InjectorStorage::NormalizeType<fruit::impl::meta::UnwrapType<AnnotatedArgs>>>(deps, Indexes::value, bindings_begin)
- ...);
+ (void)bindings_begin;
+ CPtr cPtr = outerConstructHelper(
+ injector,
+ injector.lazyGetPtr<InjectorStorage::NormalizeType<fruit::impl::meta::UnwrapType<AnnotatedArgs>>>(
+ deps, Indexes::value, bindings_begin)...);
allocator.registerExternallyAllocatedObject(cPtr);
// This can happen if the user-supplied provider returns nullptr.
if (cPtr == nullptr) {
- InjectorStorage::fatal("attempting to get an instance for the type " + std::string(getTypeId<AnnotatedC>()) + " but the provider returned nullptr");
+ InjectorStorage::fatal("attempting to get an instance for the type " + std::string(getTypeId<AnnotatedC>()) +
+ " but the provider returned nullptr");
FRUIT_UNREACHABLE; // LCOV_EXCL_LINE
}
@@ -514,82 +517,75 @@
}
};
-template <typename AnnotatedSignature, typename Lambda, typename AnnotatedC, typename... AnnotatedArgs, typename... Indexes>
-struct InvokeLambdaWithInjectedArgVector<AnnotatedSignature, Lambda, false /* lambda_returns_pointer */, AnnotatedC, fruit::impl::meta::Vector<AnnotatedArgs...>, fruit::impl::meta::Vector<Indexes...>> {
+template <typename AnnotatedSignature, typename Lambda, typename AnnotatedC, typename... AnnotatedArgs,
+ typename... Indexes>
+struct InvokeLambdaWithInjectedArgVector<AnnotatedSignature, Lambda, false /* lambda_returns_pointer */, AnnotatedC,
+ fruit::impl::meta::Vector<AnnotatedArgs...>,
+ fruit::impl::meta::Vector<Indexes...>> {
using C = InjectorStorage::RemoveAnnotations<AnnotatedC>;
FRUIT_ALWAYS_INLINE
C* operator()(InjectorStorage& injector, FixedSizeAllocator& allocator) {
// `injector' *is* used below, but when there are no AnnotatedArgs some compilers report it as unused.
- (void)injector;
- return allocator.constructObject<AnnotatedC, C&&>(
- LambdaInvoker::invoke<
- Lambda,
- typename InjectorStorage::AnnotationRemover<
- typename fruit::impl::meta::TypeUnwrapper<AnnotatedArgs>::type
- >::type&&...
- >(injector.get<typename fruit::impl::meta::TypeUnwrapper<AnnotatedArgs>::type>()...)
- );
+ (void)injector;
+ return allocator.constructObject<AnnotatedC, C&&>(
+ LambdaInvoker::invoke<Lambda, typename InjectorStorage::AnnotationRemover<
+ typename fruit::impl::meta::TypeUnwrapper<AnnotatedArgs>::type>::type&&...>(
+ injector.get<typename fruit::impl::meta::TypeUnwrapper<AnnotatedArgs>::type>()...));
}
- // This is not inlined in outerConstructHelper so that when get<> needs to construct an object more complex than a pointer
+ // This is not inlined in outerConstructHelper so that when get<> needs to construct an object more complex than a
+ // pointer
// (e.g. a shared_ptr), that happens as late as possible so that it's easier for the optimizer to optimize out some
// operations (e.g. the increment/decrement/check of shared_ptr's reference count).
template <typename... GetFirstStageResults>
- FRUIT_ALWAYS_INLINE
- C* innerConstructHelper(InjectorStorage& injector, FixedSizeAllocator& allocator, GetFirstStageResults... getFirstStageResults) {
- // `injector' *is* used below, but when there are no AnnotatedArgs some compilers report it as unused.
- (void)injector;
+ FRUIT_ALWAYS_INLINE C* innerConstructHelper(InjectorStorage& injector, FixedSizeAllocator& allocator,
+ GetFirstStageResults... getFirstStageResults) {
+ // `injector' *is* used below, but when there are no AnnotatedArgs some compilers report it as unused.
+ (void)injector;
return allocator.constructObject<AnnotatedC, C&&>(
- LambdaInvoker::invoke<
- Lambda,
- typename InjectorStorage::AnnotationRemover<
- typename fruit::impl::meta::TypeUnwrapper<AnnotatedArgs>::type
- >::type...
- >(
- GetSecondStage<
- typename InjectorStorage::AnnotationRemover<
- typename fruit::impl::meta::TypeUnwrapper<AnnotatedArgs>::type
- >::type
- >()(getFirstStageResults)...
- )
- );
+ LambdaInvoker::invoke<Lambda, typename InjectorStorage::AnnotationRemover<
+ typename fruit::impl::meta::TypeUnwrapper<AnnotatedArgs>::type>::type...>(
+ GetSecondStage<typename InjectorStorage::AnnotationRemover<
+ typename fruit::impl::meta::TypeUnwrapper<AnnotatedArgs>::type>::type>()(getFirstStageResults)...));
}
// This is not inlined in operator() so that all the lazyGetPtr() calls happen first (instead of being interleaved
// with the get() calls). The lazyGetPtr() calls don't branch, while the get() calls branch on the result of the
// lazyGetPtr()s, so it's faster to execute them in this order.
template <typename... NodeItrs>
- FRUIT_ALWAYS_INLINE
- C* outerConstructHelper(InjectorStorage& injector, FixedSizeAllocator& allocator, NodeItrs... nodeItrs) {
- // `injector' *is* used below, but when there are no AnnotatedArgs some compilers report it as unused.
- (void)injector;
- return innerConstructHelper(injector, allocator,
- GetFirstStage<InjectorStorage::RemoveAnnotations<fruit::impl::meta::UnwrapType<AnnotatedArgs>>>()(injector, nodeItrs)
- ...);
+ FRUIT_ALWAYS_INLINE C* outerConstructHelper(InjectorStorage& injector, FixedSizeAllocator& allocator,
+ NodeItrs... nodeItrs) {
+ // `injector' *is* used below, but when there are no AnnotatedArgs some compilers report it as unused.
+ (void)injector;
+ return innerConstructHelper(
+ injector, allocator,
+ GetFirstStage<InjectorStorage::RemoveAnnotations<fruit::impl::meta::UnwrapType<AnnotatedArgs>>>()(injector,
+ nodeItrs)...);
}
C* operator()(InjectorStorage& injector, SemistaticGraph<TypeId, NormalizedBinding>& bindings,
FixedSizeAllocator& allocator, InjectorStorage::Graph::edge_iterator deps) {
InjectorStorage::Graph::node_iterator bindings_begin = bindings.begin();
// `bindings_begin' *is* used below, but when there are no AnnotatedArgs some compilers report it as unused.
- (void) bindings_begin;
+ (void)bindings_begin;
// `deps' *is* used below, but when there are no AnnotatedArgs some compilers report it as unused.
(void)deps;
- // `injector' *is* used below, but when there are no AnnotatedArgs some compilers report it as unused.
- (void)injector;
- C* p = outerConstructHelper(injector, allocator,
- injector.lazyGetPtr<InjectorStorage::NormalizeType<fruit::impl::meta::UnwrapType<AnnotatedArgs>>>(deps, Indexes::value, bindings_begin)
- ...);
+ // `injector' *is* used below, but when there are no AnnotatedArgs some compilers report it as unused.
+ (void)injector;
+ C* p = outerConstructHelper(
+ injector, allocator,
+ injector.lazyGetPtr<InjectorStorage::NormalizeType<fruit::impl::meta::UnwrapType<AnnotatedArgs>>>(
+ deps, Indexes::value, bindings_begin)...);
return p;
}
};
-
template <typename C, typename T, typename AnnotatedSignature, typename Lambda>
-InjectorStorage::const_object_ptr_t InjectorStorage::createInjectedObjectForProvider(InjectorStorage& injector, Graph::node_iterator node_itr) {
+InjectorStorage::const_object_ptr_t InjectorStorage::createInjectedObjectForProvider(InjectorStorage& injector,
+ Graph::node_iterator node_itr) {
C* cPtr = InvokeLambdaWithInjectedArgVector<AnnotatedSignature, Lambda, std::is_pointer<T>::value>()(
injector, injector.bindings, injector.allocator, node_itr.neighborsBegin());
node_itr.setTerminal();
@@ -599,20 +595,22 @@
template <typename AnnotatedSignature, typename Lambda>
inline ComponentStorageEntry InjectorStorage::createComponentStorageEntryForProvider() {
#ifdef FRUIT_EXTRA_DEBUG
- using Signature = fruit::impl::meta::UnwrapType<fruit::impl::meta::Eval<fruit::impl::meta::RemoveAnnotationsFromSignature(fruit::impl::meta::Type<AnnotatedSignature>)>>;
- FruitStaticAssert(fruit::impl::meta::IsSame(fruit::impl::meta::Type<Signature>, fruit::impl::meta::FunctionSignature(fruit::impl::meta::Type<Lambda>)));
+ using Signature =
+ fruit::impl::meta::UnwrapType<fruit::impl::meta::Eval<fruit::impl::meta::RemoveAnnotationsFromSignature(
+ fruit::impl::meta::Type<AnnotatedSignature>)>>;
+ FruitStaticAssert(fruit::impl::meta::IsSame(fruit::impl::meta::Type<Signature>,
+ fruit::impl::meta::FunctionSignature(fruit::impl::meta::Type<Lambda>)));
#endif
using AnnotatedT = SignatureType<AnnotatedSignature>;
using AnnotatedC = NormalizeType<AnnotatedT>;
// T is either C or C*.
- using T = RemoveAnnotations<AnnotatedT>;
- using C = NormalizeType<T>;
+ using T = RemoveAnnotations<AnnotatedT>;
+ using C = NormalizeType<T>;
ComponentStorageEntry result;
constexpr bool needs_allocation = !std::is_pointer<T>::value;
- result.kind =
- needs_allocation
- ? ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_ALLOCATION
- : ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION;
+ result.kind = needs_allocation
+ ? ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_ALLOCATION
+ : ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION;
result.type_id = getTypeId<AnnotatedC>();
ComponentStorageEntry::BindingForObjectToConstruct& binding = result.binding_for_object_to_construct;
binding.create = createInjectedObjectForProvider<C, T, AnnotatedSignature, Lambda>;
@@ -624,8 +622,8 @@
}
template <typename I, typename C, typename T, typename AnnotatedSignature, typename Lambda>
-InjectorStorage::const_object_ptr_t InjectorStorage::createInjectedObjectForCompressedProvider(
- InjectorStorage& injector, Graph::node_iterator node_itr) {
+InjectorStorage::const_object_ptr_t
+InjectorStorage::createInjectedObjectForCompressedProvider(InjectorStorage& injector, Graph::node_iterator node_itr) {
C* cPtr = InvokeLambdaWithInjectedArgVector<AnnotatedSignature, Lambda, std::is_pointer<T>::value>()(
injector, injector.bindings, injector.allocator, node_itr.neighborsBegin());
node_itr.setTerminal();
@@ -636,15 +634,18 @@
template <typename AnnotatedSignature, typename Lambda, typename AnnotatedI>
inline ComponentStorageEntry InjectorStorage::createComponentStorageEntryForCompressedProvider() {
#ifdef FRUIT_EXTRA_DEBUG
- using Signature = fruit::impl::meta::UnwrapType<fruit::impl::meta::Eval<fruit::impl::meta::RemoveAnnotationsFromSignature(fruit::impl::meta::Type<AnnotatedSignature>)>>;
- FruitStaticAssert(fruit::impl::meta::IsSame(fruit::impl::meta::Type<Signature>, fruit::impl::meta::FunctionSignature(fruit::impl::meta::Type<Lambda>)));
+ using Signature =
+ fruit::impl::meta::UnwrapType<fruit::impl::meta::Eval<fruit::impl::meta::RemoveAnnotationsFromSignature(
+ fruit::impl::meta::Type<AnnotatedSignature>)>>;
+ FruitStaticAssert(fruit::impl::meta::IsSame(fruit::impl::meta::Type<Signature>,
+ fruit::impl::meta::FunctionSignature(fruit::impl::meta::Type<Lambda>)));
#endif
using AnnotatedT = SignatureType<AnnotatedSignature>;
using AnnotatedC = NormalizeType<AnnotatedT>;
// T is either C or C*.
- using T = RemoveAnnotations<AnnotatedT>;
- using C = NormalizeType<T>;
- using I = RemoveAnnotations<AnnotatedI>;
+ using T = RemoveAnnotations<AnnotatedT>;
+ using C = NormalizeType<T>;
+ using I = RemoveAnnotations<AnnotatedI>;
ComponentStorageEntry result;
result.kind = ComponentStorageEntry::Kind::COMPRESSED_BINDING;
result.type_id = getTypeId<AnnotatedI>();
@@ -658,40 +659,38 @@
// returns the injected object as a C*.
// This takes care of allocating the required space into the injector's allocator.
template <typename AnnotatedSignature,
- typename Indexes = fruit::impl::meta::Eval<
- fruit::impl::meta::GenerateIntSequence(fruit::impl::meta::VectorSize(
- fruit::impl::meta::SignatureArgs(fruit::impl::meta::Type<AnnotatedSignature>)))
- >>
+ typename Indexes =
+ fruit::impl::meta::Eval<fruit::impl::meta::GenerateIntSequence(fruit::impl::meta::VectorSize(
+ fruit::impl::meta::SignatureArgs(fruit::impl::meta::Type<AnnotatedSignature>)))>>
struct InvokeConstructorWithInjectedArgVector;
template <typename AnnotatedC, typename... AnnotatedArgs, typename... Indexes>
struct InvokeConstructorWithInjectedArgVector<AnnotatedC(AnnotatedArgs...), fruit::impl::meta::Vector<Indexes...>> {
- using C = InjectorStorage::RemoveAnnotations<AnnotatedC>;
+ using C = InjectorStorage::RemoveAnnotations<AnnotatedC>;
- // This is not inlined in outerConstructHelper so that when get<> needs to construct an object more complex than a pointer
+ // This is not inlined in outerConstructHelper so that when get<> needs to construct an object more complex than a
+ // pointer
// (e.g. a shared_ptr), that happens as late as possible so that it's easier for the optimizer to optimize out some
// operations (e.g. the increment/decrement/check of shared_ptr's reference count).
template <typename... GetFirstStageResults>
- FRUIT_ALWAYS_INLINE
- C* innerConstructHelper(InjectorStorage& injector, FixedSizeAllocator& allocator, GetFirstStageResults... getFirstStageResults) {
- // `injector' *is* used below, but when there are no AnnotatedArgs some compilers report it as unused.
- (void)injector;
+ FRUIT_ALWAYS_INLINE C* innerConstructHelper(InjectorStorage& injector, FixedSizeAllocator& allocator,
+ GetFirstStageResults... getFirstStageResults) {
+ // `injector' *is* used below, but when there are no AnnotatedArgs some compilers report it as unused.
+ (void)injector;
return allocator.constructObject<AnnotatedC, typename InjectorStorage::AnnotationRemover<AnnotatedArgs>::type&&...>(
- GetSecondStage<InjectorStorage::RemoveAnnotations<AnnotatedArgs>>()(getFirstStageResults)
- ...);
+ GetSecondStage<InjectorStorage::RemoveAnnotations<AnnotatedArgs>>()(getFirstStageResults)...);
}
// This is not inlined in operator() so that all the lazyGetPtr() calls happen first (instead of being interleaved
// with the get() calls). The lazyGetPtr() calls don't branch, while the get() calls branch on the result of the
// lazyGetPtr()s, so it's faster to execute them in this order.
template <typename... NodeItrs>
- FRUIT_ALWAYS_INLINE
- C* outerConstructHelper(InjectorStorage& injector, FixedSizeAllocator& allocator, NodeItrs... nodeItrs) {
- // `injector' *is* used below, but when there are no AnnotatedArgs some compilers report it as unused.
- (void)injector;
- return innerConstructHelper(injector, allocator,
- GetFirstStage<InjectorStorage::RemoveAnnotations<AnnotatedArgs>>()(injector, nodeItrs)
- ...);
+ FRUIT_ALWAYS_INLINE C* outerConstructHelper(InjectorStorage& injector, FixedSizeAllocator& allocator,
+ NodeItrs... nodeItrs) {
+ // `injector' *is* used below, but when there are no AnnotatedArgs some compilers report it as unused.
+ (void)injector;
+ return innerConstructHelper(
+ injector, allocator, GetFirstStage<InjectorStorage::RemoveAnnotations<AnnotatedArgs>>()(injector, nodeItrs)...);
}
FRUIT_ALWAYS_INLINE
@@ -703,20 +702,19 @@
InjectorStorage::Graph::node_iterator bindings_begin = bindings.begin();
// `bindings_begin' *is* used below, but when there are no Args some compilers report it as unused.
- (void) bindings_begin;
+ (void)bindings_begin;
C* p = outerConstructHelper(injector, allocator,
- injector.lazyGetPtr<typename InjectorStorage::TypeNormalizer<AnnotatedArgs>::type>(
- deps, Indexes::value, bindings_begin)
- ...);
+ injector.lazyGetPtr<typename InjectorStorage::TypeNormalizer<AnnotatedArgs>::type>(
+ deps, Indexes::value, bindings_begin)...);
return p;
}
};
template <typename C, typename AnnotatedSignature>
-InjectorStorage::const_object_ptr_t InjectorStorage::createInjectedObjectForConstructor(
- InjectorStorage& injector, Graph::node_iterator node_itr) {
- C* cPtr = InvokeConstructorWithInjectedArgVector<AnnotatedSignature>()(injector,
- injector.bindings, injector.allocator, node_itr.neighborsBegin());
+InjectorStorage::const_object_ptr_t InjectorStorage::createInjectedObjectForConstructor(InjectorStorage& injector,
+ Graph::node_iterator node_itr) {
+ C* cPtr = InvokeConstructorWithInjectedArgVector<AnnotatedSignature>()(injector, injector.bindings,
+ injector.allocator, node_itr.neighborsBegin());
node_itr.setTerminal();
return reinterpret_cast<InjectorStorage::object_ptr_t>(cPtr);
}
@@ -724,7 +722,7 @@
template <typename AnnotatedSignature>
inline ComponentStorageEntry InjectorStorage::createComponentStorageEntryForConstructor() {
using AnnotatedC = SignatureType<AnnotatedSignature>;
- using C = RemoveAnnotations<AnnotatedC>;
+ using C = RemoveAnnotations<AnnotatedC>;
ComponentStorageEntry result;
result.kind = ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_ALLOCATION;
result.type_id = getTypeId<AnnotatedC>();
@@ -738,10 +736,11 @@
}
template <typename I, typename C, typename AnnotatedSignature>
-InjectorStorage::const_object_ptr_t InjectorStorage::createInjectedObjectForCompressedConstructor(
- InjectorStorage& injector, Graph::node_iterator node_itr) {
- C* cPtr = InvokeConstructorWithInjectedArgVector<AnnotatedSignature>()(injector,
- injector.bindings, injector.allocator, node_itr.neighborsBegin());
+InjectorStorage::const_object_ptr_t
+InjectorStorage::createInjectedObjectForCompressedConstructor(InjectorStorage& injector,
+ Graph::node_iterator node_itr) {
+ C* cPtr = InvokeConstructorWithInjectedArgVector<AnnotatedSignature>()(injector, injector.bindings,
+ injector.allocator, node_itr.neighborsBegin());
node_itr.setTerminal();
I* iPtr = static_cast<I*>(cPtr);
return reinterpret_cast<object_ptr_t>(iPtr);
@@ -750,8 +749,8 @@
template <typename AnnotatedSignature, typename AnnotatedI>
inline ComponentStorageEntry InjectorStorage::createComponentStorageEntryForCompressedConstructor() {
using AnnotatedC = SignatureType<AnnotatedSignature>;
- using C = RemoveAnnotations<AnnotatedC>;
- using I = RemoveAnnotations<AnnotatedI>;
+ using C = RemoveAnnotations<AnnotatedC>;
+ using I = RemoveAnnotations<AnnotatedI>;
ComponentStorageEntry result;
result.kind = ComponentStorageEntry::Kind::COMPRESSED_BINDING;
result.type_id = getTypeId<AnnotatedI>();
@@ -782,9 +781,10 @@
template <typename AnnotatedI, typename AnnotatedC>
inline ComponentStorageEntry InjectorStorage::createComponentStorageEntryForMultibinding() {
- using AnnotatedCPtr = fruit::impl::meta::UnwrapType<fruit::impl::meta::Eval<fruit::impl::meta::AddPointerInAnnotatedType(fruit::impl::meta::Type<AnnotatedC>)>>;
- using I = RemoveAnnotations<AnnotatedI>;
- using C = RemoveAnnotations<AnnotatedC>;
+ using AnnotatedCPtr = fruit::impl::meta::UnwrapType<
+ fruit::impl::meta::Eval<fruit::impl::meta::AddPointerInAnnotatedType(fruit::impl::meta::Type<AnnotatedC>)>>;
+ using I = RemoveAnnotations<AnnotatedI>;
+ using C = RemoveAnnotations<AnnotatedC>;
ComponentStorageEntry result;
result.kind = ComponentStorageEntry::Kind::MULTIBINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION;
result.type_id = getTypeId<AnnotatedI>();
@@ -814,14 +814,17 @@
template <typename AnnotatedSignature, typename Lambda>
inline ComponentStorageEntry InjectorStorage::createComponentStorageEntryForMultibindingProvider() {
#ifdef FRUIT_EXTRA_DEBUG
- using Signature = fruit::impl::meta::UnwrapType<fruit::impl::meta::Eval<fruit::impl::meta::RemoveAnnotationsFromSignature(fruit::impl::meta::Type<AnnotatedSignature>)>>;
- FruitStaticAssert(fruit::impl::meta::IsSame(fruit::impl::meta::Type<Signature>, fruit::impl::meta::FunctionSignature(fruit::impl::meta::Type<Lambda>)));
+ using Signature =
+ fruit::impl::meta::UnwrapType<fruit::impl::meta::Eval<fruit::impl::meta::RemoveAnnotationsFromSignature(
+ fruit::impl::meta::Type<AnnotatedSignature>)>>;
+ FruitStaticAssert(fruit::impl::meta::IsSame(fruit::impl::meta::Type<Signature>,
+ fruit::impl::meta::FunctionSignature(fruit::impl::meta::Type<Lambda>)));
#endif
using AnnotatedT = SignatureType<AnnotatedSignature>;
using AnnotatedC = NormalizeType<AnnotatedT>;
- using T = RemoveAnnotations<AnnotatedT>;
- using C = NormalizeType<T>;
+ using T = RemoveAnnotations<AnnotatedT>;
+ using C = NormalizeType<T>;
ComponentStorageEntry result;
bool needs_allocation = !std::is_pointer<T>::value;
if (needs_allocation)
@@ -838,5 +841,4 @@
} // namespace fruit
} // namespace impl
-
#endif // FRUIT_INJECTOR_STORAGE_DEFN_H
diff --git a/include/fruit/impl/injector/injector_storage.h b/include/fruit/impl/injector/injector_storage.h
index c4cef9b..704f74b 100644
--- a/include/fruit/impl/injector/injector_storage.h
+++ b/include/fruit/impl/injector/injector_storage.h
@@ -4,9 +4,9 @@
* 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.
@@ -22,8 +22,8 @@
#include <fruit/impl/meta/component.h>
#include <fruit/impl/normalized_component_storage/normalized_bindings.h>
-#include <vector>
#include <unordered_map>
+#include <vector>
namespace fruit {
namespace impl {
@@ -34,7 +34,7 @@
/**
* A component where all types have to be explicitly registered, and all checks are at runtime.
* Used to implement Component<>, don't use directly.
- *
+ *
* This class handles the creation of types of the forms:
* - shared_ptr<C>, [const] C*, [const] C&, C (where C is an atomic type)
* - Injector<T1, ..., Tk> (with T1, ..., Tk of the above forms).
@@ -42,43 +42,40 @@
class InjectorStorage {
public:
// TODO: remove.
-// using BindingVectors = std::pair<std::vector<std::pair<TypeId, BindingData>>,
-// std::vector<std::pair<TypeId, MultibindingData>>>;
+ // using BindingVectors = std::pair<std::vector<std::pair<TypeId, BindingData>>,
+ // std::vector<std::pair<TypeId, MultibindingData>>>;
using Graph = SemistaticGraph<TypeId, NormalizedBinding>;
-
+
template <typename AnnotatedT>
- using RemoveAnnotations = fruit::impl::meta::UnwrapType<fruit::impl::meta::Eval<
- fruit::impl::meta::RemoveAnnotations(fruit::impl::meta::Type<AnnotatedT>)
- >>;
+ using RemoveAnnotations = fruit::impl::meta::UnwrapType<
+ fruit::impl::meta::Eval<fruit::impl::meta::RemoveAnnotations(fruit::impl::meta::Type<AnnotatedT>)>>;
// MSVC 14 has trouble specializing alias templates using expanded pack elements.
- // This is a known issue: https://stackoverflow.com/questions/43411542/metaprogramming-failed-to-specialize-alias-template
+ // This is a known issue:
+ // https://stackoverflow.com/questions/43411542/metaprogramming-failed-to-specialize-alias-template
// The workaround is just to use a struct directly.
template <typename AnnotatedT>
struct AnnotationRemover {
using type = RemoveAnnotations<AnnotatedT>;
};
-
+
template <typename T>
- using NormalizeType = fruit::impl::meta::UnwrapType<fruit::impl::meta::Eval<
- fruit::impl::meta::NormalizeType(fruit::impl::meta::Type<T>)
- >>;
+ using NormalizeType = fruit::impl::meta::UnwrapType<
+ fruit::impl::meta::Eval<fruit::impl::meta::NormalizeType(fruit::impl::meta::Type<T>)>>;
template <typename T>
struct TypeNormalizer {
using type = NormalizeType<T>;
};
-
+
template <typename Signature>
- using SignatureType = fruit::impl::meta::UnwrapType<fruit::impl::meta::Eval<
- fruit::impl::meta::SignatureType(fruit::impl::meta::Type<Signature>)
- >>;
-
+ using SignatureType = fruit::impl::meta::UnwrapType<
+ fruit::impl::meta::Eval<fruit::impl::meta::SignatureType(fruit::impl::meta::Type<Signature>)>>;
+
template <typename Signature>
- using NormalizedSignatureArgs = fruit::impl::meta::Eval<
- fruit::impl::meta::NormalizeTypeVector(fruit::impl::meta::SignatureArgs(fruit::impl::meta::Type<Signature>))
- >;
-
+ using NormalizedSignatureArgs = fruit::impl::meta::Eval<fruit::impl::meta::NormalizeTypeVector(
+ fruit::impl::meta::SignatureArgs(fruit::impl::meta::Type<Signature>))>;
+
// Prints the specified error and calls exit(1).
static void fatal(const std::string& error);
@@ -122,55 +119,56 @@
// The NormalizedComponentStorage owned by this object (if any).
// Only used for the 1-argument constructor, otherwise it's nullptr.
std::unique_ptr<NormalizedComponentStorage> normalized_component_storage_ptr;
-
+
FixedSizeAllocator allocator;
-
- // A graph with injected types as nodes (each node stores the NormalizedBindingData for the type) and dependencies as edges.
+
+ // A graph with injected types as nodes (each node stores the NormalizedBindingData for the type) and dependencies as
+ // edges.
// For types that have a constructed object already, the corresponding node is stored as terminal node.
SemistaticGraph<TypeId, NormalizedBinding> bindings;
-
- // Maps the type index of a type T to the corresponding NormalizedMultibindingSet object (that stores all multibindings).
+
+ // Maps the type index of a type T to the corresponding NormalizedMultibindingSet object (that stores all
+ // multibindings).
std::unordered_map<TypeId, NormalizedMultibindingSet> multibindings;
-
+
private:
-
template <typename AnnotatedC>
static std::shared_ptr<char> createMultibindingVector(InjectorStorage& storage);
-
+
// If not bound, returns nullptr.
NormalizedMultibindingSet* getNormalizedMultibindingSet(TypeId type);
-
+
// Looks up the location where the type is (or will be) stored, but does not construct the class.
template <typename AnnotatedC>
Graph::node_iterator lazyGetPtr();
-
+
// getPtr() is equivalent to getPtrInternal(lazyGetPtr())
template <typename C>
const C* getPtr(Graph::node_iterator itr);
-
+
// Similar to the previous, but takes a node_iterator. Use this when the node_iterator is known, it's faster.
const void* getPtrInternal(Graph::node_iterator itr);
-
+
// getPtr(typeInfo) is equivalent to getPtr(lazyGetPtr(typeInfo)).
Graph::node_iterator lazyGetPtr(TypeId type);
-
+
// getPtr(deps, index) is equivalent to getPtr(lazyGetPtr(deps, index)).
Graph::node_iterator lazyGetPtr(Graph::edge_iterator deps, std::size_t dep_index);
-
+
// Similar to getPtr, but the binding might not exist. Returns nullptr if it doesn't.
const void* unsafeGetPtr(TypeId type);
-
+
void* getPtrForMultibinding(TypeId type);
-
+
// Returns a std::vector<T*>*, or nullptr if there are no multibindings.
void* getMultibindings(TypeId type);
-
+
// Constructs any necessary instances, but NOT the instance set.
void ensureConstructedMultibinding(NormalizedMultibindingSet& multibinding_set);
-
+
template <typename T>
friend struct GetFirstStage;
-
+
template <typename T>
friend class fruit::Provider;
@@ -178,24 +176,23 @@
using const_object_ptr_t = const void*;
template <typename I, typename C, typename AnnotatedC>
- static const_object_ptr_t createInjectedObjectForBind(
- InjectorStorage& injector, InjectorStorage::Graph::node_iterator node_itr);
-
+ static const_object_ptr_t createInjectedObjectForBind(InjectorStorage& injector,
+ InjectorStorage::Graph::node_iterator node_itr);
+
template <typename C, typename T, typename AnnotatedSignature, typename Lambda>
- static const_object_ptr_t createInjectedObjectForProvider(
- InjectorStorage& injector, Graph::node_iterator node_itr);
+ static const_object_ptr_t createInjectedObjectForProvider(InjectorStorage& injector, Graph::node_iterator node_itr);
template <typename I, typename C, typename T, typename AnnotatedSignature, typename Lambda>
- static const_object_ptr_t createInjectedObjectForCompressedProvider(
- InjectorStorage& injector, Graph::node_iterator node_itr);
+ static const_object_ptr_t createInjectedObjectForCompressedProvider(InjectorStorage& injector,
+ Graph::node_iterator node_itr);
template <typename C, typename AnnotatedSignature>
- static const_object_ptr_t createInjectedObjectForConstructor(
- InjectorStorage& injector, Graph::node_iterator node_itr);
+ static const_object_ptr_t createInjectedObjectForConstructor(InjectorStorage& injector,
+ Graph::node_iterator node_itr);
template <typename I, typename C, typename AnnotatedSignature>
- static const_object_ptr_t createInjectedObjectForCompressedConstructor(
- InjectorStorage& injector, Graph::node_iterator node_itr);
+ static const_object_ptr_t createInjectedObjectForCompressedConstructor(InjectorStorage& injector,
+ Graph::node_iterator node_itr);
template <typename I, typename C, typename AnnotatedCPtr>
static object_ptr_t createInjectedObjectForMultibinding(InjectorStorage& m);
@@ -204,21 +201,20 @@
static object_ptr_t createInjectedObjectForMultibindingProvider(InjectorStorage& injector);
public:
-
// Wraps a std::vector<ComponentStorageEntry>::iterator as an iterator on tuples
// (typeId, normalizedBindingData, isTerminal, edgesBegin, edgesEnd)
struct BindingDataNodeIter {
std::vector<ComponentStorageEntry, ArenaAllocator<ComponentStorageEntry>>::iterator itr;
-
+
BindingDataNodeIter* operator->();
-
+
void operator++();
-
+
bool operator==(const BindingDataNodeIter& other) const;
bool operator!=(const BindingDataNodeIter& other) const;
-
+
std::ptrdiff_t operator-(BindingDataNodeIter other) const;
-
+
TypeId getId();
NormalizedBinding getValue();
bool isTerminal();
@@ -229,53 +225,51 @@
/**
* The MemoryPool is only used during construction, the constructed object *can* outlive the memory pool.
*/
- InjectorStorage(
- ComponentStorage&& storage,
- const std::vector<TypeId, ArenaAllocator<TypeId>>& exposed_types,
- MemoryPool& memory_pool);
+ InjectorStorage(ComponentStorage&& storage, const std::vector<TypeId, ArenaAllocator<TypeId>>& exposed_types,
+ MemoryPool& memory_pool);
/**
* The MemoryPool is only used during construction, the constructed object *can* outlive the memory pool.
*/
- InjectorStorage(
- const NormalizedComponentStorage& normalized_storage,
- ComponentStorage&& storage,
- MemoryPool& memory_pool);
-
+ InjectorStorage(const NormalizedComponentStorage& normalized_storage, ComponentStorage&& storage,
+ MemoryPool& memory_pool);
+
// This is just the default destructor, but we declare it here to avoid including
// normalized_component_storage.h in fruit.h.
~InjectorStorage();
-
+
InjectorStorage(InjectorStorage&&) = delete;
InjectorStorage& operator=(InjectorStorage&&) = delete;
-
+
InjectorStorage(const InjectorStorage& other) = delete;
InjectorStorage& operator=(const InjectorStorage& other) = delete;
-
+
// Usually get<T>() returns a T.
// However, get<Annotated<Annotation1, T>>() returns a T, not an Annotated<Annotation1, T>.
template <typename AnnotatedT>
RemoveAnnotations<AnnotatedT> get();
-
- // Similar to the above, but specifying the node_iterator of the type. Use this together with lazyGetPtr when the node_iterator is known, it's faster.
+
+ // Similar to the above, but specifying the node_iterator of the type. Use this together with lazyGetPtr when the
+ // node_iterator is known, it's faster.
// Note that T should *not* be annotated.
template <typename T>
T get(InjectorStorage::Graph::node_iterator node_iterator);
-
+
// Looks up the location where the type is (or will be) stored, but does not construct the class.
// get<AnnotatedT>() is equivalent to get<AnnotatedT>(lazyGetPtr<Apply<NormalizeType, AnnotatedT>>(deps, dep_index))
// and also to get<T> (lazyGetPtr<Apply<NormalizeType, AnnotatedT>>(deps, dep_index))
// dep_index is the index of the dep in `deps'.
template <typename AnnotatedC>
- Graph::node_iterator lazyGetPtr(Graph::edge_iterator deps, std::size_t dep_index, Graph::node_iterator bindings_begin);
-
+ Graph::node_iterator lazyGetPtr(Graph::edge_iterator deps, std::size_t dep_index,
+ Graph::node_iterator bindings_begin);
+
// Returns nullptr if AnnotatedC was not bound.
template <typename AnnotatedC>
const RemoveAnnotations<AnnotatedC>* unsafeGet();
-
+
template <typename AnnotatedC>
const std::vector<RemoveAnnotations<AnnotatedC>*>& getMultibindings();
-
+
void eagerlyInjectMultibindings();
};
@@ -284,5 +278,4 @@
#include <fruit/impl/injector/injector_storage.defn.h>
-
#endif // FRUIT_INJECTOR_STORAGE_H
diff --git a/include/fruit/impl/meta/algos.h b/include/fruit/impl/meta/algos.h
index ba3ba7e..a5a1996 100644
--- a/include/fruit/impl/meta/algos.h
+++ b/include/fruit/impl/meta/algos.h
@@ -4,9 +4,9 @@
* 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.
@@ -34,18 +34,17 @@
struct apply {
using type = Bool<false>;
};
-
+
template <typename Type, typename... Types>
struct apply<Type, Types...> {
- using type = Or(StaticOr<std::is_same<Type, Types>::value...>,
- Id<HasDuplicatesHelper(Types...)>);
+ using type = Or(StaticOr<std::is_same<Type, Types>::value...>, Id<HasDuplicatesHelper(Types...)>);
};
-};
+};
struct HasDuplicates {
template <typename V>
struct apply;
-
+
template <typename... Types>
struct apply<Vector<Types...>> {
using type = HasDuplicatesHelper(Types...);
@@ -53,17 +52,16 @@
};
#else // !FRUIT_HAS_CLANG_ARBITRARY_OVERLOAD_RESOLUTION_BUG
-
+
// Checks if the given Vector has duplicated types.
struct HasDuplicates {
template <typename V>
struct apply;
-
+
template <typename... Types>
struct apply<Vector<Types...>> {
using M = VectorsToImmutableMap(Vector<Types...>, GenerateIntSequence(Int<sizeof...(Types)>));
- using type = Not(StaticAnd<Eval<ImmutableMapContainsKey(M, Types)>::value
- ...>);
+ using type = Not(StaticAnd<Eval<ImmutableMapContainsKey(M, Types)>::value...>);
};
};
diff --git a/include/fruit/impl/meta/basics.h b/include/fruit/impl/meta/basics.h
index 1494575..41b7195 100644
--- a/include/fruit/impl/meta/basics.h
+++ b/include/fruit/impl/meta/basics.h
@@ -4,9 +4,9 @@
* 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.
@@ -48,7 +48,8 @@
// that's the result instead.
struct PropagateError {};
-// Used to propagate an ErrorTag::apply<ErrorArgs...> up the instantiation chain, but without instantiating it right away, to allow shorter error stacktraces.
+// Used to propagate an ErrorTag::apply<ErrorArgs...> up the instantiation chain, but without instantiating it right
+// away, to allow shorter error stacktraces.
// Instantiating ErrorTag::apply<ErrorArgs...> must result in a static_assert error.
template <typename ErrorTag, typename... ErrorArgs>
struct Error {};
@@ -73,12 +74,13 @@
using UnwrapType = typename WrappedType::type;
// MSVC 14 has trouble specializing alias templates using expanded pack elements.
-// This is a known issue: https://stackoverflow.com/questions/43411542/metaprogramming-failed-to-specialize-alias-template
+// This is a known issue:
+// https://stackoverflow.com/questions/43411542/metaprogramming-failed-to-specialize-alias-template
// The workaround is just to use a struct directly.
// typename TypeUnwrapper<Type<T>>::type is T.
template <typename WrappedType>
struct TypeUnwrapper {
- using type = UnwrapType<WrappedType>;
+ using type = UnwrapType<WrappedType>;
};
// Logical And with short-circuit evaluation.
@@ -87,22 +89,20 @@
struct apply {
using type = Bool<true>;
};
-
+
template <typename MetaExpr>
struct apply<MetaExpr> {
using type = MetaExpr;
};
-
+
template <typename MetaExpr, typename MetaExpr2>
struct apply<MetaExpr, MetaExpr2> {
using type = If(MetaExpr, MetaExpr2, Bool<false>);
};
-
+
template <typename MetaExpr, typename MetaExpr2, typename... MetaExprs>
struct apply<MetaExpr, MetaExpr2, MetaExprs...> {
- using type = If(MetaExpr,
- If(MetaExpr2, And(MetaExprs...), Bool<false>),
- Bool<false>);
+ using type = If(MetaExpr, If(MetaExpr2, And(MetaExprs...), Bool<false>), Bool<false>);
};
};
@@ -112,33 +112,31 @@
struct apply {
using type = Bool<false>;
};
-
+
template <typename MetaExpr>
struct apply<MetaExpr> {
using type = MetaExpr;
};
-
+
template <typename MetaExpr, typename MetaExpr2>
struct apply<MetaExpr, MetaExpr2> {
using type = If(MetaExpr, Bool<true>, MetaExpr2);
};
-
+
template <typename MetaExpr, typename MetaExpr2, typename... MetaExprs>
struct apply<MetaExpr, MetaExpr2, MetaExprs...> {
- using type = If(MetaExpr,
- Bool<true>,
- If(MetaExpr2, Bool<true>, Or(MetaExprs...)));
+ using type = If(MetaExpr, Bool<true>, If(MetaExpr2, Bool<true>, Or(MetaExprs...)));
};
};
// Call(Call(DeferArgs(F), Args...), MoreArgs...)
-//
+//
// is equivalent to:
// Result = F(Args..., MoreArgs...)
-//
+//
// Note that you can't write:
// DeferArgs(F)(Args...)(MoreArgs...)
-//
+//
// Because Call must be used to call metafunctions that are metaexpressions.
struct DeferArgs {
template <typename F>
@@ -158,13 +156,13 @@
};
// Call(PartialCall(F, Args...), MoreArgs...)
-//
+//
// is equivalent to:
// Result = F(Args..., MoreArgs...)
-//
+//
// Note that you can't write:
// PartialCall(F, Args...)(MoreArgs...)
-//
+//
// Because Call must be used to call metafunctions that are metaexpressions.
struct PartialCall {
template <typename F, typename... Args>
@@ -183,7 +181,7 @@
struct apply {
using type = Bool<false>;
};
-
+
template <typename T>
struct apply<T, T> {
using type = Bool<true>;
@@ -221,7 +219,7 @@
template <typename T>
struct DebugTypeHelper {
- static_assert(sizeof(T*)*0 != 0, "");
+ static_assert(sizeof(T*) * 0 != 0, "");
using type = T;
};
@@ -232,5 +230,4 @@
} // namespace impl
} // namespace fruit
-
#endif // FRUIT_META_BASICS_H
diff --git a/include/fruit/impl/meta/component.h b/include/fruit/impl/meta/component.h
index 3f8e310..54aaf40 100644
--- a/include/fruit/impl/meta/component.h
+++ b/include/fruit/impl/meta/component.h
@@ -4,9 +4,9 @@
* 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.
@@ -19,17 +19,17 @@
#include <fruit/fruit_forward_decls.h>
#include <fruit/impl/fruit_internal_forward_decls.h>
+#include <fruit/impl/injection_debug_errors.h>
#include <fruit/impl/meta/algos.h>
-#include <fruit/impl/meta/set.h>
-#include <fruit/impl/meta/map.h>
+#include <fruit/impl/meta/errors.h>
#include <fruit/impl/meta/list.h>
+#include <fruit/impl/meta/map.h>
#include <fruit/impl/meta/metaprogramming.h>
#include <fruit/impl/meta/numeric_operations.h>
-#include <fruit/impl/meta/errors.h>
#include <fruit/impl/meta/proof_trees.h>
-#include <fruit/impl/meta/wrappers.h>
+#include <fruit/impl/meta/set.h>
#include <fruit/impl/meta/signatures.h>
-#include <fruit/impl/injection_debug_errors.h>
+#include <fruit/impl/meta/wrappers.h>
#include <memory>
#include <type_traits>
@@ -51,37 +51,59 @@
struct apply;
template <typename T>
- struct apply<Type<T>> {using type = Type<T>;};
+ struct apply<Type<T>> {
+ using type = Type<T>;
+ };
template <typename T>
- struct apply<Type<const T>> {using type = Type<T>;};
+ struct apply<Type<const T>> {
+ using type = Type<T>;
+ };
template <typename T>
- struct apply<Type<T*>> {using type = Type<T>;};
+ struct apply<Type<T*>> {
+ using type = Type<T>;
+ };
template <typename T>
- struct apply<Type<T&>> {using type = Type<T>;};
+ struct apply<Type<T&>> {
+ using type = Type<T>;
+ };
template <typename T>
- struct apply<Type<const T*>> {using type = Type<T>;};
+ struct apply<Type<const T*>> {
+ using type = Type<T>;
+ };
template <typename T>
- struct apply<Type<const T&>> {using type = Type<T>;};
+ struct apply<Type<const T&>> {
+ using type = Type<T>;
+ };
template <typename T>
- struct apply<Type<std::shared_ptr<T>>> {using type = Type<T>;};
-
+ struct apply<Type<std::shared_ptr<T>>> {
+ using type = Type<T>;
+ };
+
template <typename T>
- struct apply<Type<Assisted<T>>> {using type = None;};
-
+ struct apply<Type<Assisted<T>>> {
+ using type = None;
+ };
+
template <typename T>
- struct apply<Type<Provider<T>>> {using type = Type<T>;};
-
+ struct apply<Type<Provider<T>>> {
+ using type = Type<T>;
+ };
+
template <typename T>
- struct apply<Type<Provider<const T>>> {using type = Type<T>;};
+ struct apply<Type<Provider<const T>>> {
+ using type = Type<T>;
+ };
template <typename Annotation, typename T>
- struct apply<Type<fruit::Annotated<Annotation, T>>> {using type = Type<T>;};
+ struct apply<Type<fruit::Annotated<Annotation, T>>> {
+ using type = Type<T>;
+ };
};
struct GetClassForTypeVector {
@@ -97,47 +119,67 @@
// can actually get<> the specified type when the class was registered.
template <typename T>
struct apply;
-
- template <typename T>
- struct apply<Type<T>> {using type = Type<T>;};
template <typename T>
- struct apply<Type<const T>> {using type = Type<T>;};
+ struct apply<Type<T>> {
+ using type = Type<T>;
+ };
template <typename T>
- struct apply<Type<T*>> {using type = Type<T>;};
+ struct apply<Type<const T>> {
+ using type = Type<T>;
+ };
template <typename T>
- struct apply<Type<T&>> {using type = Type<T>;};
+ struct apply<Type<T*>> {
+ using type = Type<T>;
+ };
template <typename T>
- struct apply<Type<const T*>> {using type = Type<T>;};
+ struct apply<Type<T&>> {
+ using type = Type<T>;
+ };
template <typename T>
- struct apply<Type<const T&>> {using type = Type<T>;};
+ struct apply<Type<const T*>> {
+ using type = Type<T>;
+ };
template <typename T>
- struct apply<Type<std::shared_ptr<T>>> {using type = Type<T>;};
-
+ struct apply<Type<const T&>> {
+ using type = Type<T>;
+ };
+
template <typename T>
- struct apply<Type<Assisted<T>>> {using type = None;};
-
+ struct apply<Type<std::shared_ptr<T>>> {
+ using type = Type<T>;
+ };
+
template <typename T>
- struct apply<Type<Provider<T>>> {using type = Type<T>;};
-
+ struct apply<Type<Assisted<T>>> {
+ using type = None;
+ };
+
template <typename T>
- struct apply<Type<Provider<const T>>> {using type = Type<T>;};
+ struct apply<Type<Provider<T>>> {
+ using type = Type<T>;
+ };
+
+ template <typename T>
+ struct apply<Type<Provider<const T>>> {
+ using type = Type<T>;
+ };
template <typename Annotation, typename T>
- struct apply<Type<fruit::Annotated<Annotation, T>>> {using type = Type<fruit::Annotated<Annotation, UnwrapType<Eval<NormalizeType(Type<T>)>>>>;};
+ struct apply<Type<fruit::Annotated<Annotation, T>>> {
+ using type = Type<fruit::Annotated<Annotation, UnwrapType<Eval<NormalizeType(Type<T>)>>>>;
+ };
};
struct NormalizeUntilStable {
template <typename T>
struct apply {
- using type = If(IsSame(NormalizeType(T), T),
- T,
- NormalizeUntilStable(NormalizeType(T)));
+ using type = If(IsSame(NormalizeType(T), T), T, NormalizeUntilStable(NormalizeType(T)));
};
};
@@ -153,34 +195,54 @@
struct apply;
template <typename T>
- struct apply<Type<T>> {using type = Bool<false>;};
+ struct apply<Type<T>> {
+ using type = Bool<false>;
+ };
template <typename T>
- struct apply<Type<const T>> {using type = Bool<false>;};
+ struct apply<Type<const T>> {
+ using type = Bool<false>;
+ };
template <typename T>
- struct apply<Type<T*>> {using type = Bool<true>;};
+ struct apply<Type<T*>> {
+ using type = Bool<true>;
+ };
template <typename T>
- struct apply<Type<T&>> {using type = Bool<true>;};
+ struct apply<Type<T&>> {
+ using type = Bool<true>;
+ };
template <typename T>
- struct apply<Type<const T*>> {using type = Bool<false>;};
+ struct apply<Type<const T*>> {
+ using type = Bool<false>;
+ };
template <typename T>
- struct apply<Type<const T&>> {using type = Bool<false>;};
+ struct apply<Type<const T&>> {
+ using type = Bool<false>;
+ };
template <typename T>
- struct apply<Type<std::shared_ptr<T>>> {using type = Bool<true>;};
+ struct apply<Type<std::shared_ptr<T>>> {
+ using type = Bool<true>;
+ };
template <typename T>
- struct apply<Type<Assisted<T>>> {using type = Bool<false>;};
+ struct apply<Type<Assisted<T>>> {
+ using type = Bool<false>;
+ };
template <typename T>
- struct apply<Type<Provider<T>>> {using type = Bool<true>;};
+ struct apply<Type<Provider<T>>> {
+ using type = Bool<true>;
+ };
template <typename T>
- struct apply<Type<Provider<const T>>> {using type = Bool<false>;};
+ struct apply<Type<Provider<const T>>> {
+ using type = Bool<false>;
+ };
template <typename Annotation, typename T>
struct apply<Type<fruit::Annotated<Annotation, T>>> {
@@ -192,12 +254,12 @@
struct CopyAnnotation {
template <typename AnnotatedT, typename U>
struct apply;
-
+
template <typename T, typename U>
struct apply {
using type = U;
};
-
+
template <typename Annotation, typename T, typename U>
struct apply<Type<fruit::Annotated<Annotation, T>>, Type<U>> {
using type = Type<fruit::Annotated<Annotation, U>>;
@@ -220,12 +282,12 @@
struct RemoveAnnotations {
template <typename T>
struct apply;
-
+
template <typename T>
struct apply<Type<T>> {
using type = Type<T>;
};
-
+
template <typename Annotation, typename T>
struct apply<Type<fruit::Annotated<Annotation, T>>> {
using type = Type<T>;
@@ -238,11 +300,10 @@
struct apply {
using type = ConstructError(NotASignatureErrorTag, AnnotatedSignature);
};
-
+
template <typename AnnotatedT, typename... AnnotatedArgs>
struct apply<Type<AnnotatedT(AnnotatedArgs...)>> {
- using type = ConsSignature(RemoveAnnotations(Type<AnnotatedT>),
- Id<RemoveAnnotations(Type<AnnotatedArgs>)>...);
+ using type = ConsSignature(RemoveAnnotations(Type<AnnotatedT>), Id<RemoveAnnotations(Type<AnnotatedArgs>)>...);
};
};
@@ -258,12 +319,12 @@
struct AddPointerInAnnotatedType {
template <typename T>
struct apply;
-
+
template <typename T>
struct apply<Type<T>> {
using type = Type<T*>;
};
-
+
template <typename Annotation, typename T>
struct apply<Type<fruit::Annotated<Annotation, T>>> {
using type = Type<fruit::Annotated<Annotation, T*>>;
@@ -287,7 +348,7 @@
using type = PushBack(CurrentResult, Type<T>);
};
};
-
+
using type = FoldVector(V, Helper, Vector<>);
};
};
@@ -308,7 +369,7 @@
using type = CurrentResult;
};
};
-
+
using type = FoldVector(V, Helper, Vector<>);
};
};
@@ -316,7 +377,7 @@
struct UnlabelAssistedSingleType {
template <typename T>
struct apply;
-
+
template <typename T>
struct apply<Type<T>> {
using type = Type<T>;
@@ -370,7 +431,7 @@
struct apply {
using type = Bool<false>;
};
-
+
template <typename T>
struct apply<Type<Assisted<T>>> {
using type = Bool<true>;
@@ -380,7 +441,7 @@
struct NumAssisted {
template <typename V>
struct apply;
-
+
template <typename... Types>
struct apply<Vector<Types...>> {
using type = SumAll(typename IsAssisted::apply<Types>::type...);
@@ -391,17 +452,16 @@
struct NumAssistedBefore {
template <typename Index, typename V>
struct apply;
-
+
template <typename V>
struct apply<Int<0>, V> {
using type = Int<0>;
};
-
+
template <int n, typename V>
struct apply<Int<n>, V> {
- using N = Int<n>;
- using type = Minus(NumAssisted(V),
- NumAssisted(VectorRemoveFirstN(V, N)));
+ using N = Int<n>;
+ using type = Minus(NumAssisted(V), NumAssisted(VectorRemoveFirstN(V, N)));
};
};
@@ -409,7 +469,7 @@
struct HasInjectAnnotation {
template <typename C>
struct apply;
-
+
template <typename C>
struct apply<Type<C>> {
template <typename C1>
@@ -417,7 +477,7 @@
template <typename>
static Bool<false> test(...);
-
+
using type = decltype(test<C>(nullptr));
};
};
@@ -425,7 +485,7 @@
struct DoGetInjectAnnotation {
template <typename C>
struct apply;
-
+
template <typename C>
struct apply<Type<C>> {
using type = Type<typename C::Inject>;
@@ -442,17 +502,16 @@
using SArgs = RemoveAnnotationsFromVector(UnlabelAssisted(AnnotatedSArgs));
// We replace the non-annotated return type with the potentially-annotated AnnotatedC.
using AnnotatedDecoratedS = ConsSignatureWithVector(AnnotatedC, AnnotatedSArgs);
- using type = If(IsAbstract(C),
- ConstructError(CannotConstructAbstractClassErrorTag, C),
- If(Not(IsValidSignature(DecoratedS)),
- ConstructError(InjectTypedefNotASignatureErrorTag, C, DecoratedS),
- If(Not(IsSame(SResult, RemoveAnnotations(SResult))),
- ConstructError(InjectTypedefWithAnnotationErrorTag, C),
- If(Not(IsSame(C, SResult)),
- ConstructError(InjectTypedefForWrongClassErrorTag, C, SResult),
- If(Not(IsConstructibleWithVector(C, SArgs)),
- ConstructError(NoConstructorMatchingInjectSignatureErrorTag, C, ConsSignatureWithVector(SResult, SArgs)),
- AnnotatedDecoratedS)))));
+ using type = If(IsAbstract(C), ConstructError(CannotConstructAbstractClassErrorTag, C),
+ If(Not(IsValidSignature(DecoratedS)),
+ ConstructError(InjectTypedefNotASignatureErrorTag, C, DecoratedS),
+ If(Not(IsSame(SResult, RemoveAnnotations(SResult))),
+ ConstructError(InjectTypedefWithAnnotationErrorTag, C),
+ If(Not(IsSame(C, SResult)), ConstructError(InjectTypedefForWrongClassErrorTag, C, SResult),
+ If(Not(IsConstructibleWithVector(C, SArgs)),
+ ConstructError(NoConstructorMatchingInjectSignatureErrorTag, C,
+ ConsSignatureWithVector(SResult, SArgs)),
+ AnnotatedDecoratedS)))));
};
};
@@ -460,19 +519,16 @@
// Part 2: Type functors involving at least one ConsComp.
//********************************************************************************************************************************
-template <typename RsSupersetParam,
- typename PsParam,
- typename NonConstRsPsParam,
+template <typename RsSupersetParam, typename PsParam, typename NonConstRsPsParam,
#ifndef FRUIT_NO_LOOP_CHECK
- typename DepsParam,
+ typename DepsParam,
#endif
- typename InterfaceBindingsParam,
- typename DeferredBindingFunctorsParam>
+ typename InterfaceBindingsParam, typename DeferredBindingFunctorsParam>
struct Comp {
// The actual set of requirements is SetDifference(RsSuperset, Ps)
// We don't store Rs explicitly because we'd need to remove elements very often (and that's slow).
using RsSuperset = RsSupersetParam;
-
+
using Ps = PsParam;
// This is a set of normalized types.
// - If a type is in SetDifference(RsSuperset, Ps) and not here: it's required as const only
@@ -480,17 +536,18 @@
// - If a type is in Ps and not here: it's provided as const only
// - If a type is in Ps and also here: it's provided as non-const
using NonConstRsPs = NonConstRsPsParam;
-#ifndef FRUIT_NO_LOOP_CHECK
+#ifndef FRUIT_NO_LOOP_CHECK
using Deps = DepsParam;
#endif
using InterfaceBindings = InterfaceBindingsParam;
using DeferredBindingFunctors = DeferredBindingFunctorsParam;
-
+
// Invariants:
// * all types appearing as arguments of Deps are in Rs
// * all types in Ps are at the head of one (and only one) Dep.
// (note that the types in Rs can appear in deps any number of times, 0 is also ok)
- // * Deps is of the form Vector<Dep...> with each Dep of the form T(Args...) and where Vector<Args...> is a set (no repetitions).
+ // * Deps is of the form Vector<Dep...> with each Dep of the form T(Args...) and where Vector<Args...> is a set (no
+ // repetitions).
// * Bindings is a proof tree forest, with injected classes as formulas.
// * Each element X of the list DeferredBindingFunctors has:
// - a default-constructible X::apply<Comp> type
@@ -502,21 +559,17 @@
// Using ConsComp instead of Comp<...> in a meta-expression allows the types to be evaluated.
// See ConsVector for more details.
struct ConsComp {
- template <typename RsSupersetParam,
- typename PsParam,
- typename NonConstRsPsParam,
+ template <typename RsSupersetParam, typename PsParam, typename NonConstRsPsParam,
#ifndef FRUIT_NO_LOOP_CHECK
typename DepsParam,
#endif
- typename InterfaceBindingsParam,
- typename DeferredBindingFunctorsParam>
+ typename InterfaceBindingsParam, typename DeferredBindingFunctorsParam>
struct apply {
- using type = Comp<
- RsSupersetParam, PsParam, NonConstRsPsParam,
+ using type = Comp<RsSupersetParam, PsParam, NonConstRsPsParam,
#ifndef FRUIT_NO_LOOP_CHECK
- DepsParam,
+ DepsParam,
#endif
- InterfaceBindingsParam, DeferredBindingFunctorsParam>;
+ InterfaceBindingsParam, DeferredBindingFunctorsParam>;
};
};
@@ -554,9 +607,7 @@
template <typename T>
struct apply<Type<T>> {
- using type = Bool<std::is_arithmetic<T>::value
- || std::is_class<T>::value
- || std::is_enum<T>::value>;
+ using type = Bool<std::is_arithmetic<T>::value || std::is_class<T>::value || std::is_enum<T>::value>;
};
template <typename Annotation, typename T>
@@ -582,9 +633,7 @@
struct CheckInjectableType {
template <typename T>
struct apply {
- using type = If(Not(IsInjectableType(T)),
- ConstructError(NonInjectableTypeErrorTag, T),
- None);
+ using type = If(Not(IsInjectableType(T)), ConstructError(NonInjectableTypeErrorTag, T), None);
};
};
@@ -595,8 +644,7 @@
struct Helper {
template <typename CurrentResult, typename T>
struct apply {
- using type = PropagateError(CheckInjectableType(T),
- CurrentResult);
+ using type = PropagateError(CheckInjectableType(T), CurrentResult);
};
};
@@ -619,12 +667,13 @@
struct apply {
using NormalizedType = NormalizeType(T);
using type = PropagateError(CheckInjectableType(RemoveAnnotations(NormalizeUntilStable(T))),
- If(Not(IsSame(NormalizeType(T), T)),
- ConstructError(NonClassTypeErrorTag, RemoveAnnotations(T), RemoveAnnotations(NormalizeUntilStable(T))),
- CurrentResult));
+ If(Not(IsSame(NormalizeType(T), T)),
+ ConstructError(NonClassTypeErrorTag, RemoveAnnotations(T),
+ RemoveAnnotations(NormalizeUntilStable(T))),
+ CurrentResult));
};
};
-
+
using type = Fold(Helper, None, Type<Types>...);
};
};
@@ -642,11 +691,10 @@
struct apply {
using TypeWithoutAnnotations = RemoveAnnotations(T);
using type = If(Not(IsSame(TypeWithoutAnnotations, T)),
- ConstructError(AnnotatedTypeErrorTag, T, TypeWithoutAnnotations),
- CurrentResult);
+ ConstructError(AnnotatedTypeErrorTag, T, TypeWithoutAnnotations), CurrentResult);
};
};
-
+
using type = Fold(Helper, None, Type<Types>...);
};
};
@@ -700,9 +748,7 @@
template <typename... Types>
struct apply<Vector<Types...>> {
- using type = If(HasDuplicates(Vector<Types...>),
- ConstructError(RepeatedTypesErrorTag, Types...),
- None);
+ using type = If(HasDuplicates(Vector<Types...>), ConstructError(RepeatedTypesErrorTag, Types...), None);
};
};
@@ -779,9 +825,7 @@
struct Helper {
template <typename Acc, typename T>
struct apply {
- using type = If(TypeInjectionRequiresNonConstBinding(T),
- PushBack(Acc, NormalizeType(T)),
- Acc);
+ using type = If(TypeInjectionRequiresNonConstBinding(T), PushBack(Acc, NormalizeType(T)), Acc);
};
};
@@ -795,40 +839,37 @@
// Non-specialized case: no requirements.
template <typename... Ps>
struct apply {
- using type = PropagateError(CheckNoRepeatedTypes(RemoveConstFromTypes(Vector<Ps...>)),
- PropagateError(CheckNormalizedTypes(RemoveConstFromTypes(Vector<Ps...>)),
- PropagateError(CheckNoRequiredTypesInComponentArguments(Vector<Ps...>),
- ConsComp(EmptySet,
- VectorToSetUnchecked(RemoveConstFromTypes(Vector<Ps...>)),
- RemoveConstTypes(Vector<Ps...>),
+ using type = PropagateError(
+ CheckNoRepeatedTypes(RemoveConstFromTypes(Vector<Ps...>)),
+ PropagateError(CheckNormalizedTypes(RemoveConstFromTypes(Vector<Ps...>)),
+ PropagateError(CheckNoRequiredTypesInComponentArguments(Vector<Ps...>),
+ ConsComp(EmptySet, VectorToSetUnchecked(RemoveConstFromTypes(Vector<Ps...>)),
+ RemoveConstTypes(Vector<Ps...>),
#ifndef FRUIT_NO_LOOP_CHECK
- Vector<Pair<Ps, Vector<>>...>,
+ Vector<Pair<Ps, Vector<>>...>,
#endif
- Vector<>,
- EmptyList))));
+ Vector<>, EmptyList))));
};
// With requirements.
template <typename... Rs, typename... Ps>
struct apply<Type<Required<Rs...>>, Ps...> {
- using type1 = PropagateError(CheckNoRepeatedTypes(RemoveConstFromTypes(Vector<Type<Rs>..., Ps...>)),
- PropagateError(CheckNormalizedTypes(RemoveConstFromTypes(Vector<Type<Rs>..., Ps...>)),
- PropagateError(CheckNoRequiredTypesInComponentArguments(Vector<Ps...>),
- ConsComp(VectorToSetUnchecked(RemoveConstFromTypes(Vector<Type<Rs>...>)),
- VectorToSetUnchecked(RemoveConstFromTypes(Vector<Ps...>)),
- RemoveConstTypes(Vector<Type<Rs>..., Ps...>),
+ using type1 = PropagateError(
+ CheckNoRepeatedTypes(RemoveConstFromTypes(Vector<Type<Rs>..., Ps...>)),
+ PropagateError(CheckNormalizedTypes(RemoveConstFromTypes(Vector<Type<Rs>..., Ps...>)),
+ PropagateError(CheckNoRequiredTypesInComponentArguments(Vector<Ps...>),
+ ConsComp(VectorToSetUnchecked(RemoveConstFromTypes(Vector<Type<Rs>...>)),
+ VectorToSetUnchecked(RemoveConstFromTypes(Vector<Ps...>)),
+ RemoveConstTypes(Vector<Type<Rs>..., Ps...>),
#ifndef FRUIT_NO_LOOP_CHECK
- Vector<Pair<Ps, Vector<Type<Rs>...>>...>,
+ Vector<Pair<Ps, Vector<Type<Rs>...>>...>,
#endif
- Vector<>,
- EmptyList))));
+ Vector<>, EmptyList))));
#if !defined(FRUIT_NO_LOOP_CHECK) && defined(FRUIT_EXTRA_DEBUG)
using Loop = ProofForestFindLoop(GetComponentDeps(type1));
- using type = If(IsNone(Loop),
- type1,
- ConstructErrorWithArgVector(SelfLoopErrorTag, Loop));
-#else // defined(FRUIT_NO_LOOP_CHECK) || !defined(FRUIT_EXTRA_DEBUG)
+ using type = If(IsNone(Loop), type1, ConstructErrorWithArgVector(SelfLoopErrorTag, Loop));
+#else // defined(FRUIT_NO_LOOP_CHECK) || !defined(FRUIT_EXTRA_DEBUG)
using type = type1;
#endif // defined(FRUIT_NO_LOOP_CHECK) || !defined(FRUIT_EXTRA_DEBUG)
};
@@ -840,10 +881,8 @@
struct Helper {
template <typename Acc, typename T>
struct apply {
- using type = If(And(IsInSet(T, typename Comp::Ps),
- Not(IsInSet(T, typename Comp::NonConstRsPs))),
- ConstructError(NonConstBindingRequiredButConstBindingProvidedErrorTag, T),
- Acc);
+ using type = If(And(IsInSet(T, typename Comp::Ps), Not(IsInSet(T, typename Comp::NonConstRsPs))),
+ ConstructError(NonConstBindingRequiredButConstBindingProvidedErrorTag, T), Acc);
};
};
@@ -856,16 +895,13 @@
struct AddRequirements {
template <typename Comp, typename NewRequirementsVector, typename NewNonConstRequirementsVector>
struct apply {
- using Comp1 = ConsComp(FoldVector(NewRequirementsVector, AddToSet, typename Comp::RsSuperset),
- typename Comp::Ps,
- FoldVector(NewNonConstRequirementsVector, AddToSet, typename Comp::NonConstRsPs),
+ using Comp1 = ConsComp(FoldVector(NewRequirementsVector, AddToSet, typename Comp::RsSuperset), typename Comp::Ps,
+ FoldVector(NewNonConstRequirementsVector, AddToSet, typename Comp::NonConstRsPs),
#ifndef FRUIT_NO_LOOP_CHECK
- typename Comp::Deps,
+ typename Comp::Deps,
#endif
- typename Comp::InterfaceBindings,
- typename Comp::DeferredBindingFunctors);
- using type = PropagateError(CheckTypesNotProvidedAsConst(Comp, NewNonConstRequirementsVector),
- Comp1);
+ typename Comp::InterfaceBindings, typename Comp::DeferredBindingFunctors);
+ using type = PropagateError(CheckTypesNotProvidedAsConst(Comp, NewNonConstRequirementsVector), Comp1);
};
};
@@ -873,22 +909,16 @@
struct AddProvidedTypeIgnoringInterfaceBindings {
template <typename Comp, typename C, typename IsNonConst, typename CRequirements, typename CNonConstRequirements>
struct apply {
- using Comp1 = ConsComp(FoldVector(CRequirements, AddToSet, typename Comp::RsSuperset),
- AddToSetUnchecked(typename Comp::Ps, C),
- If(IsNonConst,
- AddToSetUnchecked(
- FoldVector(CNonConstRequirements, AddToSet, typename Comp::NonConstRsPs),
- C),
- FoldVector(CNonConstRequirements, AddToSet, typename Comp::NonConstRsPs)),
+ using Comp1 = ConsComp(
+ FoldVector(CRequirements, AddToSet, typename Comp::RsSuperset), AddToSetUnchecked(typename Comp::Ps, C),
+ If(IsNonConst, AddToSetUnchecked(FoldVector(CNonConstRequirements, AddToSet, typename Comp::NonConstRsPs), C),
+ FoldVector(CNonConstRequirements, AddToSet, typename Comp::NonConstRsPs)),
#ifndef FRUIT_NO_LOOP_CHECK
- PushFront(typename Comp::Deps, Pair<C, CRequirements>),
+ PushFront(typename Comp::Deps, Pair<C, CRequirements>),
#endif
- typename Comp::InterfaceBindings,
- typename Comp::DeferredBindingFunctors);
- using type = If(IsInSet(C, typename Comp::Ps),
- ConstructError(TypeAlreadyBoundErrorTag, C),
- PropagateError(CheckTypesNotProvidedAsConst(Comp, CNonConstRequirements),
- Comp1));
+ typename Comp::InterfaceBindings, typename Comp::DeferredBindingFunctors);
+ using type = If(IsInSet(C, typename Comp::Ps), ConstructError(TypeAlreadyBoundErrorTag, C),
+ PropagateError(CheckTypesNotProvidedAsConst(Comp, CNonConstRequirements), Comp1));
};
};
@@ -901,23 +931,20 @@
struct apply {
using type = If(Not(IsNone(FindInMap(typename Comp::InterfaceBindings, C))),
ConstructError(TypeAlreadyBoundErrorTag, C),
- AddProvidedTypeIgnoringInterfaceBindings(Comp, C, IsNonConst, CRequirements, CNonConstRequirements));
+ AddProvidedTypeIgnoringInterfaceBindings(Comp, C, IsNonConst, CRequirements,
+ CNonConstRequirements));
};
};
struct AddDeferredBinding {
template <typename Comp, typename DeferredBinding>
struct apply {
- using new_DeferredBindingFunctors = Cons<DeferredBinding,
- typename Comp::DeferredBindingFunctors>;
- using type = ConsComp(typename Comp::RsSuperset,
- typename Comp::Ps,
- typename Comp::NonConstRsPs,
+ using new_DeferredBindingFunctors = Cons<DeferredBinding, typename Comp::DeferredBindingFunctors>;
+ using type = ConsComp(typename Comp::RsSuperset, typename Comp::Ps, typename Comp::NonConstRsPs,
#ifndef FRUIT_NO_LOOP_CHECK
typename Comp::Deps,
#endif
- typename Comp::InterfaceBindings,
- new_DeferredBindingFunctors);
+ typename Comp::InterfaceBindings, new_DeferredBindingFunctors);
};
};
@@ -925,9 +952,7 @@
template <typename Comp>
struct apply {
using Loop = ProofForestFindLoop(typename Comp::Deps);
- using type = If(IsNone(Loop),
- Bool<true>,
- ConstructErrorWithArgVector(SelfLoopErrorTag, Loop));
+ using type = If(IsNone(Loop), Bool<true>, ConstructErrorWithArgVector(SelfLoopErrorTag, Loop));
};
};
@@ -935,29 +960,34 @@
struct CheckComponentEntails {
template <typename Comp, typename EntailedComp>
struct apply {
- using CompRs = SetDifference(typename Comp::RsSuperset, typename Comp::Ps);
+ using CompRs = SetDifference(typename Comp::RsSuperset, typename Comp::Ps);
using EntailedCompRs = SetDifference(typename EntailedComp::RsSuperset, typename EntailedComp::Ps);
using CommonRs = SetIntersection(CompRs, EntailedCompRs);
using CommonPs = SetIntersection(typename Comp::Ps, typename EntailedComp::Ps);
- using type = If(Not(IsContained(typename EntailedComp::Ps, typename Comp::Ps)),
- ConstructErrorWithArgVector(ComponentDoesNotEntailDueToProvidesErrorTag,
- SetToVector(SetDifference(typename EntailedComp::Ps,
- typename Comp::Ps))),
- If(Not(IsVectorContained(typename EntailedComp::InterfaceBindings,
- typename Comp::InterfaceBindings)),
- ConstructErrorWithArgVector(ComponentDoesNotEntailDueToInterfaceBindingsErrorTag,
- SetToVector(SetDifference(typename EntailedComp::InterfaceBindings,
- typename Comp::InterfaceBindings))),
- If(Not(IsContained(CompRs, EntailedCompRs)),
- ConstructErrorWithArgVector(ComponentDoesNotEntailDueToRequirementsErrorTag,
- SetToVector(SetDifference(CompRs, EntailedCompRs))),
- If(Not(IsContained(SetIntersection(CommonRs, typename Comp::NonConstRsPs), typename EntailedComp::NonConstRsPs)),
+ using type =
+ If(Not(IsContained(typename EntailedComp::Ps, typename Comp::Ps)),
+ ConstructErrorWithArgVector(ComponentDoesNotEntailDueToProvidesErrorTag,
+ SetToVector(SetDifference(typename EntailedComp::Ps, typename Comp::Ps))),
+ If(Not(IsVectorContained(typename EntailedComp::InterfaceBindings, typename Comp::InterfaceBindings)),
+ ConstructErrorWithArgVector(ComponentDoesNotEntailDueToInterfaceBindingsErrorTag,
+ SetToVector(SetDifference(typename EntailedComp::InterfaceBindings,
+ typename Comp::InterfaceBindings))),
+ If(Not(IsContained(CompRs, EntailedCompRs)),
+ ConstructErrorWithArgVector(ComponentDoesNotEntailDueToRequirementsErrorTag,
+ SetToVector(SetDifference(CompRs, EntailedCompRs))),
+ If(Not(IsContained(SetIntersection(CommonRs, typename Comp::NonConstRsPs),
+ typename EntailedComp::NonConstRsPs)),
ConstructErrorWithArgVector(ComponentDoesNotEntailDueToDifferentConstnessOfRequirementsErrorTag,
- SetToVector(SetDifference(SetIntersection(CommonRs, typename Comp::NonConstRsPs), typename EntailedComp::NonConstRsPs))),
- If(Not(IsContained(SetIntersection(CommonPs, typename EntailedComp::NonConstRsPs), typename Comp::NonConstRsPs)),
- ConstructErrorWithArgVector(ComponentDoesNotEntailDueToDifferentConstnessOfProvidesErrorTag,
- SetToVector(SetDifference(SetIntersection(CommonPs, typename EntailedComp::NonConstRsPs), typename Comp::NonConstRsPs))),
- Bool<true>)))));
+ SetToVector(SetDifference(SetIntersection(CommonRs,
+ typename Comp::NonConstRsPs),
+ typename EntailedComp::NonConstRsPs))),
+ If(Not(IsContained(SetIntersection(CommonPs, typename EntailedComp::NonConstRsPs),
+ typename Comp::NonConstRsPs)),
+ ConstructErrorWithArgVector(
+ ComponentDoesNotEntailDueToDifferentConstnessOfProvidesErrorTag,
+ SetToVector(SetDifference(SetIntersection(CommonPs, typename EntailedComp::NonConstRsPs),
+ typename Comp::NonConstRsPs))),
+ Bool<true>)))));
static_assert(true || sizeof(typename CheckIfError<Eval<type>>::type), "");
};
};
diff --git a/include/fruit/impl/meta/errors.h b/include/fruit/impl/meta/errors.h
index 57044c2..6f9de8a 100644
--- a/include/fruit/impl/meta/errors.h
+++ b/include/fruit/impl/meta/errors.h
@@ -4,9 +4,9 @@
* 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.
@@ -50,11 +50,10 @@
struct ExtractFirstError {
template <typename... Types>
struct apply;
-
+
template <typename Type, typename... Types>
- struct apply<Type, Types...> : public apply<Types...> {
- };
-
+ struct apply<Type, Types...> : public apply<Types...> {};
+
template <typename ErrorTag, typename... ErrorParams, typename... Types>
struct apply<Error<ErrorTag, ErrorParams...>, Types...> {
using type = Error<ErrorTag, ErrorParams...>;
@@ -65,5 +64,4 @@
} // namespace impl
} // namespace fruit
-
#endif // FRUIT_META_ERRORS_H
diff --git a/include/fruit/impl/meta/eval.h b/include/fruit/impl/meta/eval.h
index 78074e2..268b7dd 100644
--- a/include/fruit/impl/meta/eval.h
+++ b/include/fruit/impl/meta/eval.h
@@ -4,9 +4,9 @@
* 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.
@@ -18,8 +18,8 @@
#define FRUIT_META_EVAL_H
#include <fruit/impl/meta/basics.h>
-#include <fruit/impl/meta/logical_operations.h>
#include <fruit/impl/meta/errors.h>
+#include <fruit/impl/meta/logical_operations.h>
#include <functional>
@@ -34,7 +34,9 @@
template <typename MetaExpr>
struct DoEval {
#ifdef FRUIT_TRACE_INSTANTIATIONS
- constexpr static bool static_warning() __attribute__((deprecated("static_warning"))) { return true; }
+ constexpr static bool static_warning() __attribute__((deprecated("static_warning"))) {
+ return true;
+ }
static_assert(static_warning(), "");
#endif
using type = MetaExpr;
@@ -57,37 +59,32 @@
template <typename MetaFun, typename... Params>
struct DoEvalFun {
using type =
- typename DoEval<typename
- std::conditional<StaticOr<SimpleIsError<Params>::value...>::value,
- ExtractFirstError,
- MetaFun>::type
- ::template apply<
- Params...
- >::type>::type;
+ typename DoEval<typename std::conditional<StaticOr<SimpleIsError<Params>::value...>::value, ExtractFirstError,
+ MetaFun>::type::template apply<Params...>::type>::type;
};
template <typename MetaFun, typename... MetaExprs>
struct DoEval<MetaFun(MetaExprs...)> {
#ifdef FRUIT_TRACE_INSTANTIATIONS
- constexpr static bool static_warning() __attribute__((deprecated("static_warning"))) { return true; }
+ constexpr static bool static_warning() __attribute__((deprecated("static_warning"))) {
+ return true;
+ }
static_assert(static_warning(), "");
#endif
- using type = typename DoEvalFun<MetaFun,
- typename DoEval<MetaExprs>::type...
- >::type;
+ using type = typename DoEvalFun<MetaFun, typename DoEval<MetaExprs>::type...>::type;
};
// Similar to the previous specialization, but this will be selected when the function signature
// became a function pointer (this happens when a signature parameter is itself a signature).
template <typename MetaFun, typename... MetaExprs>
-struct DoEval<MetaFun(*)(MetaExprs...)> {
+struct DoEval<MetaFun (*)(MetaExprs...)> {
#ifdef FRUIT_TRACE_INSTANTIATIONS
- constexpr static bool static_warning() __attribute__((deprecated("static_warning"))) { return true; }
+ constexpr static bool static_warning() __attribute__((deprecated("static_warning"))) {
+ return true;
+ }
static_assert(static_warning(), "");
#endif
- using type = typename DoEvalFun<MetaFun,
- typename DoEval<MetaExprs>::type...
- >::type;
+ using type = typename DoEvalFun<MetaFun, typename DoEval<MetaExprs>::type...>::type;
};
#else // FRUIT_EXTRA_DEBUG
@@ -95,35 +92,29 @@
template <typename MetaFun, typename... MetaExprs>
struct DoEval<MetaFun(MetaExprs...)> {
#ifdef FRUIT_TRACE_INSTANTIATIONS
- constexpr static bool static_warning() __attribute__((deprecated("static_warning"))) { return true; }
+ constexpr static bool static_warning() __attribute__((deprecated("static_warning"))) {
+ return true;
+ }
static_assert(static_warning(), "");
#endif
- using type =
- typename DoEval<typename
- std::conditional<StaticOr<SimpleIsError<typename DoEval<MetaExprs>::type>::value...>::value,
- ExtractFirstError,
- MetaFun>::type
- ::template apply<
- typename DoEval<MetaExprs>::type...
- >::type>::type;
+ using type = typename DoEval<typename std::conditional<
+ StaticOr<SimpleIsError<typename DoEval<MetaExprs>::type>::value...>::value, ExtractFirstError,
+ MetaFun>::type::template apply<typename DoEval<MetaExprs>::type...>::type>::type;
};
// Similar to the previous specialization, but this will be selected when the function signature
// became a function pointer (this happens when a signature parameter is itself a signature).
template <typename MetaFun, typename... MetaExprs>
-struct DoEval<MetaFun(*)(MetaExprs...)> {
+struct DoEval<MetaFun (*)(MetaExprs...)> {
#ifdef FRUIT_TRACE_INSTANTIATIONS
- constexpr static bool static_warning() __attribute__((deprecated("static_warning"))) { return true; }
+ constexpr static bool static_warning() __attribute__((deprecated("static_warning"))) {
+ return true;
+ }
static_assert(static_warning(), "");
#endif
- using type =
- typename DoEval<typename
- std::conditional<StaticOr<SimpleIsError<typename DoEval<MetaExprs>::type>::value...>::value,
- ExtractFirstError,
- MetaFun>::type
- ::template apply<
- typename DoEval<MetaExprs>::type...
- >::type>::type;
+ using type = typename DoEval<typename std::conditional<
+ StaticOr<SimpleIsError<typename DoEval<MetaExprs>::type>::value...>::value, ExtractFirstError,
+ MetaFun>::type::template apply<typename DoEval<MetaExprs>::type...>::type>::type;
};
#endif // FRUIT_EXTRA_DEBUG
@@ -135,10 +126,10 @@
template <typename CaughtErrorTag, typename... ErrorArgs, typename Handler>
struct EvalCatch<Error<CaughtErrorTag, ErrorArgs...>, CaughtErrorTag, Handler> {
- using type = typename DoEval<typename DoEval<Handler>::type::template apply<Error<CaughtErrorTag, ErrorArgs...>>::type>::type;
+ using type =
+ typename DoEval<typename DoEval<Handler>::type::template apply<Error<CaughtErrorTag, ErrorArgs...>>::type>::type;
};
-
template <typename ExprResult, typename Handler>
struct EvalCatchAll {
using type = ExprResult;
@@ -146,33 +137,28 @@
template <typename CaughtErrorTag, typename... ErrorArgs, typename Handler>
struct EvalCatchAll<Error<CaughtErrorTag, ErrorArgs...>, Handler> {
- using type = typename DoEval<typename DoEval<Handler>::type::template apply<Error<CaughtErrorTag, ErrorArgs...>>::type>::type;
+ using type =
+ typename DoEval<typename DoEval<Handler>::type::template apply<Error<CaughtErrorTag, ErrorArgs...>>::type>::type;
};
template <typename Expr, typename ErrorTag, typename Handler>
struct DoEval<Catch(Expr, ErrorTag, Handler)> {
- using type = typename EvalCatch<typename DoEval<Expr>::type,
- typename DoEval<ErrorTag>::type,
- Handler>::type;
+ using type = typename EvalCatch<typename DoEval<Expr>::type, typename DoEval<ErrorTag>::type, Handler>::type;
};
template <typename Expr, typename ErrorTag, typename Handler>
-struct DoEval<Catch(*)(Expr, ErrorTag, Handler)> {
- using type = typename EvalCatch<typename DoEval<Expr>::type,
- typename DoEval<ErrorTag>::type,
- Handler>::type;
+struct DoEval<Catch (*)(Expr, ErrorTag, Handler)> {
+ using type = typename EvalCatch<typename DoEval<Expr>::type, typename DoEval<ErrorTag>::type, Handler>::type;
};
template <typename Expr, typename Handler>
struct DoEval<CatchAll(Expr, Handler)> {
- using type = typename EvalCatchAll<typename DoEval<Expr>::type,
- Handler>::type;
+ using type = typename EvalCatchAll<typename DoEval<Expr>::type, Handler>::type;
};
template <typename Expr, typename Handler>
-struct DoEval<CatchAll(*)(Expr, Handler)> {
- using type = typename EvalCatchAll<typename DoEval<Expr>::type,
- Handler>::type;
+struct DoEval<CatchAll (*)(Expr, Handler)> {
+ using type = typename EvalCatchAll<typename DoEval<Expr>::type, Handler>::type;
};
template <typename MetaBool, typename ThenMetaExpr, typename ElseMetaExpr>
@@ -186,7 +172,9 @@
template <typename ThenMetaExpr, typename ElseMetaExpr>
struct EvalIf<Bool<true>, ThenMetaExpr, ElseMetaExpr> {
#ifdef FRUIT_TRACE_INSTANTIATIONS
- constexpr static bool static_warning() __attribute__((deprecated("static_warning"))) { return true; }
+ constexpr static bool static_warning() __attribute__((deprecated("static_warning"))) {
+ return true;
+ }
static_assert(static_warning(), "");
#endif
using type = typename DoEval<ThenMetaExpr>::type;
@@ -195,7 +183,9 @@
template <typename ThenMetaExpr, typename ElseMetaExpr>
struct EvalIf<Bool<false>, ThenMetaExpr, ElseMetaExpr> {
#ifdef FRUIT_TRACE_INSTANTIATIONS
- constexpr static bool static_warning() __attribute__((deprecated("static_warning"))) { return true; }
+ constexpr static bool static_warning() __attribute__((deprecated("static_warning"))) {
+ return true;
+ }
static_assert(static_warning(), "");
#endif
using type = typename DoEval<ElseMetaExpr>::type;
@@ -204,27 +194,25 @@
template <typename CondMetaExpr, typename ThenMetaExpr, typename ElseMetaExpr>
struct DoEval<If(CondMetaExpr, ThenMetaExpr, ElseMetaExpr)> {
#ifdef FRUIT_TRACE_INSTANTIATIONS
- constexpr static bool static_warning() __attribute__((deprecated("static_warning"))) { return true; }
+ constexpr static bool static_warning() __attribute__((deprecated("static_warning"))) {
+ return true;
+ }
static_assert(static_warning(), "");
#endif
- using type = typename EvalIf<typename DoEval<CondMetaExpr>::type,
- ThenMetaExpr,
- ElseMetaExpr
- >::type;
+ using type = typename EvalIf<typename DoEval<CondMetaExpr>::type, ThenMetaExpr, ElseMetaExpr>::type;
};
// Similar to the previous specialization, but this will be selected when the function signature
// became a function pointer (this happens when a signature parameter is itself a signature).
template <typename CondMetaExpr, typename ThenMetaExpr, typename ElseMetaExpr>
-struct DoEval<If(*)(CondMetaExpr, ThenMetaExpr, ElseMetaExpr)> {
+struct DoEval<If (*)(CondMetaExpr, ThenMetaExpr, ElseMetaExpr)> {
#ifdef FRUIT_TRACE_INSTANTIATIONS
- constexpr static bool static_warning() __attribute__((deprecated("static_warning"))) { return true; }
+ constexpr static bool static_warning() __attribute__((deprecated("static_warning"))) {
+ return true;
+ }
static_assert(static_warning(), "");
#endif
- using type = typename EvalIf<typename DoEval<CondMetaExpr>::type,
- ThenMetaExpr,
- ElseMetaExpr
- >::type;
+ using type = typename EvalIf<typename DoEval<CondMetaExpr>::type, ThenMetaExpr, ElseMetaExpr>::type;
};
template <typename T, typename ElseMetaExpr>
@@ -240,25 +228,25 @@
template <typename MaybeErrorMetaExpr, typename ElseMetaExpr>
struct DoEval<PropagateError(MaybeErrorMetaExpr, ElseMetaExpr)> {
#ifdef FRUIT_TRACE_INSTANTIATIONS
- constexpr static bool static_warning() __attribute__((deprecated("static_warning"))) { return true; }
+ constexpr static bool static_warning() __attribute__((deprecated("static_warning"))) {
+ return true;
+ }
static_assert(static_warning(), "");
#endif
- using type = typename EvalPropagateError<typename DoEval<MaybeErrorMetaExpr>::type,
- ElseMetaExpr
- >::type;
+ using type = typename EvalPropagateError<typename DoEval<MaybeErrorMetaExpr>::type, ElseMetaExpr>::type;
};
// Similar to the previous specialization, but this will be selected when the function signature
// became a function pointer (this happens when a signature parameter is itself a signature).
template <typename MaybeErrorMetaExpr, typename ElseMetaExpr>
-struct DoEval<PropagateError(*)(MaybeErrorMetaExpr, ElseMetaExpr)> {
+struct DoEval<PropagateError (*)(MaybeErrorMetaExpr, ElseMetaExpr)> {
#ifdef FRUIT_TRACE_INSTANTIATIONS
- constexpr static bool static_warning() __attribute__((deprecated("static_warning"))) { return true; }
+ constexpr static bool static_warning() __attribute__((deprecated("static_warning"))) {
+ return true;
+ }
static_assert(static_warning(), "");
#endif
- using type = typename EvalPropagateError<typename DoEval<MaybeErrorMetaExpr>::type,
- ElseMetaExpr
- >::type;
+ using type = typename EvalPropagateError<typename DoEval<MaybeErrorMetaExpr>::type, ElseMetaExpr>::type;
};
template <typename MetaExpr>
@@ -268,5 +256,4 @@
} // namespace impl
} // namespace fruit
-
#endif // FRUIT_META_EVAL_H
diff --git a/include/fruit/impl/meta/fold.h b/include/fruit/impl/meta/fold.h
index ea3bd5b..e8c86f5 100644
--- a/include/fruit/impl/meta/fold.h
+++ b/include/fruit/impl/meta/fold.h
@@ -4,9 +4,9 @@
* 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.
@@ -26,112 +26,94 @@
struct Fold {
template <typename F, typename InitialValue, typename... Types>
struct apply;
-
+
template <typename F, typename InitialValue>
struct apply<F, InitialValue> {
using type = InitialValue;
};
-
+
template <typename F, typename InitialValue, typename T0>
struct apply<F, InitialValue, T0> {
- using type = typename F::template apply<
- InitialValue,
- T0>::type;
+ using type = typename F::template apply<InitialValue, T0>::type;
};
-
+
template <typename F, typename InitialValue, typename T0, typename T1>
struct apply<F, InitialValue, T0, T1> {
- using type = typename F::template apply<
- typename DoEval<typename F::template apply<
- InitialValue,
- T0>::type>::type,
- T1>::type;
+ using type =
+ typename F::template apply<typename DoEval<typename F::template apply<InitialValue, T0>::type>::type, T1>::type;
};
-
+
template <typename F, typename InitialValue, typename T0, typename T1, typename T2>
struct apply<F, InitialValue, T0, T1, T2> {
using type = typename F::template apply<
- typename DoEval<typename F::template apply<
- typename DoEval<typename F::template apply<
- InitialValue,
- T0>::type>::type,
- T1>::type>::type,
- T2>::type;
+ typename DoEval<typename F::template apply<
+ typename DoEval<typename F::template apply<InitialValue, T0>::type>::type, T1>::type>::type,
+ T2>::type;
};
-
+
template <typename F, typename InitialValue, typename T0, typename T1, typename T2, typename T3>
struct apply<F, InitialValue, T0, T1, T2, T3> {
using type = typename F::template apply<
- typename DoEval<typename F::template apply<
- typename DoEval<typename F::template apply<
- typename DoEval<typename F::template apply<
- InitialValue,
- T0>::type>::type,
- T1>::type>::type,
- T2>::type>::type,
- T3>::type;
+ typename DoEval<typename F::template apply<
+ typename DoEval<typename F::template apply<
+ typename DoEval<typename F::template apply<InitialValue, T0>::type>::type, T1>::type>::type,
+ T2>::type>::type,
+ T3>::type;
};
-
+
template <typename F, typename InitialValue, typename T0, typename T1, typename T2, typename T3, typename T4>
struct apply<F, InitialValue, T0, T1, T2, T3, T4> {
using type = typename F::template apply<
- typename DoEval<typename F::template apply<
- typename DoEval<typename F::template apply<
- typename DoEval<typename F::template apply<
- typename DoEval<typename F::template apply<
- InitialValue,
- T0>::type>::type,
- T1>::type>::type,
- T2>::type>::type,
- T3>::type>::type,
- T4>::type;
+ typename DoEval<typename F::template apply<
+ typename DoEval<typename F::template apply<
+ typename DoEval<typename F::template apply<
+ typename DoEval<typename F::template apply<InitialValue, T0>::type>::type, T1>::type>::type,
+ T2>::type>::type,
+ T3>::type>::type,
+ T4>::type;
};
-
- template <typename F, typename InitialValue, typename T0, typename T1, typename T2, typename T3, typename T4, typename... Types>
- struct apply<F, InitialValue, T0, T1, T2, T3, T4, Types...> {
- using type = Fold(F,
- typename F::template apply<
- typename DoEval<typename F::template apply<
- typename DoEval<typename F::template apply<
- typename DoEval<typename F::template apply<
- typename DoEval<typename F::template apply<
- InitialValue,
- T0>::type>::type,
- T1>::type>::type,
- T2>::type>::type,
- T3>::type>::type,
- T4>::type,
- Types...);
- };
-
- // Optimized specialization, processing 10 values at a time.
- template <typename F, typename InitialValue, typename T0, typename T1, typename T2, typename T3,
- typename T4, typename T5, typename T6, typename T7, typename T8, typename T9,
+
+ template <typename F, typename InitialValue, typename T0, typename T1, typename T2, typename T3, typename T4,
typename... Types>
+ struct apply<F, InitialValue, T0, T1, T2, T3, T4, Types...> {
+ using type = Fold(
+ F, typename F::template apply<
+ typename DoEval<typename F::template apply<
+ typename DoEval<typename F::template apply<
+ typename DoEval<typename F::template apply<
+ typename DoEval<typename F::template apply<InitialValue, T0>::type>::type, T1>::type>::type,
+ T2>::type>::type,
+ T3>::type>::type,
+ T4>::type,
+ Types...);
+ };
+
+ // Optimized specialization, processing 10 values at a time.
+ template <typename F, typename InitialValue, typename T0, typename T1, typename T2, typename T3, typename T4,
+ typename T5, typename T6, typename T7, typename T8, typename T9, typename... Types>
struct apply<F, InitialValue, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, Types...> {
- using type = Fold(F,
- typename F::template apply<
- typename DoEval<typename F::template apply<
- typename DoEval<typename F::template apply<
- typename DoEval<typename F::template apply<
- typename DoEval<typename F::template apply<
- typename DoEval<typename F::template apply<
- typename DoEval<typename F::template apply<
- typename DoEval<typename F::template apply<
- typename DoEval<typename F::template apply<
- typename DoEval<typename F::template apply<
- InitialValue,
- T0>::type>::type,
- T1>::type>::type,
- T2>::type>::type,
- T3>::type>::type,
- T4>::type>::type,
- T5>::type>::type,
+ using type = Fold(
+ F,
+ typename F::template apply<
+ typename DoEval<typename F::template apply<
+ typename DoEval<typename F::template apply<
+ typename DoEval<typename F::template apply<
+ typename DoEval<typename F::template apply<
+ typename DoEval<typename F::template apply<
+ typename DoEval<typename F::template apply<
+ typename DoEval<typename F::template apply<
+ typename DoEval<typename F::template apply<
+ typename DoEval<typename F::template apply<InitialValue, T0>::type>::type,
+ T1>::type>::type,
+ T2>::type>::type,
+ T3>::type>::type,
+ T4>::type>::type,
+ T5>::type>::type,
T6>::type>::type,
- T7>::type>::type,
- T8>::type>::type,
- T9>::type,
- Types...);
+ T7>::type>::type,
+ T8>::type>::type,
+ T9>::type,
+ Types...);
};
};
@@ -139,5 +121,4 @@
} // namespace impl
} // namespace fruit
-
#endif // FRUIT_META_FOLD_H
diff --git a/include/fruit/impl/meta/graph.h b/include/fruit/impl/meta/graph.h
index 724726f..ca8dece 100644
--- a/include/fruit/impl/meta/graph.h
+++ b/include/fruit/impl/meta/graph.h
@@ -4,9 +4,9 @@
* 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.
@@ -17,9 +17,9 @@
#ifndef FRUIT_META_GRAPH_H
#define FRUIT_META_GRAPH_H
-#include <fruit/impl/meta/set.h>
-#include <fruit/impl/meta/map.h>
#include <fruit/impl/meta/immutable_map.h>
+#include <fruit/impl/meta/map.h>
+#include <fruit/impl/meta/set.h>
#include <fruit/impl/meta/triplet.h>
namespace fruit {
@@ -40,7 +40,7 @@
template <typename G>
struct apply {
using ImmutableG = VectorToImmutableMap(G);
-
+
// DfsVisit(VisitedSet, VisitingSet, Node) does a DFS visit starting at Node and returns a
// Triplet<NewVisitedSet, Loop, IsLoopComplete>, where Loop is the Vector representing the part
// of the loop starting at Node (if any loop was found) or Null otherwise.
@@ -48,7 +48,7 @@
template <typename VisitedSet, typename VisitingSet, typename Node>
struct apply {
using NewVisitingSet = AddToSetUnchecked(VisitingSet, Node);
-
+
struct VisitSingleNeighbor {
// CurrentResult is a Triplet<VisitedSet, Loop, IsLoopComplete> (where IsLoopComplete
// is only meaningful when Loop is not None).
@@ -57,37 +57,35 @@
using type = If(IsNone(typename CurrentResult::Second),
// Go ahead, no loop found yet.
DfsVisit(typename CurrentResult::First, NewVisitingSet, Neighbor),
- // Found a loop in another neighbor of the same node, we don't need to
- // visit this neighbor.
- CurrentResult);
+ // Found a loop in another neighbor of the same node, we don't need to
+ // visit this neighbor.
+ CurrentResult);
};
};
-
+
using NewVisitedSet = AddToSet(VisitedSet, Node);
using Neighbors = GraphFindNeighbors(ImmutableG, Node);
using Result = FoldVector(Neighbors, VisitSingleNeighbor, ConsTriplet(NewVisitedSet, None, Bool<false>));
using type = If(IsNone(Neighbors),
// No neighbors.
ConsTriplet(NewVisitedSet, None, Bool<false>),
- If(IsInSet(Node, VisitingSet),
- // We've just found a loop, since Node is another node that we're currently
- // visiting
- Triplet<VisitedSet, Vector<Node>, Bool<false>>,
- If(IsNone(GetSecond(Result)),
- // No loop found.
- Result,
- // Found a loop
- If(GetThird(Result) /* IsLoopComplete */,
- Result,
- If(VectorEndsWith(GetSecond(Result) /* Loop */, Node),
- // The loop is complete now.
- ConsTriplet(GetFirst(Result), GetSecond(Result), Bool<true>),
- // Loop still not complete, add the current node.
- ConsTriplet(GetFirst(Result), PushFront(GetSecond(Result), Node), Bool<false>))))));
-
+ If(IsInSet(Node, VisitingSet),
+ // We've just found a loop, since Node is another node that we're currently
+ // visiting
+ Triplet<VisitedSet, Vector<Node>, Bool<false>>,
+ If(IsNone(GetSecond(Result)),
+ // No loop found.
+ Result,
+ // Found a loop
+ If(GetThird(Result) /* IsLoopComplete */, Result,
+ If(VectorEndsWith(GetSecond(Result) /* Loop */, Node),
+ // The loop is complete now.
+ ConsTriplet(GetFirst(Result), GetSecond(Result), Bool<true>),
+ // Loop still not complete, add the current node.
+ ConsTriplet(GetFirst(Result), PushFront(GetSecond(Result), Node), Bool<false>))))));
};
};
-
+
struct VisitStartingAtNode {
// CurrentResult is a Pair<CurrentVisitedSet, Loop>
template <typename CurrentResult, typename Node>
@@ -96,11 +94,11 @@
using type = If(IsNone(GetSecond(CurrentResult)),
// No loop found yet.
MakePair(GetFirst(DfsResult), GetSecond(DfsResult)),
- // Found a loop, return early
- CurrentResult);
+ // Found a loop, return early
+ CurrentResult);
};
};
-
+
using type = GetSecond(FoldVector(GetMapKeys(G), VisitStartingAtNode, Pair<EmptySet, None>));
};
};
@@ -109,5 +107,4 @@
} // namespace impl
} // namespace fruit
-
#endif // FRUIT_META_GRAPH_H
diff --git a/include/fruit/impl/meta/immutable_map.h b/include/fruit/impl/meta/immutable_map.h
index 8470b12..898cc6e 100644
--- a/include/fruit/impl/meta/immutable_map.h
+++ b/include/fruit/impl/meta/immutable_map.h
@@ -4,9 +4,9 @@
* 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.
@@ -18,9 +18,9 @@
#define FRUIT_META_IMMUTABLE_MAP_H
#include <fruit/impl/meta/basics.h>
+#include <fruit/impl/meta/immutable_set.h>
#include <fruit/impl/meta/pair.h>
#include <fruit/impl/meta/set.h>
-#include <fruit/impl/meta/immutable_set.h>
namespace fruit {
namespace impl {
@@ -31,7 +31,7 @@
struct VectorsToImmutableMap {
template <typename KeyVector, typename ValueVector>
struct apply;
-
+
template <typename... Keys, typename... Values>
struct apply<Vector<Keys...>, Vector<Values...>> {
using type = ConsImmutableSet<Pair<Keys, Values>...>;
@@ -41,7 +41,7 @@
struct VectorToImmutableMap {
template <typename PairVector>
struct apply;
-
+
template <typename... Pairs>
struct apply<Vector<Pairs...>> {
using type = ConsImmutableSet<Pairs...>;
@@ -60,9 +60,9 @@
struct apply {
template <typename Value>
static Value f(Pair<T, Value>*);
-
+
static None f(void*);
-
+
using type = decltype(f((M*)nullptr));
};
};
@@ -77,7 +77,7 @@
struct GetImmutableMapKeys {
template <typename M>
struct apply;
-
+
template <typename... Pairs>
struct apply<ConsImmutableSet<Pairs...>> {
using type = Vector<typename Pairs::First...>;
diff --git a/include/fruit/impl/meta/immutable_set.h b/include/fruit/impl/meta/immutable_set.h
index 762b183..5e6998a 100644
--- a/include/fruit/impl/meta/immutable_set.h
+++ b/include/fruit/impl/meta/immutable_set.h
@@ -4,9 +4,9 @@
* 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.
@@ -17,9 +17,9 @@
#ifndef FRUIT_META_IMMUTABLE_SET_H
#define FRUIT_META_IMMUTABLE_SET_H
+#include <fruit/impl/fruit_assert.h>
#include <fruit/impl/meta/basics.h>
#include <fruit/impl/meta/vector.h>
-#include <fruit/impl/fruit_assert.h>
namespace fruit {
namespace impl {
@@ -33,7 +33,7 @@
struct VectorToImmutableSet {
template <typename V>
struct apply;
-
+
template <typename... Ts>
struct apply<Vector<Ts...>> {
using type = ConsImmutableSet<Ts...>;
@@ -50,7 +50,7 @@
struct SizeOfImmutableSet {
template <typename IS>
struct apply;
-
+
template <typename... Ts>
struct apply<ConsImmutableSet<Ts...>> {
using type = Int<sizeof...(Ts)>;
diff --git a/include/fruit/impl/meta/list.h b/include/fruit/impl/meta/list.h
index 3b0b828..b0bb695 100644
--- a/include/fruit/impl/meta/list.h
+++ b/include/fruit/impl/meta/list.h
@@ -4,9 +4,9 @@
* 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.
@@ -38,22 +38,20 @@
struct FoldList {
template <typename L, typename F, typename InitialValue>
struct apply;
-
+
template <typename F, typename InitialValue>
struct apply<EmptyList, F, InitialValue> {
using type = InitialValue;
};
-
+
template <typename Head, typename Tail, typename F, typename InitialValue>
struct apply<Cons<Head, Tail>, F, InitialValue> {
using type = FoldList(Tail, F, F(InitialValue, Head));
};
};
-
} // namespace meta
} // namespace impl
} // namespace fruit
-
#endif // FRUIT_META_LIST_H
diff --git a/include/fruit/impl/meta/logical_operations.h b/include/fruit/impl/meta/logical_operations.h
index 7ae437f..e35ebeb 100644
--- a/include/fruit/impl/meta/logical_operations.h
+++ b/include/fruit/impl/meta/logical_operations.h
@@ -4,9 +4,9 @@
* 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.
@@ -27,18 +27,13 @@
struct BoolVector {};
template <bool... bs>
-using StaticAnd = Bool<std::is_same<BoolVector<bs...>,
- BoolVector<(true || bs)...>
- >::value>;
+using StaticAnd = Bool<std::is_same<BoolVector<bs...>, BoolVector<(true || bs)...>>::value>;
template <bool... bs>
-using StaticOr = Bool<!std::is_same<BoolVector<bs...>,
- BoolVector<(false && bs)...>
- >::value>;
+using StaticOr = Bool<!std::is_same<BoolVector<bs...>, BoolVector<(false && bs)...>>::value>;
} // namespace meta
} // namespace impl
} // namespace fruit
-
#endif // FRUIT_META_LOGICAL_OPERATIONS_H
diff --git a/include/fruit/impl/meta/map.h b/include/fruit/impl/meta/map.h
index c6f3b43..6291a59 100644
--- a/include/fruit/impl/meta/map.h
+++ b/include/fruit/impl/meta/map.h
@@ -4,9 +4,9 @@
* 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.
@@ -25,11 +25,10 @@
// A Map is a Set whose elements have the form Pair<Key, Value>
-
struct GetMapKeys {
template <typename M>
struct apply;
-
+
template <typename... Pairs>
struct apply<Vector<Pairs...>> {
using type = Vector<typename Pairs::First...>;
@@ -49,7 +48,7 @@
using type = Bool<true>;
};
};
-
+
template <typename M, typename TToFind>
struct apply {
using type = FoldVector(M, Helper<TToFind>, Bool<false>);
@@ -70,7 +69,7 @@
using type = Value;
};
};
-
+
template <typename M, typename TToFind>
struct apply {
using type = FoldVector(M, Helper<TToFind>, None);
@@ -102,5 +101,4 @@
} // namespace impl
} // namespace fruit
-
#endif // FRUIT_META_MAP_H
diff --git a/include/fruit/impl/meta/metaprogramming.h b/include/fruit/impl/meta/metaprogramming.h
index fa2283f..c6190a0 100644
--- a/include/fruit/impl/meta/metaprogramming.h
+++ b/include/fruit/impl/meta/metaprogramming.h
@@ -4,9 +4,9 @@
* 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.
@@ -54,7 +54,7 @@
struct AddPointer {
template <typename T>
struct apply;
-
+
template <typename T>
struct apply<Type<T>> {
using type = Type<T*>;
@@ -64,7 +64,7 @@
struct IsCallable {
template <typename T>
struct apply;
-
+
template <typename C>
struct apply<Type<C>> {
template <typename C1>
@@ -72,7 +72,7 @@
template <typename>
static Bool<false> test(...);
-
+
using type = decltype(test<C>(nullptr));
};
};
@@ -80,7 +80,7 @@
struct GetCallOperatorSignature {
template <typename T>
struct apply;
-
+
template <typename C>
struct apply<Type<C>> {
using type = Type<decltype(&C::operator())>;
@@ -108,14 +108,14 @@
template <int n, typename T, typename... Ts>
struct apply<Int<n>, T, Ts...> {
- using type = GetNthTypeHelper(Int<n-1>, Ts...);
+ using type = GetNthTypeHelper(Int<n - 1>, Ts...);
};
};
struct GetNthType {
template <typename N, typename V>
struct apply;
-
+
template <typename N, typename... Ts>
struct apply<N, Vector<Ts...>> {
using type = GetNthTypeHelper(N, Ts...);
@@ -127,7 +127,7 @@
struct apply;
template <typename Result, typename Functor, typename... Args>
- struct apply<Type<Result(Functor::*)(Args...)>> {
+ struct apply<Type<Result (Functor::*)(Args...)>> {
using type = Type<Result>;
};
};
@@ -135,7 +135,7 @@
struct FunctorResult {
template <typename F>
struct apply;
-
+
template <typename F>
struct apply<Type<F>> {
using type = FunctorResultHelper(Type<decltype(&F::operator())>);
@@ -147,7 +147,7 @@
struct apply;
template <typename Result, typename LambdaObject, typename... Args>
- struct apply<Type<Result(LambdaObject::*)(Args...) const>> {
+ struct apply<Type<Result (LambdaObject::*)(Args...) const>> {
using type = Type<Result(Args...)>;
};
};
@@ -156,15 +156,13 @@
struct FunctionSignature {
template <typename Function>
struct apply;
-
+
template <typename Function>
struct apply<Type<Function>> {
using CandidateSignature = FunctionSignatureHelper(GetCallOperatorSignature(Type<Function>));
- using type = If(Not(IsCallable(Type<Function>)),
- ConstructError(NotALambdaErrorTag, Type<Function>),
- If(Not(IsConstructible(AddPointer(CandidateSignature), Type<Function>)),
- ConstructError(FunctorUsedAsProviderErrorTag, Type<Function>),
- CandidateSignature));
+ using type = If(Not(IsCallable(Type<Function>)), ConstructError(NotALambdaErrorTag, Type<Function>),
+ If(Not(IsConstructible(AddPointer(CandidateSignature), Type<Function>)),
+ ConstructError(FunctorUsedAsProviderErrorTag, Type<Function>), CandidateSignature));
};
template <typename Result, typename... Args>
@@ -173,7 +171,7 @@
};
template <typename Result, typename... Args>
- struct apply<Type<Result(*)(Args...)>> {
+ struct apply<Type<Result (*)(Args...)>> {
using type = Type<Result(Args...)>;
};
};
@@ -182,5 +180,4 @@
} // namespace impl
} // namespace fruit
-
#endif // FRUIT_META_METAPROGRAMMING_H
diff --git a/include/fruit/impl/meta/numeric_operations.h b/include/fruit/impl/meta/numeric_operations.h
index f21be89..be362c1 100644
--- a/include/fruit/impl/meta/numeric_operations.h
+++ b/include/fruit/impl/meta/numeric_operations.h
@@ -4,9 +4,9 @@
* 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.
@@ -26,7 +26,7 @@
struct Sum {
template <typename... Ints>
struct apply;
-
+
template <int n, int m>
struct apply<Int<n>, Int<m>> {
using type = Int<n + m>;
@@ -54,7 +54,7 @@
struct Minus {
template <typename N, typename M>
struct apply;
-
+
template <int n, int m>
struct apply<Int<n>, Int<m>> {
using type = Int<n - m>;
@@ -64,7 +64,7 @@
struct GreaterThan {
template <typename N, typename M>
struct apply;
-
+
template <int n, int m>
struct apply<Int<n>, Int<m>> {
using type = Bool<(n > m)>;
@@ -75,5 +75,4 @@
} // namespace impl
} // namespace fruit
-
#endif // FRUIT_META_NUMERIC_OPERATIONS_H
diff --git a/include/fruit/impl/meta/pair.h b/include/fruit/impl/meta/pair.h
index 00fd782..10d8a3e 100644
--- a/include/fruit/impl/meta/pair.h
+++ b/include/fruit/impl/meta/pair.h
@@ -4,9 +4,9 @@
* 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.
@@ -54,5 +54,4 @@
} // namespace impl
} // namespace fruit
-
#endif // FRUIT_META_PAIR_H
diff --git a/include/fruit/impl/meta/proof_tree_comparison.h b/include/fruit/impl/meta/proof_tree_comparison.h
index 27e5fdd..a8d1f91 100644
--- a/include/fruit/impl/meta/proof_tree_comparison.h
+++ b/include/fruit/impl/meta/proof_tree_comparison.h
@@ -25,104 +25,101 @@
namespace impl {
namespace meta {
-// Checks whether Proof is entailed by Forest, i.e. whether there is a corresponding Proof1 in Forest with the same thesis
+// Checks whether Proof is entailed by Forest, i.e. whether there is a corresponding Proof1 in Forest with the same
+// thesis
// and with the same hypotheses as Proof (or a subset).
struct IsProofEntailedByForest {
- template <typename ProofTh, typename ProofHps, typename Forest>
- struct apply {
- using ForestHps = FindInMap(Forest, ProofTh);
- using type = If(IsNone(ForestHps),
- Bool<false>,
- IsContained(ForestHps, ProofHps));
- };
+ template <typename ProofTh, typename ProofHps, typename Forest>
+ struct apply {
+ using ForestHps = FindInMap(Forest, ProofTh);
+ using type = If(IsNone(ForestHps), Bool<false>, IsContained(ForestHps, ProofHps));
+ };
};
struct IsForestEntailedByForest {
- template <typename EntailedForest, typename Forest>
- struct apply {
- struct Helper {
- template <typename CurrentResult, typename EntailedProof>
- struct apply;
+ template <typename EntailedForest, typename Forest>
+ struct apply {
+ struct Helper {
+ template <typename CurrentResult, typename EntailedProof>
+ struct apply;
- template <typename CurrentResult, typename EntailedProofTh, typename EntailedProofHps>
- struct apply<CurrentResult, Pair<EntailedProofTh, EntailedProofHps>> {
- using type = And(CurrentResult,
- IsProofEntailedByForest(EntailedProofTh, EntailedProofHps, Forest));
- };
- };
-
- using type = FoldVector(EntailedForest, Helper, Bool<true>);
+ template <typename CurrentResult, typename EntailedProofTh, typename EntailedProofHps>
+ struct apply<CurrentResult, Pair<EntailedProofTh, EntailedProofHps>> {
+ using type = And(CurrentResult, IsProofEntailedByForest(EntailedProofTh, EntailedProofHps, Forest));
+ };
};
+
+ using type = FoldVector(EntailedForest, Helper, Bool<true>);
+ };
};
// Given two proof trees, check if they are equal.
// Only for debugging.
struct IsProofTreeEqualTo {
- template <typename Proof1, typename Proof2>
- struct apply {
- using type = And(IsSame(typename Proof1::First, typename Proof2::First),
- IsSameSet(typename Proof1::Second, typename Proof2::Second));
- };
+ template <typename Proof1, typename Proof2>
+ struct apply {
+ using type = And(IsSame(typename Proof1::First, typename Proof2::First),
+ IsSameSet(typename Proof1::Second, typename Proof2::Second));
+ };
};
// Given two proofs forests, check if they are equal.
// This is not very efficient, consider re-implementing if it will be used often.
// Only for debugging.
struct IsForestEqualTo {
- template <typename Forest1, typename Forest2>
- struct apply {
- using type = And(IsForestEntailedByForest(Forest1, Forest2),
- IsForestEntailedByForest(Forest2, Forest1));
- };
+ template <typename Forest1, typename Forest2>
+ struct apply {
+ using type = And(IsForestEntailedByForest(Forest1, Forest2), IsForestEntailedByForest(Forest2, Forest1));
+ };
};
// Only for debugging, similar to checking IsProofEntailedByForest but gives a detailed error.
// Only for debugging.
struct CheckProofEntailedByForest {
- template <typename ProofTh, typename ProofHps, typename Forest>
- struct apply {
- using ForestHps = FindInMap(Forest, ProofTh);
- using type = If(IsNone(ForestHps),
- ConstructError(ProofNotEntailedByForestBecauseThNotFoundErrorTag, ProofTh, GetMapKeys(Forest)),
- If(IsContained(ForestHps, ProofHps),
- Bool<true>,
- ConstructError(ProofNotEntailedByForestBecauseHpsNotASubsetErrorTag, ForestHps, ProofHps, SetDifference(ForestHps, ProofHps))));
- };
+ template <typename ProofTh, typename ProofHps, typename Forest>
+ struct apply {
+ using ForestHps = FindInMap(Forest, ProofTh);
+ using type = If(IsNone(ForestHps),
+ ConstructError(ProofNotEntailedByForestBecauseThNotFoundErrorTag, ProofTh, GetMapKeys(Forest)),
+ If(IsContained(ForestHps, ProofHps), Bool<true>,
+ ConstructError(ProofNotEntailedByForestBecauseHpsNotASubsetErrorTag, ForestHps, ProofHps,
+ SetDifference(ForestHps, ProofHps))));
+ };
};
// Only for debugging, similar to checking IsProofEntailedByForest but gives a detailed error.
// Only for debugging.
struct CheckForestEntailedByForest {
- template <typename EntailedForest, typename Forest>
- struct apply {
- struct Helper {
- template <typename CurrentResult, typename EntailedProof>
- struct apply;
+ template <typename EntailedForest, typename Forest>
+ struct apply {
+ struct Helper {
+ template <typename CurrentResult, typename EntailedProof>
+ struct apply;
- template <typename CurrentResult, typename EntailedProofTh, typename EntailedProofHps>
- struct apply<CurrentResult, Pair<EntailedProofTh, EntailedProofHps>> {
- using type = PropagateError(CurrentResult,
- CheckProofEntailedByForest(EntailedProofTh, EntailedProofHps, Forest));
- };
- };
-
- using type = FoldVector(EntailedForest, Helper, Bool<true>);
+ template <typename CurrentResult, typename EntailedProofTh, typename EntailedProofHps>
+ struct apply<CurrentResult, Pair<EntailedProofTh, EntailedProofHps>> {
+ using type = PropagateError(CurrentResult,
+ CheckProofEntailedByForest(EntailedProofTh, EntailedProofHps, Forest));
+ };
};
+
+ using type = FoldVector(EntailedForest, Helper, Bool<true>);
+ };
};
// Given two proofs forests, check if they are equal.
// This is not very efficient, consider re-implementing if it will be used often.
// Only for debugging.
struct CheckForestEqualTo {
- template <typename Forest1, typename Forest2>
- struct apply {
- using type = PropagateError(CheckForestEntailedByForest(Forest1, Forest2),
- CheckForestEntailedByForest(Forest2, Forest1));
- };
+ template <typename Forest1, typename Forest2>
+ struct apply {
+ using type = PropagateError(CheckForestEntailedByForest(Forest1, Forest2),
+ CheckForestEntailedByForest(Forest2, Forest1));
+ };
};
} // namespace meta
} // namespace impl
} // namespace fruit
-#endif //FRUIT_PROOF_TREE_COMPARISON_H
+#endif // FRUIT_PROOF_TREE_COMPARISON_H
diff --git a/include/fruit/impl/meta/proof_trees.h b/include/fruit/impl/meta/proof_trees.h
index f04d5f8..ad6795f 100644
--- a/include/fruit/impl/meta/proof_trees.h
+++ b/include/fruit/impl/meta/proof_trees.h
@@ -4,9 +4,9 @@
* 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.
@@ -19,9 +19,9 @@
#include <fruit/impl/fruit_assert.h>
#include <fruit/impl/injection_debug_errors.h>
-#include <fruit/impl/meta/set.h>
-#include <fruit/impl/meta/graph.h>
#include <fruit/impl/meta/errors.h>
+#include <fruit/impl/meta/graph.h>
+#include <fruit/impl/meta/set.h>
namespace fruit {
namespace impl {
@@ -29,14 +29,14 @@
// Given a set of formulas Hps=Set<Hp1, ... Hp(n)> and a formula Th, Pair<Th, Hps> represents the
// following proof tree:
-//
+//
// Hp1 ... Hp(n)
// -------------
// Th
-//
+//
// Hp1, ... Hp(n) must be distinct.
// Formulas are atomic, any type can be used as formula (except None).
-//
+//
// A proof forest is a map (i.e. a Set of Pair(s)) from each Th to the corresponding set of Hps.
// Note that a proof forest doesn't need to have any additional property (for example, a proof tree
// might contain the thesis as hypotheses, or there might be a longer loop e.g A=>B, B=>A.
@@ -77,10 +77,8 @@
#endif // FRUIT_NO_LOOP_CHECK
-
} // namespace meta
} // namespace impl
} // namespace fruit
-
#endif // FRUIT_META_PROOF_TREES_H
diff --git a/include/fruit/impl/meta/set.h b/include/fruit/impl/meta/set.h
index 2769557..7a39d43 100644
--- a/include/fruit/impl/meta/set.h
+++ b/include/fruit/impl/meta/set.h
@@ -4,9 +4,9 @@
* 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.
@@ -17,10 +17,10 @@
#ifndef FRUIT_META_SET_H
#define FRUIT_META_SET_H
-#include <fruit/impl/meta/vector.h>
+#include <fruit/impl/fruit_assert.h>
#include <fruit/impl/meta/immutable_set.h>
#include <fruit/impl/meta/pair.h>
-#include <fruit/impl/fruit_assert.h>
+#include <fruit/impl/meta/vector.h>
namespace fruit {
namespace impl {
@@ -38,14 +38,14 @@
using IsInSet = IsInVector;
-// If S is a set with elements (T1, ..., Tn) this calculates
+// If S is a set with elements (T1, ..., Tn) this calculates
// F(InitialValue, F(T1, F(..., F(Tn) ...))).
// If S is EmptySet this returns InitialValue.
using FoldSet = FoldVector;
-// If S is a set with elements (T1, ..., Tn) this calculates
+// If S is a set with elements (T1, ..., Tn) this calculates
// Combine(F(T1), Combine(F(T2),..., F(Tn) ...)).
-//
+//
// `Combine' must be associative, and CombineIdentity must be an identity value wrt Combine.
// Use this instead of FoldSet when possible, it shares more sub-instances when invoked multiple
// times with similar sets.
@@ -67,9 +67,7 @@
struct AddToSet {
template <typename S, typename T>
struct apply {
- using type = If(IsInSet(T, S),
- S,
- AddToSetUnchecked(S, T));
+ using type = If(IsInSet(T, S), S, AddToSetUnchecked(S, T));
};
};
@@ -83,7 +81,7 @@
using type = And(CurrentResult, IsInSet(T, S2));
};
};
-
+
using type = FoldVector(S1, Helper, Bool<true>);
};
};
@@ -98,7 +96,7 @@
using type = Or(CurrentResult, IsInSet(T, S2));
};
};
-
+
using type = Not(FoldVector(S1, Helper, Bool<false>));
};
};
@@ -126,9 +124,7 @@
struct Helper {
template <typename CurrentResult, typename T>
struct apply {
- using type = If(IsInSet(T, S2),
- CurrentResult,
- AddToSetUnchecked(CurrentResult, T));
+ using type = If(IsInSet(T, S2), CurrentResult, AddToSetUnchecked(CurrentResult, T));
};
};
@@ -142,24 +138,19 @@
struct Helper {
template <typename CurrentResult, typename T>
struct apply {
- using type = If(IsInSet(T, S2),
- AddToSetUnchecked(CurrentResult, T),
- CurrentResult);
+ using type = If(IsInSet(T, S2), AddToSetUnchecked(CurrentResult, T), CurrentResult);
};
};
- using type = If(GreaterThan(SetSize(S1), SetSize(S2)),
- SetIntersection(S2, S1),
- FoldSet(S1, Helper, EmptySet));
+ using type = If(GreaterThan(SetSize(S1), SetSize(S2)), SetIntersection(S2, S1), FoldSet(S1, Helper, EmptySet));
};
};
struct SetUnion {
template <typename S1, typename S2>
struct apply {
- using type = If(GreaterThan(SetSize(S1), SetSize(S2)),
- SetUnion(S2, S1),
- FoldSet(SetDifference(S1, S2), AddToSetUnchecked, S2));
+ using type = If(GreaterThan(SetSize(S1), SetSize(S2)), SetUnion(S2, S1),
+ FoldSet(SetDifference(S1, S2), AddToSetUnchecked, S2));
};
};
@@ -168,8 +159,7 @@
struct IsSameSet {
template <typename S1, typename S2>
struct apply {
- using type = And(IsContained(S1, S2),
- IsContained(S2, S1));
+ using type = And(IsContained(S1, S2), IsContained(S2, S1));
};
};
diff --git a/include/fruit/impl/meta/signatures.h b/include/fruit/impl/meta/signatures.h
index c184679..69e5ac7 100644
--- a/include/fruit/impl/meta/signatures.h
+++ b/include/fruit/impl/meta/signatures.h
@@ -4,9 +4,9 @@
* 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.
@@ -28,7 +28,7 @@
struct ConsSignatureWithVector {
template <typename ReturnType, typename ArgVector>
struct apply;
-
+
template <typename ReturnType, typename... Args>
struct apply<Type<ReturnType>, Vector<Type<Args>...>> {
using type = Type<ReturnType(Args...)>;
@@ -60,7 +60,7 @@
struct apply {
using type = Bool<false>;
};
-
+
template <typename C, typename... Args>
struct apply<Type<C(Args...)>> {
using type = Bool<true>;
@@ -71,5 +71,4 @@
} // namespace impl
} // namespace fruit
-
#endif // FRUIT_META_SIGNATURES_H
diff --git a/include/fruit/impl/meta/triplet.h b/include/fruit/impl/meta/triplet.h
index f51f956..832a8cf 100644
--- a/include/fruit/impl/meta/triplet.h
+++ b/include/fruit/impl/meta/triplet.h
@@ -4,9 +4,9 @@
* 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.
@@ -48,5 +48,4 @@
} // namespace impl
} // namespace fruit
-
#endif // FRUIT_META_TRIPLET_H
diff --git a/include/fruit/impl/meta/vector.h b/include/fruit/impl/meta/vector.h
index 84bd602..a94a21d 100644
--- a/include/fruit/impl/meta/vector.h
+++ b/include/fruit/impl/meta/vector.h
@@ -4,9 +4,9 @@
* 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.
@@ -18,10 +18,10 @@
#define FRUIT_META_VECTOR_H
#include <fruit/impl/meta/basics.h>
-#include <fruit/impl/meta/logical_operations.h>
-#include <fruit/impl/meta/numeric_operations.h>
#include <fruit/impl/meta/eval.h>
#include <fruit/impl/meta/fold.h>
+#include <fruit/impl/meta/logical_operations.h>
+#include <fruit/impl/meta/numeric_operations.h>
#include <functional>
namespace fruit {
@@ -46,7 +46,7 @@
struct GenerateIntSequenceEvenHelper {
template <typename Half>
struct apply;
-
+
template <int... ns>
struct apply<Vector<Int<ns>...>> {
using type = Vector<Int<ns>..., Int<sizeof...(ns) + ns>...>;
@@ -56,7 +56,7 @@
struct GenerateIntSequenceOddHelper {
template <typename Half>
struct apply;
-
+
template <int... ns>
struct apply<Vector<Int<ns>...>> {
using type = Vector<Int<ns>..., Int<sizeof...(ns)>, Int<sizeof...(ns) + 1 + ns>...>;
@@ -66,9 +66,8 @@
struct GenerateIntSequence {
template <typename N>
struct apply {
- using type = If(Bool<(N::value % 2) == 0>,
- GenerateIntSequenceEvenHelper(GenerateIntSequence(Int<N::value/2>)),
- GenerateIntSequenceOddHelper(GenerateIntSequence(Int<N::value/2>)));
+ using type = If(Bool<(N::value % 2) == 0>, GenerateIntSequenceEvenHelper(GenerateIntSequence(Int<N::value / 2>)),
+ GenerateIntSequenceOddHelper(GenerateIntSequence(Int<N::value / 2>)));
};
};
@@ -87,18 +86,17 @@
struct AlwaysFalseBool {
constexpr static bool value = false;
};
-
+
template <bool... bs>
struct BoolVector;
-
+
template <typename T, typename V>
struct apply;
template <typename T, typename... Ts>
struct apply<T, Vector<Ts...>> {
- using type = Bool<!std::is_same<BoolVector<AlwaysFalseBool<Ts>::value...>,
- BoolVector<std::is_same<T, Ts>::value...>
- >::value>;
+ using type = Bool<
+ !std::is_same<BoolVector<AlwaysFalseBool<Ts>::value...>, BoolVector<std::is_same<T, Ts>::value...>>::value>;
};
};
@@ -110,15 +108,14 @@
struct AlwaysTrueBool {
constexpr static bool value = true;
};
-
+
template <bool... bs>
struct BoolVector;
-
+
template <typename... Ts, typename V2>
struct apply<Vector<Ts...>, V2> {
- using type = Bool<std::is_same<BoolVector<AlwaysTrueBool<Ts>::value...>,
- BoolVector<Id<typename IsInVector::template apply<Ts, V2>::type>::value...>
- >::value>;
+ using type = Bool<std::is_same<BoolVector<AlwaysTrueBool<Ts>::value...>,
+ BoolVector<Id<typename IsInVector::template apply<Ts, V2>::type>::value...>>::value>;
};
};
@@ -165,7 +162,7 @@
struct TransformVector {
template <typename V, typename F>
struct apply;
-
+
template <typename... Ts, typename F>
struct apply<Vector<Ts...>, F> {
using type = Vector<Eval<typename F::template apply<Ts>::type>...>;
@@ -177,7 +174,7 @@
struct apply {
using type = T;
};
-
+
template <typename ToReplace, typename NewElem>
struct apply<ToReplace, NewElem, ToReplace> {
using type = NewElem;
@@ -196,7 +193,7 @@
struct FoldVector {
template <typename V, typename F, typename InitialValue>
struct apply;
-
+
template <typename... Ts, typename F, typename InitialValue>
struct apply<Vector<Ts...>, F, InitialValue> {
using type = Fold(F, InitialValue, Ts...);
@@ -216,7 +213,7 @@
struct apply<Vector<Types...>, N, Vector<Indexes...>> {
template <typename... RemainingTypes>
static Vector<RemainingTypes...> f(AlwaysVoidPtr<Indexes>..., RemainingTypes*...);
-
+
using type = decltype(f((Types*)nullptr...));
};
};
@@ -225,10 +222,9 @@
template <typename V, typename T>
struct apply {
using N = Int<Eval<VectorSize(V)>::value - 1>;
- using type = IsSame(VectorRemoveFirstN(V, N),
- Vector<T>);
+ using type = IsSame(VectorRemoveFirstN(V, N), Vector<T>);
};
-
+
template <typename T>
struct apply<Vector<>, T> {
using type = Bool<false>;
@@ -242,12 +238,12 @@
struct apply {
using type = Vector<>;
};
-
+
template <typename T, typename... Ts>
struct apply<Vector<T, Ts...>> {
using type = PushFront(VectorRemoveNone(Vector<Ts...>), T);
};
-
+
template <typename... Ts>
struct apply<Vector<None, Ts...>> {
using type = VectorRemoveNone(Vector<Ts...>);
@@ -257,7 +253,7 @@
struct ConstructErrorWithArgVectorHelper {
template <typename ErrorTag, typename ArgsVector, typename... OtherArgs>
struct apply;
-
+
template <typename ErrorTag, typename... Args, typename... OtherArgs>
struct apply<ErrorTag, Vector<Args...>, OtherArgs...> {
using type = ConstructError(ErrorTag, OtherArgs..., Args...);
@@ -275,5 +271,4 @@
} // namespace impl
} // namespace fruit
-
#endif // FRUIT_META_VECTOR_H
diff --git a/include/fruit/impl/meta/wrappers.h b/include/fruit/impl/meta/wrappers.h
index d4e0b29..53dd05c 100644
--- a/include/fruit/impl/meta/wrappers.h
+++ b/include/fruit/impl/meta/wrappers.h
@@ -4,9 +4,9 @@
* 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.
@@ -28,7 +28,7 @@
struct ConsSignature {
template <typename ReturnType, typename... Args>
struct apply;
-
+
template <typename ReturnType, typename... Args>
struct apply<Type<ReturnType>, Type<Args>...> {
using type = Type<ReturnType(Args...)>;
@@ -38,7 +38,7 @@
struct ConsStdFunction {
template <typename Signature>
struct apply;
-
+
template <typename Signature>
struct apply<Type<Signature>> {
using type = Type<std::function<Signature>>;
@@ -48,7 +48,7 @@
struct ConsUniquePtr {
template <typename T>
struct apply;
-
+
template <typename T>
struct apply<Type<T>> {
using type = Type<std::unique_ptr<T>>;
@@ -82,7 +82,7 @@
struct ConsReference {
template <typename T>
struct apply;
-
+
template <typename T>
struct apply<Type<T>> {
using type = Type<T&>;
@@ -102,7 +102,7 @@
struct IsEmpty {
template <typename T>
struct apply;
-
+
template <typename T>
struct apply<Type<T>> {
using type = Bool<std::is_empty<T>::value>;
@@ -112,10 +112,9 @@
struct IsTriviallyCopyable {
template <typename T>
struct apply;
-
+
template <typename T>
struct apply<Type<T>> {
-
using type = Bool<FRUIT_IS_TRIVIALLY_COPYABLE(T)>;
};
};
@@ -145,7 +144,7 @@
struct IsAbstract {
template <typename T>
struct apply;
-
+
template <typename T>
struct apply<Type<T>> {
using type = Bool<std::is_abstract<T>::value>;
@@ -155,7 +154,7 @@
struct IsBaseOf {
template <typename I, typename C>
struct apply;
-
+
template <typename I, typename C>
struct apply<Type<I>, Type<C>> {
using type = Bool<std::is_base_of<I, C>::value>;
@@ -176,5 +175,4 @@
} // namespace impl
} // namespace fruit
-
#endif // FRUIT_META_WRAPPERS_H
diff --git a/include/fruit/impl/normalized_component.defn.h b/include/fruit/impl/normalized_component.defn.h
index 3d7c639..3aad35f 100644
--- a/include/fruit/impl/normalized_component.defn.h
+++ b/include/fruit/impl/normalized_component.defn.h
@@ -4,9 +4,9 @@
* 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.
@@ -26,29 +26,21 @@
template <typename... Params>
template <typename... FormalArgs, typename... Args>
-inline NormalizedComponent<Params...>::NormalizedComponent(Component<Params...>(*getComponent)(FormalArgs...), Args&&... args)
- : NormalizedComponent(
- std::move(
- fruit::Component<Params...>(
- fruit::createComponent().install(getComponent, std::forward<Args>(args)...))
- .storage),
- fruit::impl::MemoryPool()) {
-}
+inline NormalizedComponent<Params...>::NormalizedComponent(Component<Params...> (*getComponent)(FormalArgs...),
+ Args&&... args)
+ : NormalizedComponent(std::move(fruit::Component<Params...>(
+ fruit::createComponent().install(getComponent, std::forward<Args>(args)...))
+ .storage),
+ fruit::impl::MemoryPool()) {}
template <typename... Params>
-inline NormalizedComponent<Params...>::NormalizedComponent(
- fruit::impl::ComponentStorage&& storage,
- fruit::impl::MemoryPool memory_pool)
- : storage(
- std::move(storage),
- fruit::impl::getTypeIdsForList<
- typename fruit::impl::meta::Eval<fruit::impl::meta::SetToVector(
- typename fruit::impl::meta::Eval<
- fruit::impl::meta::ConstructComponentImpl(fruit::impl::meta::Type<Params>...)
- >::Ps)>>(memory_pool),
- memory_pool,
- fruit::impl::NormalizedComponentStorageHolder::WithUndoableCompression()) {
-}
+inline NormalizedComponent<Params...>::NormalizedComponent(fruit::impl::ComponentStorage&& storage,
+ fruit::impl::MemoryPool memory_pool)
+ : storage(std::move(storage),
+ fruit::impl::getTypeIdsForList<typename fruit::impl::meta::Eval<fruit::impl::meta::SetToVector(
+ typename fruit::impl::meta::Eval<fruit::impl::meta::ConstructComponentImpl(
+ fruit::impl::meta::Type<Params>...)>::Ps)>>(memory_pool),
+ memory_pool, fruit::impl::NormalizedComponentStorageHolder::WithUndoableCompression()) {}
} // namespace fruit
diff --git a/include/fruit/impl/normalized_component_storage/binding_normalization.h b/include/fruit/impl/normalized_component_storage/binding_normalization.h
index 38b05b7..b5d395e 100644
--- a/include/fruit/impl/normalized_component_storage/binding_normalization.h
+++ b/include/fruit/impl/normalized_component_storage/binding_normalization.h
@@ -4,9 +4,9 @@
* 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.
@@ -22,11 +22,11 @@
#error "binding_normalization.h included in non-cpp file."
#endif
-#include <fruit/impl/util/hash_helpers.h>
-#include <fruit/impl/data_structures/fixed_size_allocator.h>
#include <fruit/impl/component_storage/component_storage_entry.h>
-#include <fruit/impl/normalized_component_storage/normalized_component_storage.h>
#include <fruit/impl/data_structures/arena_allocator.h>
+#include <fruit/impl/data_structures/fixed_size_allocator.h>
+#include <fruit/impl/normalized_component_storage/normalized_component_storage.h>
+#include <fruit/impl/util/hash_helpers.h>
namespace fruit {
namespace impl {
@@ -38,7 +38,6 @@
*/
class BindingNormalization {
public:
-
// Stores an element of the form (c_type_id, -> undo_info) for each binding compression that was
// performed.
// These are used to undo binding compression after applying it (if necessary).
@@ -61,8 +60,7 @@
*/
static void normalizeBindingsWithPermanentBindingCompression(
FixedSizeVector<ComponentStorageEntry>&& toplevel_entries,
- FixedSizeAllocator::FixedSizeAllocatorData& fixed_size_allocator_data,
- MemoryPool& memory_pool,
+ FixedSizeAllocator::FixedSizeAllocatorData& fixed_size_allocator_data, MemoryPool& memory_pool,
const std::vector<TypeId, ArenaAllocator<TypeId>>& exposed_types,
std::vector<ComponentStorageEntry, ArenaAllocator<ComponentStorageEntry>>& bindings_vector,
std::unordered_map<TypeId, NormalizedMultibindingSet>& multibindings);
@@ -74,8 +72,7 @@
*/
static void normalizeBindingsWithUndoableBindingCompression(
FixedSizeVector<ComponentStorageEntry>&& toplevel_entries,
- FixedSizeAllocator::FixedSizeAllocatorData& fixed_size_allocator_data,
- MemoryPool& memory_pool,
+ FixedSizeAllocator::FixedSizeAllocatorData& fixed_size_allocator_data, MemoryPool& memory_pool,
MemoryPool& memory_pool_for_fully_expanded_components_maps,
MemoryPool& memory_pool_for_component_replacements_maps,
const std::vector<TypeId, ArenaAllocator<TypeId>>& exposed_types,
@@ -88,15 +85,13 @@
LazyComponentWithArgsReplacementMap& component_with_args_replacements);
static void normalizeBindingsAndAddTo(
- FixedSizeVector<ComponentStorageEntry>&& toplevel_entries,
- MemoryPool& memory_pool,
+ FixedSizeVector<ComponentStorageEntry>&& toplevel_entries, MemoryPool& memory_pool,
const NormalizedComponentStorage& base_normalized_component,
FixedSizeAllocator::FixedSizeAllocatorData& fixed_size_allocator_data,
std::vector<ComponentStorageEntry, ArenaAllocator<ComponentStorageEntry>>& new_bindings_vector,
std::unordered_map<TypeId, NormalizedMultibindingSet>& multibindings);
private:
-
using multibindings_vector_elem_t = std::pair<ComponentStorageEntry, ComponentStorageEntry>;
using multibindings_vector_t = std::vector<multibindings_vector_elem_t, ArenaAllocator<multibindings_vector_elem_t>>;
@@ -117,14 +112,12 @@
* Normalizes the toplevel entries (but doesn't perform binding compression).
*/
template <typename... Functors>
- static void normalizeBindings(
- FixedSizeVector<ComponentStorageEntry>&& toplevel_entries,
- FixedSizeAllocator::FixedSizeAllocatorData& fixed_size_allocator_data,
- MemoryPool& memory_pool,
- MemoryPool& memory_pool_for_fully_expanded_components_maps,
- MemoryPool& memory_pool_for_component_replacements_maps,
- HashMapWithArenaAllocator<TypeId, ComponentStorageEntry>& binding_data_map,
- Functors... functors);
+ static void normalizeBindings(FixedSizeVector<ComponentStorageEntry>&& toplevel_entries,
+ FixedSizeAllocator::FixedSizeAllocatorData& fixed_size_allocator_data,
+ MemoryPool& memory_pool, MemoryPool& memory_pool_for_fully_expanded_components_maps,
+ MemoryPool& memory_pool_for_component_replacements_maps,
+ HashMapWithArenaAllocator<TypeId, ComponentStorageEntry>& binding_data_map,
+ Functors... functors);
struct BindingCompressionInfo {
TypeId i_type_id;
@@ -137,16 +130,12 @@
* with (c_type_id, undo_info) for each binding compression that was applied (and that therefore might need to be
* undone later).
*/
- template <
- typename SaveCompressedBindingUndoInfo,
- typename SaveFullyExpandedComponentsWithNoArgs,
- typename SaveFullyExpandedComponentsWithArgs,
- typename SaveComponentReplacementsWithNoArgs,
- typename SaveComponentReplacementsWithArgs>
+ template <typename SaveCompressedBindingUndoInfo, typename SaveFullyExpandedComponentsWithNoArgs,
+ typename SaveFullyExpandedComponentsWithArgs, typename SaveComponentReplacementsWithNoArgs,
+ typename SaveComponentReplacementsWithArgs>
static void normalizeBindingsWithBindingCompression(
FixedSizeVector<ComponentStorageEntry>&& toplevel_entries,
- FixedSizeAllocator::FixedSizeAllocatorData& fixed_size_allocator_data,
- MemoryPool& memory_pool,
+ FixedSizeAllocator::FixedSizeAllocatorData& fixed_size_allocator_data, MemoryPool& memory_pool,
MemoryPool& memory_pool_for_fully_expanded_components_maps,
MemoryPool& memory_pool_for_component_replacements_maps,
const std::vector<TypeId, ArenaAllocator<TypeId>>& exposed_types,
@@ -167,44 +156,31 @@
* undone later).
*/
template <typename SaveCompressedBindingUndoInfo>
- static std::vector<ComponentStorageEntry, ArenaAllocator<ComponentStorageEntry>> performBindingCompression(
- HashMapWithArenaAllocator<TypeId, ComponentStorageEntry>&& binding_data_map,
- HashMapWithArenaAllocator<TypeId, BindingCompressionInfo>&& compressed_bindings_map,
- MemoryPool& memory_pool,
- const multibindings_vector_t& multibindings_vector,
- const std::vector<TypeId, ArenaAllocator<TypeId>>& exposed_types,
- SaveCompressedBindingUndoInfo save_compressed_binding_undo_info);
+ static std::vector<ComponentStorageEntry, ArenaAllocator<ComponentStorageEntry>>
+ performBindingCompression(HashMapWithArenaAllocator<TypeId, ComponentStorageEntry>&& binding_data_map,
+ HashMapWithArenaAllocator<TypeId, BindingCompressionInfo>&& compressed_bindings_map,
+ MemoryPool& memory_pool, const multibindings_vector_t& multibindings_vector,
+ const std::vector<TypeId, ArenaAllocator<TypeId>>& exposed_types,
+ SaveCompressedBindingUndoInfo save_compressed_binding_undo_info);
- static void handlePreexistingLazyComponentWithArgsReplacement(
- ComponentStorageEntry& replaced_component_entry,
- const ComponentStorageEntry& preexisting_replacement,
- ComponentStorageEntry& new_replacement);
+ static void handlePreexistingLazyComponentWithArgsReplacement(ComponentStorageEntry& replaced_component_entry,
+ const ComponentStorageEntry& preexisting_replacement,
+ ComponentStorageEntry& new_replacement);
- static void handlePreexistingLazyComponentWithNoArgsReplacement(
- ComponentStorageEntry& replaced_component_entry,
- const ComponentStorageEntry& preexisting_replacement,
- ComponentStorageEntry& new_replacement);
+ static void handlePreexistingLazyComponentWithNoArgsReplacement(ComponentStorageEntry& replaced_component_entry,
+ const ComponentStorageEntry& preexisting_replacement,
+ ComponentStorageEntry& new_replacement);
- template <
- typename HandleCompressedBinding,
- typename HandleMultibinding,
- typename FindNormalizedBinding,
- typename IsValidItr,
- typename IsNormalizedBindingItrForConstructedObject,
- typename GetObjectPtr,
- typename GetCreate,
- typename IsComponentWithNoArgsAlreadyExpandedInNormalizedComponent,
- typename IsComponentWithArgsAlreadyExpandedInNormalizedComponent,
- typename SaveFullyExpandedComponentsWithNoArgs,
- typename SaveFullyExpandedComponentsWithArgs,
- typename GetComponentWithNoArgsReplacementInNormalizedComponent,
- typename GetComponentWithArgsReplacementInNormalizedComponent,
- typename IsLazyComponentWithNoArgsIteratorValid,
- typename IsLazyComponentWithArgsIteratorValid,
- typename DereferenceLazyComponentWithNoArgsIterator,
- typename DereferenceLazyComponentWithArgsIterator,
- typename SaveComponentReplacementsWithNoArgs,
- typename SaveComponentReplacementsWithArgs>
+ template <typename HandleCompressedBinding, typename HandleMultibinding, typename FindNormalizedBinding,
+ typename IsValidItr, typename IsNormalizedBindingItrForConstructedObject, typename GetObjectPtr,
+ typename GetCreate, typename IsComponentWithNoArgsAlreadyExpandedInNormalizedComponent,
+ typename IsComponentWithArgsAlreadyExpandedInNormalizedComponent,
+ typename SaveFullyExpandedComponentsWithNoArgs, typename SaveFullyExpandedComponentsWithArgs,
+ typename GetComponentWithNoArgsReplacementInNormalizedComponent,
+ typename GetComponentWithArgsReplacementInNormalizedComponent,
+ typename IsLazyComponentWithNoArgsIteratorValid, typename IsLazyComponentWithArgsIteratorValid,
+ typename DereferenceLazyComponentWithNoArgsIterator, typename DereferenceLazyComponentWithArgsIterator,
+ typename SaveComponentReplacementsWithNoArgs, typename SaveComponentReplacementsWithArgs>
struct BindingNormalizationFunctors {
/**
@@ -253,8 +229,10 @@
*/
GetCreate get_create;
- IsComponentWithNoArgsAlreadyExpandedInNormalizedComponent is_component_with_no_args_already_expanded_in_normalized_component;
- IsComponentWithArgsAlreadyExpandedInNormalizedComponent is_component_with_args_already_expanded_in_normalized_component;
+ IsComponentWithNoArgsAlreadyExpandedInNormalizedComponent
+ is_component_with_no_args_already_expanded_in_normalized_component;
+ IsComponentWithArgsAlreadyExpandedInNormalizedComponent
+ is_component_with_args_already_expanded_in_normalized_component;
SaveFullyExpandedComponentsWithNoArgs save_fully_expanded_components_with_no_args;
SaveFullyExpandedComponentsWithArgs save_fully_expanded_components_with_args;
@@ -262,7 +240,8 @@
* Gets a LazyComponentWithNoArgsIterator pointing to the replacement for the given lazy component in the normalized
* component (if any).
*/
- GetComponentWithNoArgsReplacementInNormalizedComponent get_component_with_no_args_replacement_in_normalized_component;
+ GetComponentWithNoArgsReplacementInNormalizedComponent
+ get_component_with_no_args_replacement_in_normalized_component;
/**
* Gets a LazyComponentWithArgsIterator pointing to the replacement for the given lazy component in the normalized
@@ -298,20 +277,18 @@
// These sets contain the lazy components whose expansion has already completed.
LazyComponentWithNoArgsSet fully_expanded_components_with_no_args =
- NormalizedComponentStorage::createLazyComponentWithNoArgsSet(
- 20 /* capacity */, memory_pool_for_fully_expanded_components_maps);
+ NormalizedComponentStorage::createLazyComponentWithNoArgsSet(20 /* capacity */,
+ memory_pool_for_fully_expanded_components_maps);
LazyComponentWithArgsSet fully_expanded_components_with_args =
- NormalizedComponentStorage::createLazyComponentWithArgsSet(
- 20 /* capacity */, memory_pool_for_fully_expanded_components_maps);
+ NormalizedComponentStorage::createLazyComponentWithArgsSet(20 /* capacity */,
+ memory_pool_for_fully_expanded_components_maps);
// These sets contain the elements with kind *_END_MARKER in entries_to_process.
// For component with args, these sets do *not* own the objects, entries_to_process does.
LazyComponentWithNoArgsSet components_with_no_args_with_expansion_in_progress =
- NormalizedComponentStorage::createLazyComponentWithNoArgsSet(
- 20 /* capacity */, memory_pool);
+ NormalizedComponentStorage::createLazyComponentWithNoArgsSet(20 /* capacity */, memory_pool);
LazyComponentWithArgsSet components_with_args_with_expansion_in_progress =
- NormalizedComponentStorage::createLazyComponentWithArgsSet(
- 20 /* capacity */, memory_pool);
+ NormalizedComponentStorage::createLazyComponentWithArgsSet(20 /* capacity */, memory_pool);
// These sets contain Component replacements, as mappings componentToReplace->replacementComponent.
LazyComponentWithNoArgsReplacementMap component_with_no_args_replacements =
@@ -321,14 +298,12 @@
NormalizedComponentStorage::createLazyComponentWithArgsReplacementMap(
20 /* capacity */, memory_pool_for_component_replacements_maps);
- BindingNormalizationContext(
- FixedSizeVector<ComponentStorageEntry>& toplevel_entries,
- FixedSizeAllocator::FixedSizeAllocatorData& fixed_size_allocator_data,
- MemoryPool& memory_pool,
- MemoryPool& memory_pool_for_fully_expanded_components_maps,
- MemoryPool& memory_pool_for_component_replacements_maps,
- HashMapWithArenaAllocator<TypeId, ComponentStorageEntry>& binding_data_map,
- BindingNormalizationFunctors<Functors...> functors);
+ BindingNormalizationContext(FixedSizeVector<ComponentStorageEntry>& toplevel_entries,
+ FixedSizeAllocator::FixedSizeAllocatorData& fixed_size_allocator_data,
+ MemoryPool& memory_pool, MemoryPool& memory_pool_for_fully_expanded_components_maps,
+ MemoryPool& memory_pool_for_component_replacements_maps,
+ HashMapWithArenaAllocator<TypeId, ComponentStorageEntry>& binding_data_map,
+ BindingNormalizationFunctors<Functors...> functors);
BindingNormalizationContext(const BindingNormalizationContext&) = delete;
BindingNormalizationContext(BindingNormalizationContext&&) = delete;
@@ -340,36 +315,28 @@
};
template <typename... Params>
- static void handleBindingForConstructedObject(
- BindingNormalizationContext<Params...>& context);
+ static void handleBindingForConstructedObject(BindingNormalizationContext<Params...>& context);
template <typename... Params>
- static void handleBindingForObjectToConstructThatNeedsAllocation(
- BindingNormalizationContext<Params...>& context);
+ static void handleBindingForObjectToConstructThatNeedsAllocation(BindingNormalizationContext<Params...>& context);
template <typename... Params>
- static void handleBindingForObjectToConstructThatNeedsNoAllocation(
- BindingNormalizationContext<Params...>& context);
+ static void handleBindingForObjectToConstructThatNeedsNoAllocation(BindingNormalizationContext<Params...>& context);
template <typename... Params>
- static void handleCompressedBinding(
- BindingNormalizationContext<Params...>& context);
+ static void handleCompressedBinding(BindingNormalizationContext<Params...>& context);
template <typename... Params>
- static void handleMultibinding(
- BindingNormalizationContext<Params...>& context);
+ static void handleMultibinding(BindingNormalizationContext<Params...>& context);
template <typename... Params>
- static void handleMultibindingVectorCreator(
- BindingNormalizationContext<Params...>& context);
+ static void handleMultibindingVectorCreator(BindingNormalizationContext<Params...>& context);
template <typename... Params>
- static void handleComponentWithoutArgsEndMarker(
- BindingNormalizationContext<Params...>& context);
+ static void handleComponentWithoutArgsEndMarker(BindingNormalizationContext<Params...>& context);
template <typename... Params>
- static void handleComponentWithArgsEndMarker(
- BindingNormalizationContext<Params...>& context);
+ static void handleComponentWithArgsEndMarker(BindingNormalizationContext<Params...>& context);
template <typename... Params>
static void handleReplacedLazyComponentWithArgs(BindingNormalizationContext<Params...>& context);
@@ -378,27 +345,24 @@
static void handleReplacedLazyComponentWithNoArgs(BindingNormalizationContext<Params...>& context);
template <typename... Params>
- static void handleLazyComponentWithArgs(
- BindingNormalizationContext<Params...>& context);
+ static void handleLazyComponentWithArgs(BindingNormalizationContext<Params...>& context);
template <typename... Params>
- static void handleLazyComponentWithNoArgs(
- BindingNormalizationContext<Params...>& context);
+ static void handleLazyComponentWithNoArgs(BindingNormalizationContext<Params...>& context);
template <typename... Params>
- static void performComponentReplacement(
- BindingNormalizationContext<Params...>& context, const ComponentStorageEntry& replacement);
+ static void performComponentReplacement(BindingNormalizationContext<Params...>& context,
+ const ComponentStorageEntry& replacement);
static void printMultipleBindingsError(TypeId type);
- static void printIncompatibleComponentReplacementsError(
- const ComponentStorageEntry& replaced_component_entry,
- const ComponentStorageEntry& replacement_component_entry1,
- const ComponentStorageEntry& replacement_component_entry2);
+ static void printIncompatibleComponentReplacementsError(const ComponentStorageEntry& replaced_component_entry,
+ const ComponentStorageEntry& replacement_component_entry1,
+ const ComponentStorageEntry& replacement_component_entry2);
- static void printComponentReplacementFailedBecauseTargetAlreadyExpanded(
- const ComponentStorageEntry& replaced_component_entry,
- const ComponentStorageEntry& replacement_component_entry);
+ static void
+ printComponentReplacementFailedBecauseTargetAlreadyExpanded(const ComponentStorageEntry& replaced_component_entry,
+ const ComponentStorageEntry& replacement_component_entry);
};
} // namespace impl
diff --git a/include/fruit/impl/normalized_component_storage/binding_normalization.templates.h b/include/fruit/impl/normalized_component_storage/binding_normalization.templates.h
index 3111e13..85888d7 100644
--- a/include/fruit/impl/normalized_component_storage/binding_normalization.templates.h
+++ b/include/fruit/impl/normalized_component_storage/binding_normalization.templates.h
@@ -4,9 +4,9 @@
* 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.
@@ -23,8 +23,8 @@
#endif
#include <fruit/impl/component_storage/component_storage_entry.h>
-#include <fruit/impl/util/type_info.h>
#include <fruit/impl/normalized_component_storage/binding_normalization.h>
+#include <fruit/impl/util/type_info.h>
using namespace fruit::impl;
@@ -34,20 +34,16 @@
template <typename... Functors>
BindingNormalization::BindingNormalizationContext<Functors...>::BindingNormalizationContext(
FixedSizeVector<ComponentStorageEntry>& toplevel_entries,
- FixedSizeAllocator::FixedSizeAllocatorData& fixed_size_allocator_data,
- MemoryPool& memory_pool,
- MemoryPool& memory_pool_for_fully_expanded_components_maps,
- MemoryPool& memory_pool_for_component_replacements_maps,
+ FixedSizeAllocator::FixedSizeAllocatorData& fixed_size_allocator_data, MemoryPool& memory_pool,
+ MemoryPool& memory_pool_for_fully_expanded_components_maps, MemoryPool& memory_pool_for_component_replacements_maps,
HashMapWithArenaAllocator<TypeId, ComponentStorageEntry>& binding_data_map,
BindingNormalizationFunctors<Functors...> functors)
- : fixed_size_allocator_data(fixed_size_allocator_data),
- memory_pool(memory_pool),
- memory_pool_for_fully_expanded_components_maps(memory_pool_for_fully_expanded_components_maps),
- memory_pool_for_component_replacements_maps(memory_pool_for_component_replacements_maps),
- binding_data_map(binding_data_map),
- functors(functors),
- entries_to_process(
- toplevel_entries.begin(), toplevel_entries.end(), ArenaAllocator<ComponentStorageEntry>(memory_pool)) {
+ : fixed_size_allocator_data(fixed_size_allocator_data), memory_pool(memory_pool),
+ memory_pool_for_fully_expanded_components_maps(memory_pool_for_fully_expanded_components_maps),
+ memory_pool_for_component_replacements_maps(memory_pool_for_component_replacements_maps),
+ binding_data_map(binding_data_map), functors(functors),
+ entries_to_process(toplevel_entries.begin(), toplevel_entries.end(),
+ ArenaAllocator<ComponentStorageEntry>(memory_pool)) {
toplevel_entries.clear();
}
@@ -75,27 +71,21 @@
}
template <typename... Functors>
-void BindingNormalization::normalizeBindings(
- FixedSizeVector<ComponentStorageEntry>&& toplevel_entries,
- FixedSizeAllocator::FixedSizeAllocatorData& fixed_size_allocator_data,
- MemoryPool& memory_pool,
- MemoryPool& memory_pool_for_fully_expanded_components_maps,
- MemoryPool& memory_pool_for_component_replacements_maps,
- HashMapWithArenaAllocator<TypeId, ComponentStorageEntry>& binding_data_map,
- Functors... functors) {
+void BindingNormalization::normalizeBindings(FixedSizeVector<ComponentStorageEntry>&& toplevel_entries,
+ FixedSizeAllocator::FixedSizeAllocatorData& fixed_size_allocator_data,
+ MemoryPool& memory_pool,
+ MemoryPool& memory_pool_for_fully_expanded_components_maps,
+ MemoryPool& memory_pool_for_component_replacements_maps,
+ HashMapWithArenaAllocator<TypeId, ComponentStorageEntry>& binding_data_map,
+ Functors... functors) {
FruitAssert(binding_data_map.empty());
using Context = BindingNormalizationContext<Functors...>;
- Context context(
- toplevel_entries,
- fixed_size_allocator_data,
- memory_pool,
- memory_pool_for_fully_expanded_components_maps,
- memory_pool_for_component_replacements_maps,
- binding_data_map,
- BindingNormalizationFunctors<Functors...>{functors...});
+ Context context(toplevel_entries, fixed_size_allocator_data, memory_pool,
+ memory_pool_for_fully_expanded_components_maps, memory_pool_for_component_replacements_maps,
+ binding_data_map, BindingNormalizationFunctors<Functors...>{functors...});
// When we expand a lazy component, instead of removing it from the stack we change its kind (in entries_to_process)
// to one of the *_END_MARKER kinds. This allows to keep track of the "call stack" for the expansion.
@@ -167,8 +157,8 @@
}
template <typename... Params>
-FRUIT_ALWAYS_INLINE inline void BindingNormalization::handleBindingForConstructedObject(
- BindingNormalizationContext<Params...>& context) {
+FRUIT_ALWAYS_INLINE inline void
+BindingNormalization::handleBindingForConstructedObject(BindingNormalizationContext<Params...>& context) {
ComponentStorageEntry entry = context.entries_to_process.back();
FruitAssert(entry.kind == ComponentStorageEntry::Kind::BINDING_FOR_CONSTRUCTED_OBJECT);
@@ -176,8 +166,8 @@
auto itr = context.functors.find_normalized_binding(entry.type_id);
if (context.functors.is_valid_itr(itr)) {
- if (!context.functors.is_normalized_binding_itr_for_constructed_object(itr)
- || context.functors.get_object_ptr(itr) != entry.binding_for_constructed_object.object_ptr) {
+ if (!context.functors.is_normalized_binding_itr_for_constructed_object(itr) ||
+ context.functors.get_object_ptr(itr) != entry.binding_for_constructed_object.object_ptr) {
printMultipleBindingsError(entry.type_id);
FRUIT_UNREACHABLE; // LCOV_EXCL_LINE
}
@@ -187,16 +177,15 @@
ComponentStorageEntry& entry_in_map = context.binding_data_map[entry.type_id];
if (entry_in_map.type_id.type_info != nullptr) {
- if (entry_in_map.kind != ComponentStorageEntry::Kind::BINDING_FOR_CONSTRUCTED_OBJECT
- || entry.binding_for_constructed_object.object_ptr
- != entry_in_map.binding_for_constructed_object.object_ptr) {
+ if (entry_in_map.kind != ComponentStorageEntry::Kind::BINDING_FOR_CONSTRUCTED_OBJECT ||
+ entry.binding_for_constructed_object.object_ptr != entry_in_map.binding_for_constructed_object.object_ptr) {
printMultipleBindingsError(entry.type_id);
FRUIT_UNREACHABLE; // LCOV_EXCL_LINE
}
- // Otherwise ok, duplicate but consistent binding.
+// Otherwise ok, duplicate but consistent binding.
- // This avoids assertion failures when injecting a non-const pointer and there is a const duplicate binding that
- // appears before the non-const one (so we'd otherwise ignore the non-const one).
+// This avoids assertion failures when injecting a non-const pointer and there is a const duplicate binding that
+// appears before the non-const one (so we'd otherwise ignore the non-const one).
#ifdef FRUIT_EXTRA_DEBUG
entry_in_map.binding_for_constructed_object.is_nonconst |= entry.binding_for_constructed_object.is_nonconst;
#endif
@@ -216,8 +205,8 @@
auto itr = context.functors.find_normalized_binding(entry.type_id);
if (context.functors.is_valid_itr(itr)) {
- if (context.functors.is_normalized_binding_itr_for_constructed_object(itr)
- || context.functors.get_create(itr) != entry.binding_for_object_to_construct.create) {
+ if (context.functors.is_normalized_binding_itr_for_constructed_object(itr) ||
+ context.functors.get_create(itr) != entry.binding_for_object_to_construct.create) {
printMultipleBindingsError(entry.type_id);
FRUIT_UNREACHABLE; // LCOV_EXCL_LINE
}
@@ -228,9 +217,8 @@
ComponentStorageEntry& entry_in_map = context.binding_data_map[entry.type_id];
context.fixed_size_allocator_data.addType(entry.type_id);
if (entry_in_map.type_id.type_info != nullptr) {
- if (entry_in_map.kind != ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_ALLOCATION
- || entry.binding_for_object_to_construct.create
- != entry_in_map.binding_for_object_to_construct.create) {
+ if (entry_in_map.kind != ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_ALLOCATION ||
+ entry.binding_for_object_to_construct.create != entry_in_map.binding_for_object_to_construct.create) {
printMultipleBindingsError(entry.type_id);
FRUIT_UNREACHABLE; // LCOV_EXCL_LINE
}
@@ -251,8 +239,8 @@
auto itr = context.functors.find_normalized_binding(entry.type_id);
if (context.functors.is_valid_itr(itr)) {
- if (context.functors.is_normalized_binding_itr_for_constructed_object(itr)
- || context.functors.get_create(itr) != entry.binding_for_object_to_construct.create) {
+ if (context.functors.is_normalized_binding_itr_for_constructed_object(itr) ||
+ context.functors.get_create(itr) != entry.binding_for_object_to_construct.create) {
printMultipleBindingsError(entry.type_id);
FRUIT_UNREACHABLE; // LCOV_EXCL_LINE
}
@@ -263,9 +251,8 @@
ComponentStorageEntry& entry_in_map = context.binding_data_map[entry.type_id];
context.fixed_size_allocator_data.addExternallyAllocatedType(entry.type_id);
if (entry_in_map.type_id.type_info != nullptr) {
- if (entry_in_map.kind != ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION
- || entry.binding_for_object_to_construct.create
- != entry_in_map.binding_for_object_to_construct.create) {
+ if (entry_in_map.kind != ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION ||
+ entry.binding_for_object_to_construct.create != entry_in_map.binding_for_object_to_construct.create) {
printMultipleBindingsError(entry.type_id);
FRUIT_UNREACHABLE; // LCOV_EXCL_LINE
}
@@ -278,8 +265,8 @@
}
template <typename... Params>
-FRUIT_ALWAYS_INLINE inline void BindingNormalization::handleCompressedBinding(
- BindingNormalizationContext<Params...>& context) {
+FRUIT_ALWAYS_INLINE inline void
+BindingNormalization::handleCompressedBinding(BindingNormalizationContext<Params...>& context) {
ComponentStorageEntry entry = context.entries_to_process.back();
FruitAssert(entry.kind == ComponentStorageEntry::Kind::COMPRESSED_BINDING);
context.entries_to_process.pop_back();
@@ -287,12 +274,11 @@
}
template <typename... Params>
-void BindingNormalization::handleMultibinding(
- BindingNormalizationContext<Params...>& context) {
+void BindingNormalization::handleMultibinding(BindingNormalizationContext<Params...>& context) {
ComponentStorageEntry entry = context.entries_to_process.back();
- FruitAssert(entry.kind == ComponentStorageEntry::Kind::MULTIBINDING_FOR_CONSTRUCTED_OBJECT
- || entry.kind == ComponentStorageEntry::Kind::MULTIBINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_ALLOCATION
- || entry.kind == ComponentStorageEntry::Kind::MULTIBINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION);
+ FruitAssert(entry.kind == ComponentStorageEntry::Kind::MULTIBINDING_FOR_CONSTRUCTED_OBJECT ||
+ entry.kind == ComponentStorageEntry::Kind::MULTIBINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_ALLOCATION ||
+ entry.kind == ComponentStorageEntry::Kind::MULTIBINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION);
context.entries_to_process.pop_back();
FruitAssert(!context.entries_to_process.empty());
ComponentStorageEntry vector_creator_entry = std::move(context.entries_to_process.back());
@@ -302,26 +288,24 @@
}
template <typename... Params>
-void BindingNormalization::handleMultibindingVectorCreator(
- BindingNormalizationContext<Params...>& context) {
+void BindingNormalization::handleMultibindingVectorCreator(BindingNormalizationContext<Params...>& context) {
ComponentStorageEntry entry = context.entries_to_process.back();
FruitAssert(entry.kind == ComponentStorageEntry::Kind::MULTIBINDING_VECTOR_CREATOR);
context.entries_to_process.pop_back();
FruitAssert(!context.entries_to_process.empty());
ComponentStorageEntry multibinding_entry = std::move(context.entries_to_process.back());
context.entries_to_process.pop_back();
- FruitAssert(
- multibinding_entry.kind == ComponentStorageEntry::Kind::MULTIBINDING_FOR_CONSTRUCTED_OBJECT
- || multibinding_entry.kind
- == ComponentStorageEntry::Kind::MULTIBINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_ALLOCATION
- || multibinding_entry.kind
- == ComponentStorageEntry::Kind::MULTIBINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION);
+ FruitAssert(multibinding_entry.kind == ComponentStorageEntry::Kind::MULTIBINDING_FOR_CONSTRUCTED_OBJECT ||
+ multibinding_entry.kind ==
+ ComponentStorageEntry::Kind::MULTIBINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_ALLOCATION ||
+ multibinding_entry.kind ==
+ ComponentStorageEntry::Kind::MULTIBINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION);
context.functors.handle_multibinding(multibinding_entry, entry);
}
template <typename... Params>
-FRUIT_ALWAYS_INLINE inline void BindingNormalization::handleComponentWithoutArgsEndMarker(
- BindingNormalizationContext<Params...>& context) {
+FRUIT_ALWAYS_INLINE inline void
+BindingNormalization::handleComponentWithoutArgsEndMarker(BindingNormalizationContext<Params...>& context) {
ComponentStorageEntry entry = context.entries_to_process.back();
FruitAssert(entry.kind == ComponentStorageEntry::Kind::COMPONENT_WITHOUT_ARGS_END_MARKER);
context.entries_to_process.pop_back();
@@ -333,8 +317,8 @@
}
template <typename... Params>
-FRUIT_ALWAYS_INLINE inline void BindingNormalization::handleComponentWithArgsEndMarker(
- BindingNormalizationContext<Params...>& context) {
+FRUIT_ALWAYS_INLINE inline void
+BindingNormalization::handleComponentWithArgsEndMarker(BindingNormalizationContext<Params...>& context) {
ComponentStorageEntry entry = context.entries_to_process.back();
FruitAssert(entry.kind == ComponentStorageEntry::Kind::COMPONENT_WITH_ARGS_END_MARKER);
context.entries_to_process.pop_back();
@@ -355,13 +339,13 @@
ComponentStorageEntry replacement_component_entry = std::move(context.entries_to_process.back());
context.entries_to_process.pop_back();
- FruitAssert(
- replacement_component_entry.kind == ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_NO_ARGS
- || replacement_component_entry.kind == ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_ARGS);
+ FruitAssert(replacement_component_entry.kind ==
+ ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_NO_ARGS ||
+ replacement_component_entry.kind == ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_ARGS);
- if (context.components_with_args_with_expansion_in_progress.count(entry.lazy_component_with_args) != 0
- || context.fully_expanded_components_with_args.count(entry.lazy_component_with_args) != 0
- || context.functors.is_component_with_args_already_expanded_in_normalized_component(
+ if (context.components_with_args_with_expansion_in_progress.count(entry.lazy_component_with_args) != 0 ||
+ context.fully_expanded_components_with_args.count(entry.lazy_component_with_args) != 0 ||
+ context.functors.is_component_with_args_already_expanded_in_normalized_component(
entry.lazy_component_with_args)) {
printComponentReplacementFailedBecauseTargetAlreadyExpanded(replaced_component_entry, replacement_component_entry);
FRUIT_UNREACHABLE; // LCOV_EXCL_LINE
@@ -381,10 +365,8 @@
ComponentStorageEntry& replacement_component_entry_in_map =
context.component_with_args_replacements[replaced_component_entry.lazy_component_with_args];
if (replacement_component_entry_in_map.type_id.type_info != nullptr) {
- handlePreexistingLazyComponentWithArgsReplacement(
- replaced_component_entry,
- replacement_component_entry_in_map,
- replacement_component_entry);
+ handlePreexistingLazyComponentWithArgsReplacement(replaced_component_entry, replacement_component_entry_in_map,
+ replacement_component_entry);
return;
}
@@ -403,13 +385,13 @@
ComponentStorageEntry replacement_component_entry = std::move(context.entries_to_process.back());
context.entries_to_process.pop_back();
- FruitAssert(
- replacement_component_entry.kind == ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_NO_ARGS
- || replacement_component_entry.kind == ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_ARGS);
+ FruitAssert(replacement_component_entry.kind ==
+ ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_NO_ARGS ||
+ replacement_component_entry.kind == ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_ARGS);
- if (context.components_with_no_args_with_expansion_in_progress.count(entry.lazy_component_with_no_args) != 0
- || context.fully_expanded_components_with_no_args.count(entry.lazy_component_with_no_args) != 0
- || context.functors.is_component_with_no_args_already_expanded_in_normalized_component(
+ if (context.components_with_no_args_with_expansion_in_progress.count(entry.lazy_component_with_no_args) != 0 ||
+ context.fully_expanded_components_with_no_args.count(entry.lazy_component_with_no_args) != 0 ||
+ context.functors.is_component_with_no_args_already_expanded_in_normalized_component(
entry.lazy_component_with_no_args)) {
printComponentReplacementFailedBecauseTargetAlreadyExpanded(replaced_component_entry, replacement_component_entry);
FRUIT_UNREACHABLE; // LCOV_EXCL_LINE
@@ -429,10 +411,8 @@
ComponentStorageEntry& replacement_component_entry_in_map =
context.component_with_no_args_replacements[replaced_component_entry.lazy_component_with_no_args];
if (replacement_component_entry_in_map.type_id.type_info != nullptr) {
- handlePreexistingLazyComponentWithNoArgsReplacement(
- replaced_component_entry,
- replacement_component_entry_in_map,
- replacement_component_entry);
+ handlePreexistingLazyComponentWithNoArgsReplacement(replaced_component_entry, replacement_component_entry_in_map,
+ replacement_component_entry);
return;
}
@@ -442,8 +422,8 @@
}
template <typename... Params>
-void BindingNormalization::performComponentReplacement(
- BindingNormalizationContext<Params...>& context, const ComponentStorageEntry& replacement) {
+void BindingNormalization::performComponentReplacement(BindingNormalizationContext<Params...>& context,
+ const ComponentStorageEntry& replacement) {
// Instead of removing the entry from context.entries_to_process, we just replace it with the new component entry.
@@ -468,12 +448,12 @@
}
template <typename... Params>
-FRUIT_ALWAYS_INLINE inline void BindingNormalization::handleLazyComponentWithArgs(
- BindingNormalizationContext<Params...>& context) {
+FRUIT_ALWAYS_INLINE inline void
+BindingNormalization::handleLazyComponentWithArgs(BindingNormalizationContext<Params...>& context) {
ComponentStorageEntry entry = context.entries_to_process.back();
FruitAssert(entry.kind == ComponentStorageEntry::Kind::LAZY_COMPONENT_WITH_ARGS);
- if (context.fully_expanded_components_with_args.count(entry.lazy_component_with_args)
- || context.functors.is_component_with_args_already_expanded_in_normalized_component(
+ if (context.fully_expanded_components_with_args.count(entry.lazy_component_with_args) ||
+ context.functors.is_component_with_args_already_expanded_in_normalized_component(
entry.lazy_component_with_args)) {
// This lazy component was already inserted, skip it.
entry.lazy_component_with_args.destroy();
@@ -520,13 +500,13 @@
}
template <typename... Params>
-FRUIT_ALWAYS_INLINE inline void BindingNormalization::handleLazyComponentWithNoArgs(
- BindingNormalizationContext<Params...>& context) {
+FRUIT_ALWAYS_INLINE inline void
+BindingNormalization::handleLazyComponentWithNoArgs(BindingNormalizationContext<Params...>& context) {
ComponentStorageEntry entry = context.entries_to_process.back();
FruitAssert(entry.kind == ComponentStorageEntry::Kind::LAZY_COMPONENT_WITH_NO_ARGS);
- if (context.fully_expanded_components_with_no_args.count(entry.lazy_component_with_no_args)
- || context.functors.is_component_with_no_args_already_expanded_in_normalized_component(
+ if (context.fully_expanded_components_with_no_args.count(entry.lazy_component_with_no_args) ||
+ context.functors.is_component_with_no_args_already_expanded_in_normalized_component(
entry.lazy_component_with_no_args)) {
// This lazy component was already inserted, skip it.
context.entries_to_process.pop_back();
@@ -534,8 +514,10 @@
}
auto replacement_component_in_normalized_component_itr =
- context.functors.get_component_with_no_args_replacement_in_normalized_component(entry.lazy_component_with_no_args);
- if (context.functors.is_lazy_component_with_no_args_iterator_valid(replacement_component_in_normalized_component_itr)) {
+ context.functors.get_component_with_no_args_replacement_in_normalized_component(
+ entry.lazy_component_with_no_args);
+ if (context.functors.is_lazy_component_with_no_args_iterator_valid(
+ replacement_component_in_normalized_component_itr)) {
performComponentReplacement(context,
context.functors.dereference_lazy_component_with_no_args_iterator(
replacement_component_in_normalized_component_itr));
@@ -570,10 +552,10 @@
}
template <typename SaveCompressedBindingUndoInfo>
-std::vector<ComponentStorageEntry, ArenaAllocator<ComponentStorageEntry>> BindingNormalization::performBindingCompression(
+std::vector<ComponentStorageEntry, ArenaAllocator<ComponentStorageEntry>>
+BindingNormalization::performBindingCompression(
HashMapWithArenaAllocator<TypeId, ComponentStorageEntry>&& binding_data_map,
- HashMapWithArenaAllocator<TypeId, BindingCompressionInfo>&& compressed_bindings_map,
- MemoryPool& memory_pool,
+ HashMapWithArenaAllocator<TypeId, BindingCompressionInfo>&& compressed_bindings_map, MemoryPool& memory_pool,
const multibindings_vector_t& multibindings_vector,
const std::vector<TypeId, ArenaAllocator<TypeId>>& exposed_types,
SaveCompressedBindingUndoInfo save_compressed_binding_undo_info) {
@@ -583,16 +565,18 @@
// We can't compress the binding if C is a dep of a multibinding.
for (const std::pair<ComponentStorageEntry, ComponentStorageEntry>& multibinding_entry_pair : multibindings_vector) {
const ComponentStorageEntry& entry = multibinding_entry_pair.first;
- FruitAssert(entry.kind == ComponentStorageEntry::Kind::MULTIBINDING_FOR_CONSTRUCTED_OBJECT
- || entry.kind == ComponentStorageEntry::Kind::MULTIBINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_ALLOCATION
- || entry.kind == ComponentStorageEntry::Kind::MULTIBINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION);
+ FruitAssert(entry.kind == ComponentStorageEntry::Kind::MULTIBINDING_FOR_CONSTRUCTED_OBJECT ||
+ entry.kind == ComponentStorageEntry::Kind::MULTIBINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_ALLOCATION ||
+ entry.kind ==
+ ComponentStorageEntry::Kind::MULTIBINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION);
if (entry.kind != ComponentStorageEntry::Kind::MULTIBINDING_FOR_CONSTRUCTED_OBJECT) {
const BindingDeps* deps = entry.multibinding_for_object_to_construct.deps;
FruitAssert(deps != nullptr);
for (std::size_t i = 0; i < deps->num_deps; ++i) {
compressed_bindings_map.erase(deps->deps[i]);
#ifdef FRUIT_EXTRA_DEBUG
- std::cout << "InjectorStorage: ignoring compressed binding for " << deps->deps[i] << " because it's a dep of a multibinding." << std::endl;
+ std::cout << "InjectorStorage: ignoring compressed binding for " << deps->deps[i]
+ << " because it's a dep of a multibinding." << std::endl;
#endif
}
}
@@ -602,7 +586,8 @@
for (TypeId type : exposed_types) {
compressed_bindings_map.erase(type);
#ifdef FRUIT_EXTRA_DEBUG
- std::cout << "InjectorStorage: ignoring compressed binding for " << type << " because it's an exposed type." << std::endl;
+ std::cout << "InjectorStorage: ignoring compressed binding for " << type << " because it's an exposed type."
+ << std::endl;
#endif
}
@@ -610,9 +595,9 @@
for (auto& binding_data_map_entry : binding_data_map) {
TypeId x_id = binding_data_map_entry.first;
ComponentStorageEntry entry = binding_data_map_entry.second;
- FruitAssert(entry.kind == ComponentStorageEntry::Kind::BINDING_FOR_CONSTRUCTED_OBJECT
- || entry.kind == ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_ALLOCATION
- || entry.kind == ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION);
+ FruitAssert(entry.kind == ComponentStorageEntry::Kind::BINDING_FOR_CONSTRUCTED_OBJECT ||
+ entry.kind == ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_ALLOCATION ||
+ entry.kind == ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION);
if (entry.kind != ComponentStorageEntry::Kind::BINDING_FOR_CONSTRUCTED_OBJECT) {
for (std::size_t i = 0; i < entry.binding_for_object_to_construct.deps->num_deps; ++i) {
@@ -621,14 +606,16 @@
if (itr != compressed_bindings_map.end() && itr->second.i_type_id != x_id) {
compressed_bindings_map.erase(itr);
#ifdef FRUIT_EXTRA_DEBUG
- std::cout << "InjectorStorage: ignoring compressed binding for " << c_id << " because the type " << x_id << " depends on it." << std::endl;
+ std::cout << "InjectorStorage: ignoring compressed binding for " << c_id << " because the type " << x_id
+ << " depends on it." << std::endl;
#endif
}
}
}
}
- // Two pairs of compressible bindings (I->C) and (C->X) can not exist (the C of a compressible binding is always bound either
+ // Two pairs of compressible bindings (I->C) and (C->X) can not exist (the C of a compressible binding is always bound
+ // either
// using constructor binding or provider binding, it can't be a binding itself). So no need to check for that.
// Now perform the binding compression.
@@ -641,11 +628,13 @@
FruitAssert(c_binding_data != binding_data_map.end());
NormalizedComponentStorage::CompressedBindingUndoInfo undo_info;
undo_info.i_type_id = i_id;
- FruitAssert(i_binding_data->second.kind == ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION);
+ FruitAssert(i_binding_data->second.kind ==
+ ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION);
undo_info.i_binding = i_binding_data->second.binding_for_object_to_construct;
- FruitAssert(
- c_binding_data->second.kind == ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION
- || c_binding_data->second.kind == ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_ALLOCATION);
+ FruitAssert(c_binding_data->second.kind ==
+ ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION ||
+ c_binding_data->second.kind ==
+ ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_ALLOCATION);
undo_info.c_binding = c_binding_data->second.binding_for_object_to_construct;
save_compressed_binding_undo_info(c_id, undo_info);
@@ -675,18 +664,13 @@
return result;
}
-template <
- typename SaveCompressedBindingUndoInfo,
- typename SaveFullyExpandedComponentsWithNoArgs,
- typename SaveFullyExpandedComponentsWithArgs,
- typename SaveComponentReplacementsWithNoArgs,
- typename SaveComponentReplacementsWithArgs>
+template <typename SaveCompressedBindingUndoInfo, typename SaveFullyExpandedComponentsWithNoArgs,
+ typename SaveFullyExpandedComponentsWithArgs, typename SaveComponentReplacementsWithNoArgs,
+ typename SaveComponentReplacementsWithArgs>
void BindingNormalization::normalizeBindingsWithBindingCompression(
FixedSizeVector<ComponentStorageEntry>&& toplevel_entries,
- FixedSizeAllocator::FixedSizeAllocatorData& fixed_size_allocator_data,
- MemoryPool& memory_pool,
- MemoryPool& memory_pool_for_fully_expanded_components_maps,
- MemoryPool& memory_pool_for_component_replacements_maps,
+ FixedSizeAllocator::FixedSizeAllocatorData& fixed_size_allocator_data, MemoryPool& memory_pool,
+ MemoryPool& memory_pool_for_fully_expanded_components_maps, MemoryPool& memory_pool_for_component_replacements_maps,
const std::vector<TypeId, ArenaAllocator<TypeId>>& exposed_types,
std::vector<ComponentStorageEntry, ArenaAllocator<ComponentStorageEntry>>& bindings_vector,
std::unordered_map<TypeId, NormalizedMultibindingSet>& multibindings,
@@ -697,12 +681,10 @@
SaveComponentReplacementsWithArgs save_component_replacements_with_args) {
HashMapWithArenaAllocator<TypeId, ComponentStorageEntry> binding_data_map =
- createHashMapWithArenaAllocator<TypeId, ComponentStorageEntry>(
- 20 /* capacity */, memory_pool);
+ createHashMapWithArenaAllocator<TypeId, ComponentStorageEntry>(20 /* capacity */, memory_pool);
// CtypeId -> (ItypeId, bindingData)
HashMapWithArenaAllocator<TypeId, BindingNormalization::BindingCompressionInfo> compressed_bindings_map =
- createHashMapWithArenaAllocator<TypeId, BindingCompressionInfo>(
- 20 /* capacity */, memory_pool);
+ createHashMapWithArenaAllocator<TypeId, BindingCompressionInfo>(20 /* capacity */, memory_pool);
multibindings_vector_t multibindings_vector =
multibindings_vector_t(ArenaAllocator<multibindings_vector_elem_t>(memory_pool));
@@ -710,55 +692,33 @@
struct DummyIterator {};
normalizeBindings(
- std::move(toplevel_entries),
- fixed_size_allocator_data,
- memory_pool,
- memory_pool_for_fully_expanded_components_maps,
- memory_pool_for_component_replacements_maps,
- binding_data_map,
+ std::move(toplevel_entries), fixed_size_allocator_data, memory_pool,
+ memory_pool_for_fully_expanded_components_maps, memory_pool_for_component_replacements_maps, binding_data_map,
[&compressed_bindings_map](ComponentStorageEntry entry) {
BindingCompressionInfo& compression_info = compressed_bindings_map[entry.compressed_binding.c_type_id];
compression_info.i_type_id = entry.type_id;
compression_info.create_i_with_compression = entry.compressed_binding.create;
},
- [&multibindings_vector](ComponentStorageEntry multibinding,
- ComponentStorageEntry multibinding_vector_creator) {
+ [&multibindings_vector](ComponentStorageEntry multibinding, ComponentStorageEntry multibinding_vector_creator) {
multibindings_vector.emplace_back(multibinding, multibinding_vector_creator);
},
- [](TypeId) { return DummyIterator(); },
- [](DummyIterator) { return false; },
- [](DummyIterator) { return false; },
- [](DummyIterator) { return nullptr; },
- [](DummyIterator) { return nullptr; },
- [](const LazyComponentWithNoArgs&) { return false; },
- [](const LazyComponentWithArgs&) { return false; },
- save_fully_expanded_components_with_no_args,
- save_fully_expanded_components_with_args,
- [](const LazyComponentWithNoArgs&) { return (ComponentStorageEntry*) nullptr; },
- [](const LazyComponentWithArgs&) { return (ComponentStorageEntry*) nullptr; },
- [](ComponentStorageEntry*) { return false; },
- [](ComponentStorageEntry*) { return false; },
- [](ComponentStorageEntry* p) { return *p; },
- [](ComponentStorageEntry* p) { return *p; },
- save_component_replacements_with_no_args,
- save_component_replacements_with_args);
+ [](TypeId) { return DummyIterator(); }, [](DummyIterator) { return false; }, [](DummyIterator) { return false; },
+ [](DummyIterator) { return nullptr; }, [](DummyIterator) { return nullptr; },
+ [](const LazyComponentWithNoArgs&) { return false; }, [](const LazyComponentWithArgs&) { return false; },
+ save_fully_expanded_components_with_no_args, save_fully_expanded_components_with_args,
+ [](const LazyComponentWithNoArgs&) { return (ComponentStorageEntry*)nullptr; },
+ [](const LazyComponentWithArgs&) { return (ComponentStorageEntry*)nullptr; },
+ [](ComponentStorageEntry*) { return false; }, [](ComponentStorageEntry*) { return false; },
+ [](ComponentStorageEntry* p) { return *p; }, [](ComponentStorageEntry* p) { return *p; },
+ save_component_replacements_with_no_args, save_component_replacements_with_args);
- bindings_vector =
- BindingNormalization::performBindingCompression(
- std::move(binding_data_map),
- std::move(compressed_bindings_map),
- memory_pool,
- multibindings_vector,
- exposed_types,
- save_compressed_binding_undo_info);
+ bindings_vector = BindingNormalization::performBindingCompression(
+ std::move(binding_data_map), std::move(compressed_bindings_map), memory_pool, multibindings_vector, exposed_types,
+ save_compressed_binding_undo_info);
- addMultibindings(
- multibindings,
- fixed_size_allocator_data,
- multibindings_vector);
+ addMultibindings(multibindings, fixed_size_allocator_data, multibindings_vector);
}
-
} // namespace impl
} // namespace fruit
diff --git a/include/fruit/impl/normalized_component_storage/normalized_bindings.defn.h b/include/fruit/impl/normalized_component_storage/normalized_bindings.defn.h
index 62d4a7f..07022c5 100644
--- a/include/fruit/impl/normalized_component_storage/normalized_bindings.defn.h
+++ b/include/fruit/impl/normalized_component_storage/normalized_bindings.defn.h
@@ -4,9 +4,9 @@
* 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.
@@ -42,7 +42,7 @@
default:
#ifdef FRUIT_EXTRA_DEBUG
- std::cerr << "Unexpected kind: " << (std::size_t)entry.kind << std::endl;
+ std::cerr << "Unexpected kind: " << (std::size_t)entry.kind << std::endl;
#endif
FRUIT_UNREACHABLE; // LCOV_EXCL_LINE
}
diff --git a/include/fruit/impl/normalized_component_storage/normalized_bindings.h b/include/fruit/impl/normalized_component_storage/normalized_bindings.h
index 228b91e..cf7876a 100644
--- a/include/fruit/impl/normalized_component_storage/normalized_bindings.h
+++ b/include/fruit/impl/normalized_component_storage/normalized_bindings.h
@@ -4,9 +4,9 @@
* 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.
diff --git a/include/fruit/impl/normalized_component_storage/normalized_component_storage.defn.h b/include/fruit/impl/normalized_component_storage/normalized_component_storage.defn.h
index d67af7a..a0442cf 100644
--- a/include/fruit/impl/normalized_component_storage/normalized_component_storage.defn.h
+++ b/include/fruit/impl/normalized_component_storage/normalized_component_storage.defn.h
@@ -4,9 +4,9 @@
* 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.
@@ -22,41 +22,31 @@
namespace fruit {
namespace impl {
-inline NormalizedComponentStorage::LazyComponentWithNoArgsSet NormalizedComponentStorage::createLazyComponentWithNoArgsSet(
- size_t capacity, MemoryPool& memory_pool) {
+inline NormalizedComponentStorage::LazyComponentWithNoArgsSet
+NormalizedComponentStorage::createLazyComponentWithNoArgsSet(size_t capacity, MemoryPool& memory_pool) {
return createHashSetWithArenaAllocatorAndCustomFunctors<LazyComponentWithNoArgs>(
- capacity,
- memory_pool,
- NormalizedComponentStorage::HashLazyComponentWithNoArgs(),
+ capacity, memory_pool, NormalizedComponentStorage::HashLazyComponentWithNoArgs(),
std::equal_to<LazyComponentWithNoArgs>());
}
-inline NormalizedComponentStorage::LazyComponentWithArgsSet NormalizedComponentStorage::createLazyComponentWithArgsSet(
- size_t capacity, MemoryPool& memory_pool) {
+inline NormalizedComponentStorage::LazyComponentWithArgsSet
+NormalizedComponentStorage::createLazyComponentWithArgsSet(size_t capacity, MemoryPool& memory_pool) {
return createHashSetWithArenaAllocatorAndCustomFunctors<LazyComponentWithArgs>(
- capacity,
- memory_pool,
- NormalizedComponentStorage::HashLazyComponentWithArgs(),
+ capacity, memory_pool, NormalizedComponentStorage::HashLazyComponentWithArgs(),
NormalizedComponentStorage::LazyComponentWithArgsEqualTo());
}
inline NormalizedComponentStorage::LazyComponentWithNoArgsReplacementMap
- NormalizedComponentStorage::createLazyComponentWithNoArgsReplacementMap(
- size_t capacity, MemoryPool& memory_pool) {
+NormalizedComponentStorage::createLazyComponentWithNoArgsReplacementMap(size_t capacity, MemoryPool& memory_pool) {
return createHashMapWithArenaAllocatorAndCustomFunctors<LazyComponentWithNoArgs, ComponentStorageEntry>(
- capacity,
- memory_pool,
- NormalizedComponentStorage::HashLazyComponentWithNoArgs(),
+ capacity, memory_pool, NormalizedComponentStorage::HashLazyComponentWithNoArgs(),
std::equal_to<LazyComponentWithNoArgs>());
}
inline NormalizedComponentStorage::LazyComponentWithArgsReplacementMap
- NormalizedComponentStorage::createLazyComponentWithArgsReplacementMap(
- size_t capacity, MemoryPool& memory_pool) {
+NormalizedComponentStorage::createLazyComponentWithArgsReplacementMap(size_t capacity, MemoryPool& memory_pool) {
return createHashMapWithArenaAllocatorAndCustomFunctors<LazyComponentWithArgs, ComponentStorageEntry>(
- capacity,
- memory_pool,
- NormalizedComponentStorage::HashLazyComponentWithArgs(),
+ capacity, memory_pool, NormalizedComponentStorage::HashLazyComponentWithArgs(),
NormalizedComponentStorage::LazyComponentWithArgsEqualTo());
}
diff --git a/include/fruit/impl/normalized_component_storage/normalized_component_storage.h b/include/fruit/impl/normalized_component_storage/normalized_component_storage.h
index caa0e32..d580b59 100644
--- a/include/fruit/impl/normalized_component_storage/normalized_component_storage.h
+++ b/include/fruit/impl/normalized_component_storage/normalized_component_storage.h
@@ -4,9 +4,9 @@
* 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.
@@ -22,14 +22,14 @@
#error "normalized_component_storage.h included in non-cpp file."
#endif
-#include <fruit/impl/util/type_info.h>
-#include <fruit/impl/util/hash_helpers.h>
-#include <fruit/impl/data_structures/semistatic_map.h>
-#include <fruit/impl/data_structures/semistatic_graph.h>
-#include <fruit/impl/data_structures/fixed_size_allocator.h>
-#include <fruit/impl/fruit_internal_forward_decls.h>
#include <fruit/impl/component_storage/component_storage_entry.h>
+#include <fruit/impl/data_structures/fixed_size_allocator.h>
+#include <fruit/impl/data_structures/semistatic_graph.h>
+#include <fruit/impl/data_structures/semistatic_map.h>
+#include <fruit/impl/fruit_internal_forward_decls.h>
#include <fruit/impl/normalized_component_storage/normalized_bindings.h>
+#include <fruit/impl/util/hash_helpers.h>
+#include <fruit/impl/util/type_info.h>
#include <memory>
#include <unordered_map>
@@ -76,21 +76,27 @@
}
};
- using LazyComponentWithNoArgsSet =
- HashSetWithArenaAllocator<LazyComponentWithNoArgs, HashLazyComponentWithNoArgs, std::equal_to<LazyComponentWithNoArgs>>;
+ using LazyComponentWithNoArgsSet = HashSetWithArenaAllocator<LazyComponentWithNoArgs, HashLazyComponentWithNoArgs,
+ std::equal_to<LazyComponentWithNoArgs>>;
using LazyComponentWithArgsSet =
HashSetWithArenaAllocator<LazyComponentWithArgs, HashLazyComponentWithArgs, LazyComponentWithArgsEqualTo>;
using LazyComponentWithNoArgsReplacementMap =
- HashMapWithArenaAllocator<LazyComponentWithNoArgs, ComponentStorageEntry, NormalizedComponentStorage::HashLazyComponentWithNoArgs, std::equal_to<LazyComponentWithNoArgs>>;
+ HashMapWithArenaAllocator<LazyComponentWithNoArgs, ComponentStorageEntry,
+ NormalizedComponentStorage::HashLazyComponentWithNoArgs,
+ std::equal_to<LazyComponentWithNoArgs>>;
using LazyComponentWithArgsReplacementMap =
- HashMapWithArenaAllocator<LazyComponentWithArgs, ComponentStorageEntry, NormalizedComponentStorage::HashLazyComponentWithArgs, NormalizedComponentStorage::LazyComponentWithArgsEqualTo>;
+ HashMapWithArenaAllocator<LazyComponentWithArgs, ComponentStorageEntry,
+ NormalizedComponentStorage::HashLazyComponentWithArgs,
+ NormalizedComponentStorage::LazyComponentWithArgsEqualTo>;
static LazyComponentWithNoArgsSet createLazyComponentWithNoArgsSet(size_t capacity, MemoryPool& memory_pool);
static LazyComponentWithArgsSet createLazyComponentWithArgsSet(size_t capacity, MemoryPool& memory_pool);
- static LazyComponentWithNoArgsReplacementMap createLazyComponentWithNoArgsReplacementMap(size_t capacity, MemoryPool& memory_pool);
- static LazyComponentWithArgsReplacementMap createLazyComponentWithArgsReplacementMap(size_t capacity, MemoryPool& memory_pool);
+ static LazyComponentWithNoArgsReplacementMap createLazyComponentWithNoArgsReplacementMap(size_t capacity,
+ MemoryPool& memory_pool);
+ static LazyComponentWithArgsReplacementMap createLazyComponentWithArgsReplacementMap(size_t capacity,
+ MemoryPool& memory_pool);
private:
// A graph with types as nodes (each node stores the BindingData for the type) and dependencies as edges.
@@ -99,7 +105,7 @@
// Maps the type index of a type T to the corresponding NormalizedMultibindingSet.
std::unordered_map<TypeId, NormalizedMultibindingSet> multibindings;
-
+
// Contains data on the set of types that can be allocated using this component.
FixedSizeAllocator::FixedSizeAllocatorData fixed_size_allocator_data;
@@ -116,7 +122,7 @@
LazyComponentWithNoArgsReplacementMap component_with_no_args_replacements;
LazyComponentWithArgsReplacementMap component_with_args_replacements;
-
+
friend class InjectorStorage;
friend class BindingNormalization;
@@ -138,21 +144,16 @@
/**
* The MemoryPool is only used during construction, the constructed object *can* outlive the memory pool.
*/
- NormalizedComponentStorage(
- ComponentStorage&& component,
- const std::vector<TypeId, ArenaAllocator<TypeId>>& exposed_types,
- MemoryPool& memory_pool,
- WithUndoableCompression);
+ NormalizedComponentStorage(ComponentStorage&& component,
+ const std::vector<TypeId, ArenaAllocator<TypeId>>& exposed_types, MemoryPool& memory_pool,
+ WithUndoableCompression);
/**
* The MemoryPool is only used during construction, the constructed object *can* outlive the memory pool.
*/
- NormalizedComponentStorage(
- ComponentStorage&& component,
- const std::vector<TypeId, ArenaAllocator<TypeId>>& exposed_types,
- MemoryPool& memory_pool,
- WithPermanentCompression);
-
+ NormalizedComponentStorage(ComponentStorage&& component,
+ const std::vector<TypeId, ArenaAllocator<TypeId>>& exposed_types, MemoryPool& memory_pool,
+ WithPermanentCompression);
// We don't use the default destructor because that will require the inclusion of
// the Boost's hashmap header. We define this in the cpp file instead.
diff --git a/include/fruit/impl/normalized_component_storage/normalized_component_storage_holder.h b/include/fruit/impl/normalized_component_storage/normalized_component_storage_holder.h
index 1176f99..6b1b7e9 100644
--- a/include/fruit/impl/normalized_component_storage/normalized_component_storage_holder.h
+++ b/include/fruit/impl/normalized_component_storage/normalized_component_storage_holder.h
@@ -4,9 +4,9 @@
* 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.
@@ -17,11 +17,11 @@
#ifndef FRUIT_NORMALIZED_COMPONENT_STORAGE_HOLDER_H
#define FRUIT_NORMALIZED_COMPONENT_STORAGE_HOLDER_H
-#include <memory>
-#include <fruit/impl/fruit_internal_forward_decls.h>
#include <fruit/fruit_forward_decls.h>
-#include <fruit/impl/data_structures/memory_pool.h>
#include <fruit/impl/data_structures/arena_allocator.h>
+#include <fruit/impl/data_structures/memory_pool.h>
+#include <fruit/impl/fruit_internal_forward_decls.h>
+#include <memory>
namespace fruit {
namespace impl {
@@ -34,34 +34,32 @@
class NormalizedComponentStorageHolder {
private:
std::unique_ptr<NormalizedComponentStorage> storage;
-
+
friend class InjectorStorage;
-
+
template <typename... P>
friend class fruit::Injector;
-
+
public:
// These are just used as tags to select the desired constructor.
struct WithUndoableCompression {};
struct WithPermanentCompression {};
NormalizedComponentStorageHolder() = default;
-
+
/**
* The MemoryPool is only used during construction, the constructed object *can* outlive the memory pool.
*/
- NormalizedComponentStorageHolder(
- ComponentStorage&& component,
- const std::vector<TypeId, ArenaAllocator<TypeId>>& exposed_types,
- MemoryPool& memory_pool,
- WithUndoableCompression);
+ NormalizedComponentStorageHolder(ComponentStorage&& component,
+ const std::vector<TypeId, ArenaAllocator<TypeId>>& exposed_types,
+ MemoryPool& memory_pool, WithUndoableCompression);
NormalizedComponentStorageHolder(NormalizedComponentStorage&&) = delete;
NormalizedComponentStorageHolder(const NormalizedComponentStorage&) = delete;
-
+
NormalizedComponentStorageHolder& operator=(NormalizedComponentStorageHolder&&) = delete;
NormalizedComponentStorageHolder& operator=(const NormalizedComponentStorageHolder&) = default;
-
+
// We don't use the default destructor because that would require the inclusion of
// normalized_component_storage.h. We define this in the cpp file instead.
~NormalizedComponentStorageHolder();
diff --git a/include/fruit/impl/provider.defn.h b/include/fruit/impl/provider.defn.h
index 005e0ea..6f65bbf 100644
--- a/include/fruit/impl/provider.defn.h
+++ b/include/fruit/impl/provider.defn.h
@@ -4,9 +4,9 @@
* 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.
@@ -25,9 +25,9 @@
namespace fruit {
template <typename C>
-inline Provider<C>::Provider(fruit::impl::InjectorStorage* storage, fruit::impl::InjectorStorage::Graph::node_iterator itr)
- : storage(storage), itr(itr) {
-}
+inline Provider<C>::Provider(fruit::impl::InjectorStorage* storage,
+ fruit::impl::InjectorStorage::Graph::node_iterator itr)
+ : storage(storage), itr(itr) {}
template <typename C>
inline C* Provider<C>::get() {
@@ -41,14 +41,12 @@
struct ProviderImplHelper {
template <typename T>
- using CheckGet = Eval<
- PropagateError(CheckInjectableType(RemoveAnnotations(Type<T>)),
- If(Not(IsSame(GetClassForType(Type<T>), RemoveConstFromType(Type<C>))),
- ConstructError(Id<TypeNotProvidedErrorTag>, Type<T>),
- If(And(TypeInjectionRequiresNonConstBinding(Type<T>), Not(IsSame(Id<GetClassForType(Type<T>)>, Type<C>))),
- ConstructError(TypeProvidedAsConstOnlyErrorTag, Type<T>),
- None
- )))>;
+ using CheckGet = Eval<PropagateError(
+ CheckInjectableType(RemoveAnnotations(Type<T>)),
+ If(Not(IsSame(GetClassForType(Type<T>), RemoveConstFromType(Type<C>))),
+ ConstructError(Id<TypeNotProvidedErrorTag>, Type<T>),
+ If(And(TypeInjectionRequiresNonConstBinding(Type<T>), Not(IsSame(Id<GetClassForType(Type<T>)>, Type<C>))),
+ ConstructError(TypeProvidedAsConstOnlyErrorTag, Type<T>), None)))>;
};
} // namespace meta
@@ -68,8 +66,6 @@
return get<T>();
}
-
} // namespace fruit
-
#endif // FRUIT_PROVIDER_DEFN_H
diff --git a/include/fruit/impl/util/call_with_tuple.h b/include/fruit/impl/util/call_with_tuple.h
index ab7ea91..3828a1b 100644
--- a/include/fruit/impl/util/call_with_tuple.h
+++ b/include/fruit/impl/util/call_with_tuple.h
@@ -4,9 +4,9 @@
* 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.
@@ -27,7 +27,7 @@
template <typename... Ints, typename Result, typename... Args>
struct CallWithTupleHelper<fruit::impl::meta::Vector<Ints...>, Result, std::tuple<Args...>> {
- Result operator()(Result(*fun)(Args...), std::tuple<Args...> args) {
+ Result operator()(Result (*fun)(Args...), std::tuple<Args...> args) {
// This parameter *is* used, but when the tuple is empty some compilers report is as unused.
(void)args;
return fun(std::get<Ints::value>(args)...);
@@ -35,11 +35,11 @@
};
template <typename Result, typename... Args>
-inline Result callWithTuple(Result(*fun)(Args...), std::tuple<Args...> args) {
- using IntVector = fruit::impl::meta::Eval<fruit::impl::meta::GenerateIntSequence(fruit::impl::meta::Int<sizeof...(Args)>)>;
+inline Result callWithTuple(Result (*fun)(Args...), std::tuple<Args...> args) {
+ using IntVector =
+ fruit::impl::meta::Eval<fruit::impl::meta::GenerateIntSequence(fruit::impl::meta::Int<sizeof...(Args)>)>;
return CallWithTupleHelper<IntVector, Result, std::tuple<Args...>>()(fun, args);
}
-
}
}
diff --git a/include/fruit/impl/util/demangle_type_name.h b/include/fruit/impl/util/demangle_type_name.h
index 8a5d77f..59687db 100644
--- a/include/fruit/impl/util/demangle_type_name.h
+++ b/include/fruit/impl/util/demangle_type_name.h
@@ -4,9 +4,9 @@
* 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.
@@ -21,5 +21,4 @@
std::string demangleTypeName(const char* name);
-
#endif // FRUIT_DEMANGLE_TYPE_NAME_H
diff --git a/include/fruit/impl/util/hash_codes.defn.h b/include/fruit/impl/util/hash_codes.defn.h
index c2c90bf..a860e24 100644
--- a/include/fruit/impl/util/hash_codes.defn.h
+++ b/include/fruit/impl/util/hash_codes.defn.h
@@ -4,9 +4,9 @@
* 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.
@@ -49,9 +49,8 @@
template <typename... Args, int last_index>
struct HashTupleHelper<std::tuple<Args...>, last_index> {
std::size_t operator()(const std::tuple<Args...>& x) {
- return combineHashes(
- hashTupleElement<std::tuple<Args...>, last_index - 1>(x),
- HashTupleHelper<std::tuple<Args...>, last_index - 1>()(x));
+ return combineHashes(hashTupleElement<std::tuple<Args...>, last_index - 1>(x),
+ HashTupleHelper<std::tuple<Args...>, last_index - 1>()(x));
}
};
@@ -61,7 +60,7 @@
}
inline std::size_t combineHashes(std::size_t h1, std::size_t h2) {
- h1 ^= h2 + 0x9e3779b9 + (h1<<6) + (h1>>2);
+ h1 ^= h2 + 0x9e3779b9 + (h1 << 6) + (h1 >> 2);
return h1;
}
diff --git a/include/fruit/impl/util/hash_codes.h b/include/fruit/impl/util/hash_codes.h
index ee6e8d4..b9213db 100644
--- a/include/fruit/impl/util/hash_codes.h
+++ b/include/fruit/impl/util/hash_codes.h
@@ -4,9 +4,9 @@
* 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.
diff --git a/include/fruit/impl/util/hash_helpers.defn.h b/include/fruit/impl/util/hash_helpers.defn.h
index 1f3b4f3..e75ec4a 100644
--- a/include/fruit/impl/util/hash_helpers.defn.h
+++ b/include/fruit/impl/util/hash_helpers.defn.h
@@ -4,9 +4,9 @@
* 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.
@@ -17,8 +17,8 @@
#ifndef FRUIT_HASH_HELPERS_DEFN_H
#define FRUIT_HASH_HELPERS_DEFN_H
-#include <fruit/impl/util/hash_helpers.h>
#include <fruit/impl/meta/vector.h>
+#include <fruit/impl/util/hash_helpers.h>
namespace fruit {
namespace impl {
@@ -39,10 +39,11 @@
}
template <typename T, typename Hasher, typename EqualityComparator>
-inline HashSetWithArenaAllocator<T, Hasher, EqualityComparator> createHashSetWithArenaAllocatorAndCustomFunctors(
- size_t capacity, MemoryPool& memory_pool, Hasher hasher, EqualityComparator equality_comparator) {
- return HashSetWithArenaAllocator<T, Hasher, EqualityComparator>(
- capacity, hasher, equality_comparator, ArenaAllocator<T>(memory_pool));
+inline HashSetWithArenaAllocator<T, Hasher, EqualityComparator>
+createHashSetWithArenaAllocatorAndCustomFunctors(size_t capacity, MemoryPool& memory_pool, Hasher hasher,
+ EqualityComparator equality_comparator) {
+ return HashSetWithArenaAllocator<T, Hasher, EqualityComparator>(capacity, hasher, equality_comparator,
+ ArenaAllocator<T>(memory_pool));
}
template <typename Key, typename Value>
@@ -56,23 +57,20 @@
}
template <typename Key, typename Value>
-inline HashMapWithArenaAllocator<Key, Value> createHashMapWithArenaAllocator(
- std::size_t capacity, MemoryPool& memory_pool) {
- return createHashMapWithArenaAllocatorAndCustomFunctors<Key, Value>(
- capacity,
- memory_pool,
- std::hash<Key>(),
- std::equal_to<Key>());
+inline HashMapWithArenaAllocator<Key, Value> createHashMapWithArenaAllocator(std::size_t capacity,
+ MemoryPool& memory_pool) {
+ return createHashMapWithArenaAllocatorAndCustomFunctors<Key, Value>(capacity, memory_pool, std::hash<Key>(),
+ std::equal_to<Key>());
}
template <typename Key, typename Value, typename Hasher, typename EqualityComparator>
-inline HashMapWithArenaAllocator<Key, Value, Hasher, EqualityComparator> createHashMapWithArenaAllocatorAndCustomFunctors(
- size_t capacity, MemoryPool& memory_pool, Hasher hasher, EqualityComparator equality_comparator) {
+inline HashMapWithArenaAllocator<Key, Value, Hasher, EqualityComparator>
+createHashMapWithArenaAllocatorAndCustomFunctors(size_t capacity, MemoryPool& memory_pool, Hasher hasher,
+ EqualityComparator equality_comparator) {
return HashMapWithArenaAllocator<Key, Value, Hasher, EqualityComparator>(
capacity, hasher, equality_comparator, ArenaAllocator<std::pair<const Key, Value>>(memory_pool));
}
-
} // namespace impl
} // namespace fruit
diff --git a/include/fruit/impl/util/hash_helpers.h b/include/fruit/impl/util/hash_helpers.h
index ab49124..a060aac 100644
--- a/include/fruit/impl/util/hash_helpers.h
+++ b/include/fruit/impl/util/hash_helpers.h
@@ -4,9 +4,9 @@
* 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.
@@ -17,8 +17,8 @@
#ifndef FRUIT_HASH_HELPERS_H
#define FRUIT_HASH_HELPERS_H
-#include <fruit/impl/fruit-config.h>
#include <fruit/impl/data_structures/arena_allocator.h>
+#include <fruit/impl/fruit-config.h>
#ifndef IN_FRUIT_CPP_FILE
// We don't want to include it in public headers to save some compile time.
@@ -26,11 +26,11 @@
#endif
#if FRUIT_USES_BOOST
-#include <boost/unordered_set.hpp>
#include <boost/unordered_map.hpp>
+#include <boost/unordered_set.hpp>
#else
-#include <unordered_set>
#include <unordered_map>
+#include <unordered_set>
#endif
namespace fruit {
@@ -46,7 +46,8 @@
template <typename Key, typename Value, typename Hasher = std::hash<Key>>
using HashMap = boost::unordered_map<Key, Value, Hasher>;
-template <typename Key, typename Value, typename Hasher = std::hash<Key>, typename EqualityComparator = std::equal_to<Key>>
+template <typename Key, typename Value, typename Hasher = std::hash<Key>,
+ typename EqualityComparator = std::equal_to<Key>>
using HashMapWithArenaAllocator =
boost::unordered_map<Key, Value, Hasher, EqualityComparator, ArenaAllocator<std::pair<const Key, Value>>>;
@@ -60,7 +61,8 @@
template <typename Key, typename Value, typename Hasher = std::hash<Key>>
using HashMap = std::unordered_map<Key, Value, Hasher>;
-template <typename Key, typename Value, typename Hasher = std::hash<Key>, typename EqualityComparator = std::equal_to<Key>>
+template <typename Key, typename Value, typename Hasher = std::hash<Key>,
+ typename EqualityComparator = std::equal_to<Key>>
using HashMapWithArenaAllocator =
std::unordered_map<Key, Value, Hasher, EqualityComparator, ArenaAllocator<std::pair<const Key, Value>>>;
@@ -73,12 +75,11 @@
HashSet<T> createHashSet(size_t capacity);
template <typename T>
-HashSetWithArenaAllocator<T> createHashSetWithArenaAllocator(
- size_t capacity, MemoryPool& memory_pool);
+HashSetWithArenaAllocator<T> createHashSetWithArenaAllocator(size_t capacity, MemoryPool& memory_pool);
template <typename T, typename Hasher, typename EqualityComparator>
-HashSetWithArenaAllocator<T, Hasher, EqualityComparator> createHashSetWithArenaAllocatorAndCustomFunctors(
- size_t capacity, MemoryPool& memory_pool, Hasher, EqualityComparator);
+HashSetWithArenaAllocator<T, Hasher, EqualityComparator>
+createHashSetWithArenaAllocatorAndCustomFunctors(size_t capacity, MemoryPool& memory_pool, Hasher, EqualityComparator);
template <typename Key, typename Value>
HashMap<Key, Value> createHashMap();
@@ -87,12 +88,11 @@
HashMap<Key, Value> createHashMap(size_t capacity);
template <typename Key, typename Value>
-HashMapWithArenaAllocator<Key, Value> createHashMapWithArenaAllocator(
- size_t capacity, MemoryPool& memory_pool);
+HashMapWithArenaAllocator<Key, Value> createHashMapWithArenaAllocator(size_t capacity, MemoryPool& memory_pool);
template <typename Key, typename Value, typename Hasher, typename EqualityComparator>
-HashMapWithArenaAllocator<Key, Value, Hasher, EqualityComparator> createHashMapWithArenaAllocatorAndCustomFunctors(
- size_t capacity, MemoryPool& memory_pool, Hasher, EqualityComparator);
+HashMapWithArenaAllocator<Key, Value, Hasher, EqualityComparator>
+createHashMapWithArenaAllocatorAndCustomFunctors(size_t capacity, MemoryPool& memory_pool, Hasher, EqualityComparator);
} // namespace impl
} // namespace fruit
diff --git a/include/fruit/impl/util/lambda_invoker.h b/include/fruit/impl/util/lambda_invoker.h
index 966a0be..2c8d63e 100644
--- a/include/fruit/impl/util/lambda_invoker.h
+++ b/include/fruit/impl/util/lambda_invoker.h
@@ -4,9 +4,9 @@
* 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.
@@ -20,13 +20,13 @@
#include <fruit/impl/fruit-config.h>
#include <fruit/impl/injection_errors.h>
#include <fruit/impl/meta/errors.h>
-#include <fruit/impl/meta/wrappers.h>
-#include <fruit/impl/meta/signatures.h>
#include <fruit/impl/meta/metaprogramming.h>
+#include <fruit/impl/meta/signatures.h>
+#include <fruit/impl/meta/wrappers.h>
-#include <type_traits>
-#include <functional>
#include <cstddef>
+#include <functional>
+#include <type_traits>
namespace fruit {
namespace impl {
@@ -34,14 +34,14 @@
class LambdaInvoker {
public:
template <typename F, typename... Args>
- FRUIT_ALWAYS_INLINE
- static auto invoke(Args&&... args) -> decltype(std::declval<const F&>()(std::declval<Args>()...)) {
+ FRUIT_ALWAYS_INLINE static auto invoke(Args&&... args)
+ -> decltype(std::declval<const F&>()(std::declval<Args>()...)) {
// We reinterpret-cast a char[] to avoid de-referencing nullptr, which would technically be
// undefined behavior (even though we would not access any data there anyway).
// Sharing this buffer for different types F would also be undefined behavior since we'd break
// strict aliasing between those types.
alignas(alignof(F)) static char buf[1];
-
+
FruitStaticAssert(fruit::impl::meta::IsEmpty(fruit::impl::meta::Type<F>));
FruitStaticAssert(fruit::impl::meta::IsTriviallyCopyable(fruit::impl::meta::Type<F>));
// Since `F' is empty, a valid value of type F is already stored at the beginning of buf.
diff --git a/include/fruit/impl/util/type_info.defn.h b/include/fruit/impl/util/type_info.defn.h
index 0e5b8e2..8b8df69 100644
--- a/include/fruit/impl/util/type_info.defn.h
+++ b/include/fruit/impl/util/type_info.defn.h
@@ -4,9 +4,9 @@
* 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.
@@ -19,11 +19,11 @@
#include <fruit/impl/util/type_info.h>
-#include <fruit/impl/fruit-config.h>
#include <fruit/fruit_forward_decls.h>
-#include <fruit/impl/fruit_assert.h>
-#include <fruit/impl/data_structures/memory_pool.h>
#include <fruit/impl/data_structures/arena_allocator.h>
+#include <fruit/impl/data_structures/memory_pool.h>
+#include <fruit/impl/fruit-config.h>
+#include <fruit/impl/fruit_assert.h>
namespace fruit {
namespace impl {
@@ -32,9 +32,7 @@
struct GetConcreteTypeInfo {
constexpr TypeInfo::ConcreteTypeInfo operator()() const {
return TypeInfo::ConcreteTypeInfo{
- sizeof(T),
- alignof(T),
- std::is_trivially_destructible<T>::value,
+ sizeof(T), alignof(T), std::is_trivially_destructible<T>::value,
#ifdef FRUIT_EXTRA_DEBUG
false /* is_abstract */,
#endif
@@ -49,9 +47,7 @@
struct GetConcreteTypeInfo<T, true> {
constexpr TypeInfo::ConcreteTypeInfo operator()() const {
return TypeInfo::ConcreteTypeInfo{
- 0 /* type_size */,
- 0 /* type_alignment */,
- false /* is_trivially_destructible */,
+ 0 /* type_size */, 0 /* type_alignment */, false /* is_trivially_destructible */,
#ifdef FRUIT_EXTRA_DEBUG
true /* is_abstract */,
#endif
@@ -59,15 +55,12 @@
}
};
-
// This should only be used if RTTI is disabled. Use the other constructor if possible.
inline constexpr TypeInfo::TypeInfo(ConcreteTypeInfo concrete_type_info)
- : info(nullptr), concrete_type_info(concrete_type_info) {
-}
+ : info(nullptr), concrete_type_info(concrete_type_info) {}
inline constexpr TypeInfo::TypeInfo(const std::type_info& info, ConcreteTypeInfo concrete_type_info)
- : info(&info), concrete_type_info(concrete_type_info) {
-}
+ : info(&info), concrete_type_info(concrete_type_info) {}
inline std::string TypeInfo::name() const {
if (info != nullptr) // LCOV_EXCL_BR_LINE
@@ -81,14 +74,14 @@
FruitAssert(!concrete_type_info.is_abstract);
#endif
return concrete_type_info.type_size;
-}
+}
inline size_t TypeInfo::alignment() const {
#ifdef FRUIT_EXTRA_DEBUG
FruitAssert(!concrete_type_info.is_abstract);
#endif
return concrete_type_info.type_alignment;
-}
+}
inline bool TypeInfo::isTriviallyDestructible() const {
#ifdef FRUIT_EXTRA_DEBUG
@@ -96,7 +89,7 @@
#endif
return concrete_type_info.is_trivially_destructible;
}
-
+
inline TypeId::operator std::string() const {
return type_info->name();
}
@@ -138,7 +131,8 @@
template <typename T>
inline TypeId getTypeId() {
#if defined(FRUIT_HAS_TYPEID) && !defined(FRUIT_HAS_CONSTEXPR_TYPEID)
- // We can't use constexpr here because TypeInfo contains a `const std::type_info&` and that's not constexpr with the current compiler/STL.
+ // We can't use constexpr here because TypeInfo contains a `const std::type_info&` and that's not constexpr with the
+ // current compiler/STL.
static TypeInfo info = GetTypeInfoForType<T>()();
#else
// Usual case. The `constexpr' ensures compile-time evaluation.
@@ -153,9 +147,7 @@
template <typename... Ts>
struct GetTypeIdsForListHelper<fruit::impl::meta::Vector<Ts...>> {
std::vector<TypeId, ArenaAllocator<TypeId>> operator()(MemoryPool& memory_pool) {
- return std::vector<TypeId, ArenaAllocator<TypeId>>(
- std::initializer_list<TypeId>{getTypeId<Ts>()...},
- memory_pool);
+ return std::vector<TypeId, ArenaAllocator<TypeId>>(std::initializer_list<TypeId>{getTypeId<Ts>()...}, memory_pool);
}
};
@@ -176,7 +168,7 @@
} // namespace fruit
namespace std {
-
+
inline std::size_t hash<fruit::impl::TypeId>::operator()(fruit::impl::TypeId type) const {
return hash<const fruit::impl::TypeInfo*>()(type.type_info);
}
diff --git a/include/fruit/impl/util/type_info.h b/include/fruit/impl/util/type_info.h
index 3918d69..7ffc8b3 100644
--- a/include/fruit/impl/util/type_info.h
+++ b/include/fruit/impl/util/type_info.h
@@ -4,9 +4,9 @@
* 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.
@@ -17,9 +17,9 @@
#ifndef FRUIT_TYPE_INFO_H
#define FRUIT_TYPE_INFO_H
-#include <typeinfo>
-#include <fruit/impl/util/demangle_type_name.h>
#include <fruit/impl/meta/vector.h>
+#include <fruit/impl/util/demangle_type_name.h>
+#include <typeinfo>
#include <vector>
@@ -51,9 +51,9 @@
size_t size() const;
size_t alignment() const;
-
+
bool isTriviallyDestructible() const;
-
+
private:
// The std::type_info struct associated with the type, or nullptr if RTTI is disabled.
// This is only used for the type name.
@@ -63,9 +63,9 @@
struct TypeId {
const TypeInfo* type_info;
-
+
operator std::string() const;
-
+
bool operator==(TypeId x) const;
bool operator!=(TypeId x) const;
bool operator<(TypeId x) const;
@@ -100,7 +100,7 @@
#endif // FRUIT_EXTRA_DEBUG
namespace std {
-
+
template <>
struct hash<fruit::impl::TypeId> {
std::size_t operator()(fruit::impl::TypeId type) const;
diff --git a/include/fruit/injector.h b/include/fruit/injector.h
index 585351f..e6cb13e 100644
--- a/include/fruit/injector.h
+++ b/include/fruit/injector.h
@@ -4,9 +4,9 @@
* 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.
@@ -21,8 +21,8 @@
#include <fruit/impl/injection_errors.h>
#include <fruit/component.h>
-#include <fruit/provider.h>
#include <fruit/normalized_component.h>
+#include <fruit/provider.h>
namespace fruit {
@@ -32,13 +32,13 @@
* An injector does *not* need to specify all types bound in the component; you can only specify the "root" type(s) and
* the injector will also create and store the instances of classes that are needed (directly or indirectly) to inject
* the root types.
- *
+ *
* Example usage:
*
* Component<Foo, Bar> getFooBarComponent() {
* ...
* }
- *
+ *
* Injector<Foo, Bar> injector(getFooBarComponent);
* Foo* foo = injector.get<Foo*>();
* Bar* bar(injector); // Equivalent to: Bar* bar = injector.get<Bar*>();
@@ -48,21 +48,20 @@
private:
template <typename T>
struct RemoveAnnotationsHelper {
- using type = fruit::impl::meta::UnwrapType<fruit::impl::meta::Eval<
- fruit::impl::meta::RemoveAnnotations(fruit::impl::meta::Type<T>)
- >>;
+ using type = fruit::impl::meta::UnwrapType<
+ fruit::impl::meta::Eval<fruit::impl::meta::RemoveAnnotations(fruit::impl::meta::Type<T>)>>;
};
template <typename T>
using RemoveAnnotations = typename RemoveAnnotationsHelper<T>::type;
-
+
public:
// Moving injectors is allowed.
Injector(Injector&&) = default;
-
+
// Copying injectors is forbidden.
Injector(const Injector&) = delete;
-
+
/**
* This creates an injector from a component function (that can optionally have parameters).
*
@@ -89,8 +88,8 @@
* Foo* foo = injector.get<Foo*>();
*/
template <typename... FormalArgs, typename... Args>
- Injector(Component<P...>(*)(FormalArgs...), Args&&... args);
-
+ Injector(Component<P...> (*)(FormalArgs...), Args&&... args);
+
/**
* This creates an injector from a normalized component and a component function.
* See the documentation of NormalizedComponent for more details.
@@ -100,43 +99,45 @@
*
* The NormalizedComponent can have requirements, but the Component can't.
* The NormalizedComponent must remain valid during the lifetime of any Injector object constructed with it.
- *
+ *
* Example usage:
- *
+ *
* // In the global scope.
* Component<Request> getRequestComponent(Request* request) {
* return fruit::createComponent()
* .bindInstance(*request);
* }
- *
+ *
* // At startup (e.g. inside main()).
* NormalizedComponent<Required<Request>, Bar, Bar2> normalizedComponent = ...;
- *
+ *
* ...
* for (...) {
* // For each request.
* Request request = ...;
- *
+ *
* Injector<Foo, Bar> injector(normalizedComponent, getRequestComponent, &request);
* Foo* foo = injector.get<Foo*>();
* ...
* }
*/
- template <typename... NormalizedComponentParams, typename... ComponentParams, typename... FormalArgs, typename... Args>
+ template <typename... NormalizedComponentParams, typename... ComponentParams, typename... FormalArgs,
+ typename... Args>
Injector(const NormalizedComponent<NormalizedComponentParams...>& normalized_component,
- Component<ComponentParams...>(*)(FormalArgs...), Args&&... args);
-
+ Component<ComponentParams...> (*)(FormalArgs...), Args&&... args);
+
/**
* Deleted constructor, to ensure that constructing an Injector from a temporary NormalizedComponent doesn't compile.
*/
- template <typename... NormalizedComponentParams, typename... ComponentParams, typename... FormalArgs, typename... Args>
- Injector(NormalizedComponent<NormalizedComponentParams...>&& normalized_component,
- Component<ComponentParams...>(*)(FormalArgs...), Args&&... args) = delete;
-
+ template <typename... NormalizedComponentParams, typename... ComponentParams, typename... FormalArgs,
+ typename... Args>
+ Injector(NormalizedComponent<NormalizedComponentParams...>&& normalized_component,
+ Component<ComponentParams...> (*)(FormalArgs...), Args&&... args) = delete;
+
/**
* Returns an instance of the specified type. For any class C in the Injector's template parameters, the following
* variations are allowed:
- *
+ *
* get<C>()
* get<C*>()
* get<C&>()
@@ -176,14 +177,14 @@
*/
template <typename T>
typename Injector<P...>::template RemoveAnnotations<T> get();
-
+
/**
* This is a convenient way to call get(). E.g.:
- *
+ *
* MyInterface* x(injector);
- *
+ *
* is equivalent to:
- *
+ *
* MyInterface* x = injector.get<MyInterface*>();
*
* Note that this can't be used to inject an annotated type, i.e. this does NOT work:
@@ -197,29 +198,29 @@
*/
template <typename T>
explicit operator T();
-
+
/**
* Gets all multibindings for a type T.
- *
+ *
* Multibindings are independent from bindings; so if there is a (normal) binding for T, that is not returned.
* This returns an empty vector if there are no multibindings.
- *
+ *
* With a non-annotated parameter T, this returns a const std::vector<T*>&.
* With an annotated parameter AnnotatedT=Annotated<Annotation, T>, this returns a const std::vector<T*>&.
*/
template <typename T>
const std::vector<RemoveAnnotations<T>*>& getMultibindings();
-
+
/**
* Eagerly injects all reachable bindings and multibindings of this injector.
* This only creates instances of the types that are either:
* - exposed by this Injector (i.e. in the Injector's type parameters)
* - bound by a multibinding
* - needed to inject one of the above (directly or indirectly)
- *
+ *
* Unreachable bindings (i.e. bindings that are not exposed by this Injector, and that are not used by any reachable
* binding) are not processed. Bindings that are only used lazily, using a Provider, are NOT eagerly injected.
- *
+ *
* Call this to ensure thread safety if the injector will be shared by multiple threads.
* After calling this method, get() and getMultibindings() can be called concurrently on the same injector, with no
* locking. Note that the guarantee only applies after this method returns; specifically, this method can NOT be
@@ -230,11 +231,10 @@
* was already injected.
*/
void eagerlyInjectAll();
-
+
private:
using Check1 = typename fruit::impl::meta::CheckIfError<fruit::impl::meta::Eval<
- fruit::impl::meta::CheckNoRequiredTypesInInjectorArguments(fruit::impl::meta::Type<P>...)
- >>::type;
+ fruit::impl::meta::CheckNoRequiredTypesInInjectorArguments(fruit::impl::meta::Type<P>...)>>::type;
// Force instantiation of Check1.
static_assert(true || sizeof(Check1), "");
@@ -245,15 +245,15 @@
// Force instantiation of Check2.
static_assert(true || sizeof(Check2), "");
using Check3 = typename fruit::impl::meta::CheckIfError<fruit::impl::meta::Eval<fruit::impl::meta::If(
- fruit::impl::meta::Not(fruit::impl::meta::IsEmptySet(typename Comp::RsSuperset)),
- fruit::impl::meta::ConstructErrorWithArgVector(fruit::impl::InjectorWithRequirementsErrorTag, fruit::impl::meta::SetToVector(typename Comp::RsSuperset)),
- VoidType)
- >>::type;
+ fruit::impl::meta::Not(fruit::impl::meta::IsEmptySet(typename Comp::RsSuperset)),
+ fruit::impl::meta::ConstructErrorWithArgVector(fruit::impl::InjectorWithRequirementsErrorTag,
+ fruit::impl::meta::SetToVector(typename Comp::RsSuperset)),
+ VoidType)>>::type;
// Force instantiation of Check3.
static_assert(true || sizeof(Check3), "");
friend struct fruit::impl::InjectorAccessorForTests;
-
+
std::unique_ptr<fruit::impl::InjectorStorage> storage;
};
diff --git a/include/fruit/macro.h b/include/fruit/macro.h
index 80eb8bc..6ce59c8 100644
--- a/include/fruit/macro.h
+++ b/include/fruit/macro.h
@@ -4,9 +4,9 @@
* 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.
@@ -26,83 +26,83 @@
* A convenience macro to define the Inject typedef while declaring/defining the constructor that will be used for
* injection.
* It also supports assisted injection and injection of annotated types.
- *
+ *
* Example usage:
- *
+ *
* class MyClass {
* public:
* INJECT(MyClass(Foo* foo, Bar* bar)) {...}
* };
- *
+ *
* is equivalent to:
- *
+ *
* class MyClass {
* public:
* using Inject = MyClass(Foo*, Bar*);
- *
+ *
* MyClass(Foo* foo, Bar* y) {...}
* };
- *
+ *
* Example usage for assisted injection (see PartialComponent::registerFactory):
- *
+ *
* class MyClass {
* public:
* INJECT(MyClass(Foo* foo, ASSISTED(int) n) {...}
* };
- *
+ *
* is equivalent to:
- *
+ *
* class MyClass {
* public:
* using Inject = MyClass(Foo*, Assisted<int>);
- *
+ *
* MyClass(Foo* foo, int n) {...}
* };
- *
+ *
* Example usage for annotated types:
- *
+ *
* class MyClass {
* public:
* INJECT(MyClass(ANNOTATED(SomeAnnotation, Foo*) foo, Bar* bar)) {...}
* };
- *
+ *
* ASSISTED and ANNOTATED *can* be used together in the same INJECT() annotation, but they can't both be used for a
* single parameter (as this wouldn't make sense, parameters that use assisted injection are user-supplied, they aren't
* injected from a binding).
- *
+ *
* NOTE: This can't be used if the constructor is templated (the class can be templated, however), if there are any
* default arguments or if the constructor is marked `explicit'.
* In those cases, define the Inject annotation manually or use registerConstructor()/registerFactory() instead.
- *
+ *
* NOTE: ASSISTED takes just one argument, but it's declared as variadic to make sure that the preprocessor doesn't
* choke on multi-argument templates like the map above, that the processor is unable to parse correctly.
- *
+ *
* NOTE: ASSISTED takes just 2 arguments, but it's declared as variadic to make sure that the preprocessor doesn't choke
* on multi-argument templates, that the processor is unable to parse correctly.
- *
+ *
* NOTE: In addition to the public Inject typedef, two typedefs (FruitAssistedTypedef and FruitAnnotatedTypedef) will be
* defined inside the class, make sure you don't define another typedef/field/method with the same name if you use the
* INJECT macro (unlikely but possible) these typedefs are an implementation detail of Fruit and should not be used.
- *
+ *
* NOTE: The return type (MyClass in this case) should not be annotated. However an annotated
* MyClass (or MyClass factory) can be injected from any INJECT declaration.
*/
-#define INJECT(Signature) \
-using Inject = Signature; \
-\
-template <typename FruitAssistedDeclarationParam> \
-using FruitAssistedTypedef = FruitAssistedDeclarationParam; \
-template <typename Annotation, typename FruitAnnotatedDeclarationParam> \
-using FruitAnnotatedTypedef = FruitAnnotatedDeclarationParam; \
-\
-Signature
+#define INJECT(Signature) \
+ using Inject = Signature; \
+ \
+ template <typename FruitAssistedDeclarationParam> \
+ using FruitAssistedTypedef = FruitAssistedDeclarationParam; \
+ template <typename Annotation, typename FruitAnnotatedDeclarationParam> \
+ using FruitAnnotatedTypedef = FruitAnnotatedDeclarationParam; \
+ \
+ Signature
#define ASSISTED(...) FruitAssistedTypedef<__VA_ARGS__>
#define ANNOTATED(Annotation, ...) FruitAnnotatedTypedef<Annotation, __VA_ARGS__>
/**
* These are intentionally NOT in the fruit namespace, they can't be there for technical reasons.
- *
+ *
* NOTE: don't use these directly, they're only used to implement the INJECT macro.
* Consider them part of fruit::impl.
*/
diff --git a/include/fruit/normalized_component.h b/include/fruit/normalized_component.h
index 9864499..105edf8 100644
--- a/include/fruit/normalized_component.h
+++ b/include/fruit/normalized_component.h
@@ -4,9 +4,9 @@
* 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.
@@ -78,26 +78,26 @@
* in two injectors, each injector will construct its own instance of Foo.
*
* Example usage in a server:
- *
+ *
* // In the global scope.
* Component<Request> getRequestComponent(Request* request) {
* return fruit::createComponent()
* .bindInstance(*request);
* }
- *
+ *
* // At startup (e.g. inside main()).
* NormalizedComponent<Required<Request>, Bar, Bar2> normalizedComponent = ...;
- *
+ *
* ...
* for (...) {
* // For each request.
* Request request = ...;
- *
+ *
* Injector<Foo, Bar> injector(normalizedComponent, getRequestComponent, &request);
* Foo* foo = injector.get<Foo*>();
* ...
* }
- *
+ *
* See also the documentation for the Injector constructor that takes a NormalizedComponent.
*/
template <typename... Params>
@@ -111,24 +111,24 @@
* The constraints on the argument types (if there are any) are the same as the ones for PartialComponent::install().
*/
template <typename... FormalArgs, typename... Args>
- NormalizedComponent(Component<Params...>(*)(FormalArgs...), Args&&... args);
-
+ NormalizedComponent(Component<Params...> (*)(FormalArgs...), Args&&... args);
+
NormalizedComponent(NormalizedComponent&&) = default;
NormalizedComponent(const NormalizedComponent&) = delete;
-
+
NormalizedComponent& operator=(NormalizedComponent&&) = delete;
NormalizedComponent& operator=(const NormalizedComponent&) = delete;
-
+
private:
NormalizedComponent(fruit::impl::ComponentStorage&& storage, fruit::impl::MemoryPool memory_pool);
// This is held via a unique_ptr to avoid including normalized_component_storage.h
// in fruit.h.
fruit::impl::NormalizedComponentStorageHolder storage;
-
+
template <typename... OtherParams>
friend class Injector;
-
+
using Comp = fruit::impl::meta::Eval<fruit::impl::meta::ConstructComponentImpl(fruit::impl::meta::Type<Params>...)>;
using Check1 = typename fruit::impl::meta::CheckIfError<Comp>::type;
diff --git a/include/fruit/provider.h b/include/fruit/provider.h
index 3500128..9284d0b 100644
--- a/include/fruit/provider.h
+++ b/include/fruit/provider.h
@@ -4,9 +4,9 @@
* 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.
@@ -28,11 +28,11 @@
* A Provider is a class that allows access to instances of the types used as parameters of the Provider template.
* It's possible to inject a Provider<MyClass> instead of MyClass itself, and this allows lazy injection.
* For example:
- *
+ *
* class S {
* private:
* Bar* bar = nullptr;
- *
+ *
* public:
* INJECT(S(Foo* foo, Provider<Bar> barProvider)) {
* if (foo->needsBar()) {
@@ -40,22 +40,22 @@
* }
* }
* };
- *
+ *
* In the example above, Bar will only be created if get<Bar*> is called.
* This can be useful if Bar is expensive to create (or some other types that need to be injected when a Bar is injected
* are) or if there are other side effects of the Bar constructor that are undesirable when !foo->needsBar().
* It's also possible to store the Provider object in a field, and create the Bar instance when the first method that
* needs it is called:
- *
+ *
* class S {
* private:
* Provider<Bar> barProvider;
- *
+ *
* public:
* INJECT(S(Provider<Bar> barProvider))
* : barProvider(barProvider) {
* }
- *
+ *
* void execute() {
* if (...) {
* Bar* bar = barProvider.get();
@@ -63,7 +63,7 @@
* }
* }
* };
- *
+ *
* As usual, Fruit ensures that (at most) one instance is ever created in a given injector; so if the Bar object was
* already constructed, the get() will simply return it.
*
@@ -73,11 +73,15 @@
template <typename C>
class Provider {
private:
- using Check1 = typename fruit::impl::meta::CheckIfError<fruit::impl::meta::Eval<fruit::impl::meta::CheckNormalizedTypes(fruit::impl::meta::RemoveConstFromTypes(fruit::impl::meta::Vector<fruit::impl::meta::Type<C>>))>>::type;
+ using Check1 =
+ typename fruit::impl::meta::CheckIfError<fruit::impl::meta::Eval<fruit::impl::meta::CheckNormalizedTypes(
+ fruit::impl::meta::RemoveConstFromTypes(fruit::impl::meta::Vector<fruit::impl::meta::Type<C>>))>>::type;
// Force instantiation of Check1.
static_assert(true || sizeof(Check1), "");
- using Check2 = typename fruit::impl::meta::CheckIfError<fruit::impl::meta::Eval<fruit::impl::meta::CheckNotAnnotatedTypes(fruit::impl::meta::Vector<fruit::impl::meta::Type<C>>)>>::type;
+ using Check2 =
+ typename fruit::impl::meta::CheckIfError<fruit::impl::meta::Eval<fruit::impl::meta::CheckNotAnnotatedTypes(
+ fruit::impl::meta::Vector<fruit::impl::meta::Type<C>>)>>::type;
// Force instantiation of Check2.
static_assert(true || sizeof(Check2), "");
@@ -110,19 +114,19 @@
*/
template <typename T>
T get();
-
+
/**
* This is a convenient way to call get(). E.g.:
- *
+ *
* C& x(provider);
- *
+ *
* is equivalent to:
- *
+ *
* C& x = provider.get<C&>();
*/
template <typename T>
explicit operator T();
-
+
/**
* This is equivalent to get<C*>(), it's provided for convenience.
*/
@@ -133,11 +137,11 @@
// This is never nullptr.
fruit::impl::InjectorStorage* storage;
fruit::impl::InjectorStorage::Graph::node_iterator itr;
-
+
Provider(fruit::impl::InjectorStorage* storage, fruit::impl::InjectorStorage::Graph::node_iterator itr);
-
+
friend class fruit::impl::InjectorStorage;
-
+
template <typename T>
friend struct fruit::impl::GetFirstStage;
diff --git a/src/binding_normalization.cpp b/src/binding_normalization.cpp
index c618697..5ffe8ef 100644
--- a/src/binding_normalization.cpp
+++ b/src/binding_normalization.cpp
@@ -4,9 +4,9 @@
* 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.
@@ -16,18 +16,18 @@
#define IN_FRUIT_CPP_FILE
+#include <algorithm>
#include <cstdlib>
+#include <fruit/impl/util/type_info.h>
+#include <iostream>
#include <memory>
#include <vector>
-#include <iostream>
-#include <algorithm>
-#include <fruit/impl/util/type_info.h>
-#include <fruit/impl/injector/injector_storage.h>
#include <fruit/impl/data_structures/semistatic_graph.templates.h>
-#include <fruit/impl/normalized_component_storage/normalized_component_storage.h>
+#include <fruit/impl/injector/injector_storage.h>
#include <fruit/impl/normalized_component_storage/binding_normalization.h>
#include <fruit/impl/normalized_component_storage/binding_normalization.templates.h>
+#include <fruit/impl/normalized_component_storage/normalized_component_storage.h>
using std::cout;
using std::endl;
@@ -45,18 +45,18 @@
for (const ComponentStorageEntry& entry : entries_to_process) {
switch (entry.kind) {
case ComponentStorageEntry::Kind::COMPONENT_WITH_ARGS_END_MARKER:
- if (entry.type_id == last_entry.type_id
- && last_entry.kind == ComponentStorageEntry::Kind::LAZY_COMPONENT_WITH_ARGS
- && *entry.lazy_component_with_args.component == *last_entry.lazy_component_with_args.component) {
+ if (entry.type_id == last_entry.type_id &&
+ last_entry.kind == ComponentStorageEntry::Kind::LAZY_COMPONENT_WITH_ARGS &&
+ *entry.lazy_component_with_args.component == *last_entry.lazy_component_with_args.component) {
std::cerr << "<-- The loop starts here" << std::endl;
}
std::cerr << std::string(entry.lazy_component_with_args.component->getFunTypeId()) << std::endl;
break;
case ComponentStorageEntry::Kind::COMPONENT_WITHOUT_ARGS_END_MARKER:
- if (entry.type_id == last_entry.type_id
- && last_entry.kind == ComponentStorageEntry::Kind::LAZY_COMPONENT_WITH_NO_ARGS
- && entry.lazy_component_with_no_args.erased_fun == last_entry.lazy_component_with_no_args.erased_fun) {
+ if (entry.type_id == last_entry.type_id &&
+ last_entry.kind == ComponentStorageEntry::Kind::LAZY_COMPONENT_WITH_NO_ARGS &&
+ entry.lazy_component_with_no_args.erased_fun == last_entry.lazy_component_with_no_args.erased_fun) {
std::cerr << "<-- The loop starts here" << std::endl;
}
std::cerr << std::string(entry.type_id) << std::endl;
@@ -97,10 +97,9 @@
}
void BindingNormalization::printIncompatibleComponentReplacementsError(
- const ComponentStorageEntry& replaced_component_entry,
- const ComponentStorageEntry& replacement_component_entry1,
+ const ComponentStorageEntry& replaced_component_entry, const ComponentStorageEntry& replacement_component_entry1,
const ComponentStorageEntry& replacement_component_entry2) {
- using fun_t = void(*)();
+ using fun_t = void (*)();
fun_t replaced_fun_address;
switch (replaced_component_entry.kind) {
@@ -146,30 +145,26 @@
constexpr static bool function_pointers_have_same_size = sizeof(void*) == sizeof(fun_t);
if (function_pointers_have_same_size) {
- std::cerr << "Fatal injection error: the component function at "
- << reinterpret_cast<void*>(replaced_fun_address)
+ std::cerr << "Fatal injection error: the component function at " << reinterpret_cast<void*>(replaced_fun_address)
<< " with signature " << std::string(replaced_component_entry.type_id)
<< " was replaced (using .replace(...).with(...)) with both the component function at "
- << reinterpret_cast<void *>(replacement_fun_address1) << " with signature "
- << std::string(replacement_component_entry1.type_id)
- << " and the component function at " << reinterpret_cast<void *>(replacement_fun_address2)
- << " with signature "
+ << reinterpret_cast<void*>(replacement_fun_address1) << " with signature "
+ << std::string(replacement_component_entry1.type_id) << " and the component function at "
+ << reinterpret_cast<void*>(replacement_fun_address2) << " with signature "
<< std::string(replacement_component_entry2.type_id) << " ." << std::endl;
} else {
std::cerr << "Fatal injection error: a component function with signature "
<< std::string(replaced_component_entry.type_id)
<< " was replaced (using .replace(...).with(...)) with both a component function with signature "
- << std::string(replacement_component_entry1.type_id)
- << " and another component function with signature "
+ << std::string(replacement_component_entry1.type_id) << " and another component function with signature "
<< std::string(replacement_component_entry2.type_id) << " ." << std::endl;
}
exit(1);
}
void BindingNormalization::printComponentReplacementFailedBecauseTargetAlreadyExpanded(
- const ComponentStorageEntry& replaced_component_entry,
- const ComponentStorageEntry& replacement_component_entry) {
- using fun_t = void(*)();
+ const ComponentStorageEntry& replaced_component_entry, const ComponentStorageEntry& replacement_component_entry) {
+ using fun_t = void (*)();
fun_t replaced_fun_address;
switch (replaced_component_entry.kind) {
@@ -202,9 +197,8 @@
constexpr static bool function_pointers_have_same_size = sizeof(void*) == sizeof(fun_t);
if (function_pointers_have_same_size) {
std::cerr << "Fatal injection error: unable to replace (using .replace(...).with(...)) the component function at "
- << reinterpret_cast<void*>(replaced_fun_address)
- << " with signature " << std::string(replaced_component_entry.type_id)
- << " with the component function at "
+ << reinterpret_cast<void*>(replaced_fun_address) << " with signature "
+ << std::string(replaced_component_entry.type_id) << " with the component function at "
<< reinterpret_cast<void*>(replacement_fun_address1) << " with signature "
<< std::string(replacement_component_entry.type_id)
<< " because the former component function was installed before the .replace(...).with(...)." << std::endl
@@ -219,11 +213,9 @@
<< "processed before the installation of the component to replace.";
}
exit(1);
-
}
-void BindingNormalization::addMultibindings(std::unordered_map<TypeId, NormalizedMultibindingSet>&
- multibindings,
+void BindingNormalization::addMultibindings(std::unordered_map<TypeId, NormalizedMultibindingSet>& multibindings,
FixedSizeAllocator::FixedSizeAllocatorData& fixed_size_allocator_data,
const multibindings_vector_t& multibindingsVector) {
@@ -234,10 +226,11 @@
for (auto i = multibindingsVector.begin(); i != multibindingsVector.end(); ++i) {
const ComponentStorageEntry& multibinding_entry = i->first;
const ComponentStorageEntry& multibinding_vector_creator_entry = i->second;
- FruitAssert(
- multibinding_entry.kind == ComponentStorageEntry::Kind::MULTIBINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION
- || multibinding_entry.kind == ComponentStorageEntry::Kind::MULTIBINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_ALLOCATION
- || multibinding_entry.kind == ComponentStorageEntry::Kind::MULTIBINDING_FOR_CONSTRUCTED_OBJECT);
+ FruitAssert(multibinding_entry.kind ==
+ ComponentStorageEntry::Kind::MULTIBINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION ||
+ multibinding_entry.kind ==
+ ComponentStorageEntry::Kind::MULTIBINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_ALLOCATION ||
+ multibinding_entry.kind == ComponentStorageEntry::Kind::MULTIBINDING_FOR_CONSTRUCTED_OBJECT);
FruitAssert(multibinding_vector_creator_entry.kind == ComponentStorageEntry::Kind::MULTIBINDING_VECTOR_CREATOR);
NormalizedMultibindingSet& b = multibindings[multibinding_entry.type_id];
@@ -245,34 +238,28 @@
b.get_multibindings_vector = multibinding_vector_creator_entry.multibinding_vector_creator.get_multibindings_vector;
switch (i->first.kind) { // LCOV_EXCL_BR_LINE
- case ComponentStorageEntry::Kind::MULTIBINDING_FOR_CONSTRUCTED_OBJECT:
- {
- NormalizedMultibinding normalized_multibinding;
- normalized_multibinding.is_constructed = true;
- normalized_multibinding.object = i->first.multibinding_for_constructed_object.object_ptr;
- b.elems.push_back(std::move(normalized_multibinding));
- }
- break;
+ case ComponentStorageEntry::Kind::MULTIBINDING_FOR_CONSTRUCTED_OBJECT: {
+ NormalizedMultibinding normalized_multibinding;
+ normalized_multibinding.is_constructed = true;
+ normalized_multibinding.object = i->first.multibinding_for_constructed_object.object_ptr;
+ b.elems.push_back(std::move(normalized_multibinding));
+ } break;
- case ComponentStorageEntry::Kind::MULTIBINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION:
- {
- fixed_size_allocator_data.addExternallyAllocatedType(i->first.type_id);
- NormalizedMultibinding normalized_multibinding;
- normalized_multibinding.is_constructed = false;
- normalized_multibinding.create = i->first.multibinding_for_object_to_construct.create;
- b.elems.push_back(std::move(normalized_multibinding));
- }
- break;
+ case ComponentStorageEntry::Kind::MULTIBINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION: {
+ fixed_size_allocator_data.addExternallyAllocatedType(i->first.type_id);
+ NormalizedMultibinding normalized_multibinding;
+ normalized_multibinding.is_constructed = false;
+ normalized_multibinding.create = i->first.multibinding_for_object_to_construct.create;
+ b.elems.push_back(std::move(normalized_multibinding));
+ } break;
- case ComponentStorageEntry::Kind::MULTIBINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_ALLOCATION:
- {
- fixed_size_allocator_data.addType(i->first.type_id);
- NormalizedMultibinding normalized_multibinding;
- normalized_multibinding.is_constructed = false;
- normalized_multibinding.create = i->first.multibinding_for_object_to_construct.create;
- b.elems.push_back(std::move(normalized_multibinding));
- }
- break;
+ case ComponentStorageEntry::Kind::MULTIBINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_ALLOCATION: {
+ fixed_size_allocator_data.addType(i->first.type_id);
+ NormalizedMultibinding normalized_multibinding;
+ normalized_multibinding.is_constructed = false;
+ normalized_multibinding.create = i->first.multibinding_for_object_to_construct.create;
+ b.elems.push_back(std::move(normalized_multibinding));
+ } break;
default:
#ifdef FRUIT_EXTRA_DEBUG
@@ -285,10 +272,8 @@
void BindingNormalization::normalizeBindingsWithUndoableBindingCompression(
FixedSizeVector<ComponentStorageEntry>&& toplevel_entries,
- FixedSizeAllocator::FixedSizeAllocatorData& fixed_size_allocator_data,
- MemoryPool& memory_pool,
- MemoryPool& memory_pool_for_fully_expanded_components_maps,
- MemoryPool& memory_pool_for_component_replacements_maps,
+ FixedSizeAllocator::FixedSizeAllocatorData& fixed_size_allocator_data, MemoryPool& memory_pool,
+ MemoryPool& memory_pool_for_fully_expanded_components_maps, MemoryPool& memory_pool_for_component_replacements_maps,
const std::vector<TypeId, ArenaAllocator<TypeId>>& exposed_types,
std::vector<ComponentStorageEntry, ArenaAllocator<ComponentStorageEntry>>& bindings_vector,
std::unordered_map<TypeId, NormalizedMultibindingSet>& multibindings,
@@ -301,17 +286,10 @@
FruitAssert(bindingCompressionInfoMap.empty());
normalizeBindingsWithBindingCompression(
- std::move(toplevel_entries),
- fixed_size_allocator_data,
- memory_pool,
- memory_pool_for_fully_expanded_components_maps,
- memory_pool_for_component_replacements_maps,
- exposed_types,
- bindings_vector,
- multibindings,
- [&bindingCompressionInfoMap](
- TypeId c_type_id,
- NormalizedComponentStorage::CompressedBindingUndoInfo undo_info) {
+ std::move(toplevel_entries), fixed_size_allocator_data, memory_pool,
+ memory_pool_for_fully_expanded_components_maps, memory_pool_for_component_replacements_maps, exposed_types,
+ bindings_vector, multibindings,
+ [&bindingCompressionInfoMap](TypeId c_type_id, NormalizedComponentStorage::CompressedBindingUndoInfo undo_info) {
bindingCompressionInfoMap[c_type_id] = undo_info;
},
[&fully_expanded_components_with_no_args](LazyComponentWithNoArgsSet& fully_expanded_components) {
@@ -322,11 +300,11 @@
fully_expanded_components_with_args = std::move(fully_expanded_components);
fully_expanded_components.clear();
},
- [&component_with_no_args_replacements](LazyComponentWithNoArgsReplacementMap & component_replacements) {
+ [&component_with_no_args_replacements](LazyComponentWithNoArgsReplacementMap& component_replacements) {
component_with_no_args_replacements = std::move(component_replacements);
component_replacements.clear();
},
- [&component_with_args_replacements](LazyComponentWithArgsReplacementMap & component_replacements) {
+ [&component_with_args_replacements](LazyComponentWithArgsReplacementMap& component_replacements) {
component_with_args_replacements = std::move(component_replacements);
component_replacements.clear();
});
@@ -334,30 +312,19 @@
void BindingNormalization::normalizeBindingsWithPermanentBindingCompression(
FixedSizeVector<ComponentStorageEntry>&& toplevel_entries,
- FixedSizeAllocator::FixedSizeAllocatorData& fixed_size_allocator_data,
- MemoryPool& memory_pool,
+ FixedSizeAllocator::FixedSizeAllocatorData& fixed_size_allocator_data, MemoryPool& memory_pool,
const std::vector<TypeId, ArenaAllocator<TypeId>>& exposed_types,
std::vector<ComponentStorageEntry, ArenaAllocator<ComponentStorageEntry>>& bindings_vector,
std::unordered_map<TypeId, NormalizedMultibindingSet>& multibindings) {
normalizeBindingsWithBindingCompression(
- std::move(toplevel_entries),
- fixed_size_allocator_data,
- memory_pool,
- memory_pool,
- memory_pool,
- exposed_types,
- bindings_vector,
- multibindings,
- [](TypeId, NormalizedComponentStorage::CompressedBindingUndoInfo) {},
- [](LazyComponentWithNoArgsSet&) {},
- [](LazyComponentWithArgsSet&) {},
- [](LazyComponentWithNoArgsReplacementMap&) {},
- [](LazyComponentWithArgsReplacementMap&) {});
+ std::move(toplevel_entries), fixed_size_allocator_data, memory_pool, memory_pool, memory_pool, exposed_types,
+ bindings_vector, multibindings, [](TypeId, NormalizedComponentStorage::CompressedBindingUndoInfo) {},
+ [](LazyComponentWithNoArgsSet&) {}, [](LazyComponentWithArgsSet&) {},
+ [](LazyComponentWithNoArgsReplacementMap&) {}, [](LazyComponentWithArgsReplacementMap&) {});
}
void BindingNormalization::normalizeBindingsAndAddTo(
- FixedSizeVector<ComponentStorageEntry>&& toplevel_entries,
- MemoryPool& memory_pool,
+ FixedSizeVector<ComponentStorageEntry>&& toplevel_entries, MemoryPool& memory_pool,
const NormalizedComponentStorage& base_normalized_component,
FixedSizeAllocator::FixedSizeAllocatorData& fixed_size_allocator_data,
std::vector<ComponentStorageEntry, ArenaAllocator<ComponentStorageEntry>>& new_bindings_vector,
@@ -371,46 +338,30 @@
multibindings_vector_t(ArenaAllocator<multibindings_vector_elem_t>(memory_pool));
HashMapWithArenaAllocator<TypeId, ComponentStorageEntry> binding_data_map =
- createHashMapWithArenaAllocator<TypeId, ComponentStorageEntry>(
- 20 /* capacity */, memory_pool);
+ createHashMapWithArenaAllocator<TypeId, ComponentStorageEntry>(20 /* capacity */, memory_pool);
using Graph = NormalizedComponentStorage::Graph;
normalizeBindings(
- std::move(toplevel_entries),
- fixed_size_allocator_data,
- memory_pool,
- memory_pool,
- memory_pool,
- binding_data_map,
+ std::move(toplevel_entries), fixed_size_allocator_data, memory_pool, memory_pool, memory_pool, binding_data_map,
[](ComponentStorageEntry) {},
- [&multibindings_vector](ComponentStorageEntry multibinding,
- ComponentStorageEntry multibinding_vector_creator) {
+ [&multibindings_vector](ComponentStorageEntry multibinding, ComponentStorageEntry multibinding_vector_creator) {
multibindings_vector.emplace_back(multibinding, multibinding_vector_creator);
},
- [&base_normalized_component](TypeId type_id) {
- return base_normalized_component.bindings.find(type_id);
- },
+ [&base_normalized_component](TypeId type_id) { return base_normalized_component.bindings.find(type_id); },
[&base_normalized_component](Graph::const_node_iterator itr) {
return !(itr == base_normalized_component.bindings.end());
},
- [](Graph::const_node_iterator itr) {
- return itr.isTerminal();
- },
- [](Graph::const_node_iterator itr) {
- return itr.getNode().object;
- },
- [](Graph::const_node_iterator itr) {
- return itr.getNode().create;
- },
+ [](Graph::const_node_iterator itr) { return itr.isTerminal(); },
+ [](Graph::const_node_iterator itr) { return itr.getNode().object; },
+ [](Graph::const_node_iterator itr) { return itr.getNode().create; },
[&base_normalized_component](const LazyComponentWithNoArgs& lazy_component) {
return base_normalized_component.fully_expanded_components_with_no_args.count(lazy_component) != 0;
},
[&base_normalized_component](const LazyComponentWithArgs& lazy_component) {
return base_normalized_component.fully_expanded_components_with_args.count(lazy_component) != 0;
},
- [](LazyComponentWithNoArgsSet&) {},
- [](LazyComponentWithArgsSet&) {},
+ [](LazyComponentWithNoArgsSet&) {}, [](LazyComponentWithArgsSet&) {},
[&base_normalized_component](const LazyComponentWithNoArgs& lazy_component) {
return base_normalized_component.component_with_no_args_replacements.find(lazy_component);
},
@@ -423,14 +374,9 @@
[&base_normalized_component](typename LazyComponentWithArgsReplacementMap::const_iterator itr) {
return itr != base_normalized_component.component_with_args_replacements.end();
},
- [](typename LazyComponentWithNoArgsReplacementMap::const_iterator itr) {
- return itr->second;
- },
- [](typename LazyComponentWithArgsReplacementMap::const_iterator itr) {
- return itr->second;
- },
- [](LazyComponentWithNoArgsReplacementMap&) {},
- [](LazyComponentWithArgsReplacementMap&) {});
+ [](typename LazyComponentWithNoArgsReplacementMap::const_iterator itr) { return itr->second; },
+ [](typename LazyComponentWithArgsReplacementMap::const_iterator itr) { return itr->second; },
+ [](LazyComponentWithNoArgsReplacementMap&) {}, [](LazyComponentWithArgsReplacementMap&) {});
// Copy the normalized bindings into the result vector.
new_bindings_vector.clear();
@@ -442,8 +388,7 @@
// Determine what binding compressions must be undone.
HashSetWithArenaAllocator<TypeId> binding_compressions_to_undo =
- createHashSetWithArenaAllocator<TypeId>(
- 20 /* capacity */, memory_pool);
+ createHashSetWithArenaAllocator<TypeId>(20 /* capacity */, memory_pool);
for (const ComponentStorageEntry& entry : new_bindings_vector) {
switch (entry.kind) { // LCOV_EXCL_BR_LINE
case ComponentStorageEntry::Kind::BINDING_FOR_CONSTRUCTED_OBJECT:
@@ -451,21 +396,18 @@
case ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION:
case ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_ALLOCATION:
- case ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_WITH_UNKNOWN_ALLOCATION:
- {
- const BindingDeps *entry_deps = entry.binding_for_object_to_construct.deps;
- for (std::size_t i = 0; i < entry_deps->num_deps; ++i) {
- auto binding_compression_itr =
- base_normalized_component.binding_compression_info_map.find(entry_deps->deps[i]);
- if (binding_compression_itr != base_normalized_component.binding_compression_info_map.end()
- && binding_compression_itr->second.i_type_id != entry.type_id) {
- // The binding compression for `p.second.getDeps()->deps[i]' must be undone because something
- // different from binding_compression_itr->iTypeId is now bound to it.
- binding_compressions_to_undo.insert(entry_deps->deps[i]);
- }
+ case ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_WITH_UNKNOWN_ALLOCATION: {
+ const BindingDeps* entry_deps = entry.binding_for_object_to_construct.deps;
+ for (std::size_t i = 0; i < entry_deps->num_deps; ++i) {
+ auto binding_compression_itr = base_normalized_component.binding_compression_info_map.find(entry_deps->deps[i]);
+ if (binding_compression_itr != base_normalized_component.binding_compression_info_map.end() &&
+ binding_compression_itr->second.i_type_id != entry.type_id) {
+ // The binding compression for `p.second.getDeps()->deps[i]' must be undone because something
+ // different from binding_compression_itr->iTypeId is now bound to it.
+ binding_compressions_to_undo.insert(entry_deps->deps[i]);
}
}
- break;
+ } break;
default:
#ifdef FRUIT_EXTRA_DEBUG
@@ -480,7 +422,8 @@
for (TypeId cTypeId : binding_compressions_to_undo) {
auto binding_compression_itr = base_normalized_component.binding_compression_info_map.find(cTypeId);
FruitAssert(binding_compression_itr != base_normalized_component.binding_compression_info_map.end());
- FruitAssert(!(base_normalized_component.bindings.find(binding_compression_itr->second.i_type_id) == base_normalized_component.bindings.end()));
+ FruitAssert(!(base_normalized_component.bindings.find(binding_compression_itr->second.i_type_id) ==
+ base_normalized_component.bindings.end()));
ComponentStorageEntry c_binding;
c_binding.type_id = cTypeId;
@@ -497,7 +440,8 @@
new_bindings_vector.push_back(std::move(i_binding));
#ifdef FRUIT_EXTRA_DEBUG
- std::cout << "InjectorStorage: undoing binding compression for: " << binding_compression_itr->second.i_type_id << "->" << cTypeId << std::endl;
+ std::cout << "InjectorStorage: undoing binding compression for: " << binding_compression_itr->second.i_type_id
+ << "->" << cTypeId << std::endl;
#endif
}
@@ -506,16 +450,14 @@
}
void BindingNormalization::handlePreexistingLazyComponentWithArgsReplacement(
- ComponentStorageEntry& replaced_component_entry,
- const ComponentStorageEntry& preexisting_replacement,
+ ComponentStorageEntry& replaced_component_entry, const ComponentStorageEntry& preexisting_replacement,
ComponentStorageEntry& new_replacement) {
switch (new_replacement.kind) { // LCOV_EXCL_BR_LINE
case ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_NO_ARGS:
- if (preexisting_replacement.kind != ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_NO_ARGS
- || preexisting_replacement.lazy_component_with_no_args.erased_fun
- != new_replacement.lazy_component_with_no_args.erased_fun) {
- printIncompatibleComponentReplacementsError(
- replaced_component_entry, new_replacement, preexisting_replacement);
+ if (preexisting_replacement.kind != ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_NO_ARGS ||
+ preexisting_replacement.lazy_component_with_no_args.erased_fun !=
+ new_replacement.lazy_component_with_no_args.erased_fun) {
+ printIncompatibleComponentReplacementsError(replaced_component_entry, new_replacement, preexisting_replacement);
FRUIT_UNREACHABLE; // LCOV_EXCL_LINE
}
@@ -524,11 +466,10 @@
break;
case ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_ARGS:
- if (preexisting_replacement.kind != ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_ARGS
- || !(*preexisting_replacement.lazy_component_with_args.component
- == *new_replacement.lazy_component_with_args.component)) {
- printIncompatibleComponentReplacementsError(
- replaced_component_entry, new_replacement, preexisting_replacement);
+ if (preexisting_replacement.kind != ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_ARGS ||
+ !(*preexisting_replacement.lazy_component_with_args.component ==
+ *new_replacement.lazy_component_with_args.component)) {
+ printIncompatibleComponentReplacementsError(replaced_component_entry, new_replacement, preexisting_replacement);
FRUIT_UNREACHABLE; // LCOV_EXCL_LINE
}
@@ -543,17 +484,14 @@
}
void BindingNormalization::handlePreexistingLazyComponentWithNoArgsReplacement(
- ComponentStorageEntry& replaced_component_entry,
- const ComponentStorageEntry& preexisting_replacement,
+ ComponentStorageEntry& replaced_component_entry, const ComponentStorageEntry& preexisting_replacement,
ComponentStorageEntry& new_replacement) {
switch (new_replacement.kind) { // LCOV_EXCL_BR_LINE
case ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_NO_ARGS:
- if (preexisting_replacement.kind
- != ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_NO_ARGS
- || preexisting_replacement.lazy_component_with_no_args.erased_fun
- != new_replacement.lazy_component_with_no_args.erased_fun) {
- printIncompatibleComponentReplacementsError(
- replaced_component_entry, new_replacement, preexisting_replacement);
+ if (preexisting_replacement.kind != ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_NO_ARGS ||
+ preexisting_replacement.lazy_component_with_no_args.erased_fun !=
+ new_replacement.lazy_component_with_no_args.erased_fun) {
+ printIncompatibleComponentReplacementsError(replaced_component_entry, new_replacement, preexisting_replacement);
FRUIT_UNREACHABLE; // LCOV_EXCL_LINE
}
@@ -561,11 +499,10 @@
break;
case ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_ARGS:
- if (new_replacement.kind != ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_ARGS
- || !(*preexisting_replacement.lazy_component_with_args.component
- == *new_replacement.lazy_component_with_args.component)) {
- printIncompatibleComponentReplacementsError(
- replaced_component_entry, new_replacement, preexisting_replacement);
+ if (new_replacement.kind != ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_ARGS ||
+ !(*preexisting_replacement.lazy_component_with_args.component ==
+ *new_replacement.lazy_component_with_args.component)) {
+ printIncompatibleComponentReplacementsError(replaced_component_entry, new_replacement, preexisting_replacement);
FRUIT_UNREACHABLE; // LCOV_EXCL_LINE
}
diff --git a/src/component.cpp b/src/component.cpp
index 0daf202..69e971b 100644
--- a/src/component.cpp
+++ b/src/component.cpp
@@ -4,9 +4,9 @@
* 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.
@@ -18,22 +18,27 @@
#include <fruit/component.h>
-#include <iostream>
#include <exception>
+#include <iostream>
namespace fruit {
// TODO: reimplement this check somehow.
/*
EmptyPartialComponent::~EmptyPartialComponent() {
- // If the user of Fruit didn't cast the result of createComponent() (possibly after adding some bindings) to a Component<>, we abort
- // because that's a misuse of the Fruit API. If we went ahead, there might be some PartialComponent<> instances that point
+ // If the user of Fruit didn't cast the result of createComponent() (possibly after adding some bindings) to a
+Component<>, we abort
+ // because that's a misuse of the Fruit API. If we went ahead, there might be some PartialComponent<> instances that
+point
// to the ComponentStorage in this EmptyComponent, and any use of those would cause undefined behavior.
- // If an exception is in flight, don't abort; that's likely to be an unexpected flow so we don't want to alert the user of Fruit,
+ // If an exception is in flight, don't abort; that's likely to be an unexpected flow so we don't want to alert the
+user of Fruit,
// and there can't be any leftover instances of PartialComponent<> referring to this EmptyComponent anyway.
if (!already_converted_to_component && !std::uncaught_exception()) {
- std::cerr << "The result of fruit::createComponent() was not converted to a Component before the end of the expression! "
- << "This is a misuse of the Fruit API. This is likely to cause undefined behavior, aborting now to be safe." << std::endl;
+ std::cerr << "The result of fruit::createComponent() was not converted to a Component before the end of the
+expression! "
+ << "This is a misuse of the Fruit API. This is likely to cause undefined behavior, aborting now to be safe." <<
+std::endl;
std::abort();
}
}
diff --git a/src/demangle_type_name.cpp b/src/demangle_type_name.cpp
index a760bbe..d0a72dc 100644
--- a/src/demangle_type_name.cpp
+++ b/src/demangle_type_name.cpp
@@ -4,9 +4,9 @@
* 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.
@@ -21,14 +21,14 @@
#if FRUIT_HAS_CXA_DEMANGLE
-#include <string>
-#include <cxxabi.h>
#include <cstdlib>
+#include <cxxabi.h>
+#include <string>
std::string demangleTypeName(const char* name) {
int status;
std::string result;
- char *demangled_name = abi::__cxa_demangle(name, nullptr, nullptr, &status);
+ char* demangled_name = abi::__cxa_demangle(name, nullptr, nullptr, &status);
if (status == 0) { // LCOV_EXCL_BR_LINE
result = demangled_name;
std::free(demangled_name);
diff --git a/src/fixed_size_allocator.cpp b/src/fixed_size_allocator.cpp
index be27d34..e1a89ab 100644
--- a/src/fixed_size_allocator.cpp
+++ b/src/fixed_size_allocator.cpp
@@ -4,9 +4,9 @@
* 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.
@@ -31,7 +31,7 @@
--p;
p->first(p->second);
}
- delete [] storage_begin;
+ delete[] storage_begin;
}
} // namespace impl
diff --git a/src/injector_storage.cpp b/src/injector_storage.cpp
index 98c769b..ae39942 100644
--- a/src/injector_storage.cpp
+++ b/src/injector_storage.cpp
@@ -4,9 +4,9 @@
* 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.
@@ -16,17 +16,17 @@
#define IN_FRUIT_CPP_FILE
+#include <algorithm>
#include <cstdlib>
+#include <fruit/impl/util/type_info.h>
+#include <iostream>
#include <memory>
#include <vector>
-#include <iostream>
-#include <algorithm>
-#include <fruit/impl/util/type_info.h>
-#include <fruit/impl/injector/injector_storage.h>
-#include <fruit/impl/data_structures/semistatic_graph.templates.h>
-#include <fruit/impl/normalized_component_storage/binding_normalization.h>
#include <fruit/impl/component_storage/component_storage.h>
+#include <fruit/impl/data_structures/semistatic_graph.templates.h>
+#include <fruit/impl/injector/injector_storage.h>
+#include <fruit/impl/normalized_component_storage/binding_normalization.h>
#include <fruit/impl/normalized_component_storage/binding_normalization.templates.h>
using std::cout;
@@ -44,82 +44,64 @@
// LCOV_EXCL_START
namespace {
- template <typename Id, typename Value>
- struct DummyNode {
- Id getId() {
- return Id();
- }
- bool isTerminal() {
- return false;
- }
- Id* getEdgesBegin() {
- return nullptr;
- }
- Id* getEdgesEnd() {
- return nullptr;
- }
- Value getValue() {
- return Value();
- }
- };
+template <typename Id, typename Value>
+struct DummyNode {
+ Id getId() {
+ return Id();
+ }
+ bool isTerminal() {
+ return false;
+ }
+ Id* getEdgesBegin() {
+ return nullptr;
+ }
+ Id* getEdgesEnd() {
+ return nullptr;
+ }
+ Value getValue() {
+ return Value();
+ }
+};
}
// LCOV_EXCL_STOP
-InjectorStorage::InjectorStorage(
- ComponentStorage&& component,
- const std::vector<TypeId, ArenaAllocator<TypeId>>& exposed_types,
- MemoryPool& memory_pool)
- : normalized_component_storage_ptr(
- new NormalizedComponentStorage(
- std::move(component),
- exposed_types,
- memory_pool,
- NormalizedComponentStorage::WithPermanentCompression())),
- allocator(normalized_component_storage_ptr->fixed_size_allocator_data),
- bindings(normalized_component_storage_ptr->bindings,
- (DummyNode<TypeId, NormalizedBinding>*)nullptr,
- (DummyNode<TypeId, NormalizedBinding>*)nullptr,
- memory_pool),
- multibindings(std::move(normalized_component_storage_ptr->multibindings)) {
+InjectorStorage::InjectorStorage(ComponentStorage&& component,
+ const std::vector<TypeId, ArenaAllocator<TypeId>>& exposed_types,
+ MemoryPool& memory_pool)
+ : normalized_component_storage_ptr(new NormalizedComponentStorage(
+ std::move(component), exposed_types, memory_pool, NormalizedComponentStorage::WithPermanentCompression())),
+ allocator(normalized_component_storage_ptr->fixed_size_allocator_data),
+ bindings(normalized_component_storage_ptr->bindings, (DummyNode<TypeId, NormalizedBinding>*)nullptr,
+ (DummyNode<TypeId, NormalizedBinding>*)nullptr, memory_pool),
+ multibindings(std::move(normalized_component_storage_ptr->multibindings)) {
#ifdef FRUIT_EXTRA_DEBUG
bindings.checkFullyConstructed();
#endif
}
-InjectorStorage::InjectorStorage(const NormalizedComponentStorage& normalized_component,
- ComponentStorage&& component,
+InjectorStorage::InjectorStorage(const NormalizedComponentStorage& normalized_component, ComponentStorage&& component,
MemoryPool& memory_pool) {
FixedSizeAllocator::FixedSizeAllocatorData fixed_size_allocator_data;
using new_bindings_vector_t = std::vector<ComponentStorageEntry, ArenaAllocator<ComponentStorageEntry>>;
- new_bindings_vector_t new_bindings_vector =
- new_bindings_vector_t(ArenaAllocator<ComponentStorageEntry>(memory_pool));
+ new_bindings_vector_t new_bindings_vector = new_bindings_vector_t(ArenaAllocator<ComponentStorageEntry>(memory_pool));
- BindingNormalization::normalizeBindingsAndAddTo(
- std::move(component).release(),
- memory_pool,
- normalized_component,
- fixed_size_allocator_data,
- new_bindings_vector,
- multibindings);
+ BindingNormalization::normalizeBindingsAndAddTo(std::move(component).release(), memory_pool, normalized_component,
+ fixed_size_allocator_data, new_bindings_vector, multibindings);
allocator = FixedSizeAllocator(fixed_size_allocator_data);
- bindings = Graph(normalized_component.bindings,
- BindingDataNodeIter{new_bindings_vector.begin()},
- BindingDataNodeIter{new_bindings_vector.end()},
- memory_pool);
+ bindings = Graph(normalized_component.bindings, BindingDataNodeIter{new_bindings_vector.begin()},
+ BindingDataNodeIter{new_bindings_vector.end()}, memory_pool);
#ifdef FRUIT_EXTRA_DEBUG
bindings.checkFullyConstructed();
#endif
}
-InjectorStorage::~InjectorStorage() {
-}
+InjectorStorage::~InjectorStorage() {}
-void InjectorStorage::ensureConstructedMultibinding(
- NormalizedMultibindingSet& multibinding_set) {
+void InjectorStorage::ensureConstructedMultibinding(NormalizedMultibindingSet& multibinding_set) {
for (NormalizedMultibinding& multibinding : multibinding_set.elems) {
if (!multibinding.is_constructed) {
multibinding.object = multibinding.create(*this);
diff --git a/src/memory_pool.cpp b/src/memory_pool.cpp
index 6653bab..c4105b2 100644
--- a/src/memory_pool.cpp
+++ b/src/memory_pool.cpp
@@ -4,9 +4,9 @@
* 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.
diff --git a/src/normalized_component_storage.cpp b/src/normalized_component_storage.cpp
index ff0c068..b483326 100644
--- a/src/normalized_component_storage.cpp
+++ b/src/normalized_component_storage.cpp
@@ -4,9 +4,9 @@
* 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.
@@ -16,20 +16,20 @@
#define IN_FRUIT_CPP_FILE
+#include <algorithm>
#include <cstdlib>
+#include <fruit/impl/util/type_info.h>
+#include <iostream>
#include <memory>
#include <vector>
-#include <iostream>
-#include <algorithm>
-#include <fruit/impl/util/type_info.h>
#include <fruit/impl/normalized_component_storage/normalized_component_storage.h>
-#include <fruit/impl/data_structures/semistatic_map.templates.h>
-#include <fruit/impl/data_structures/semistatic_graph.templates.h>
#include <fruit/impl/component_storage/component_storage.h>
-#include <fruit/impl/normalized_component_storage/binding_normalization.h>
+#include <fruit/impl/data_structures/semistatic_graph.templates.h>
+#include <fruit/impl/data_structures/semistatic_map.templates.h>
#include <fruit/impl/injector/injector_storage.h>
+#include <fruit/impl/normalized_component_storage/binding_normalization.h>
using std::cout;
using std::endl;
@@ -40,82 +40,53 @@
namespace fruit {
namespace impl {
-NormalizedComponentStorage::NormalizedComponentStorage(
- ComponentStorage&& component,
- const std::vector<TypeId, ArenaAllocator<TypeId>>& exposed_types,
- MemoryPool& memory_pool,
- WithPermanentCompression)
- : normalized_component_memory_pool(),
- binding_compression_info_map(
- createHashMapWithArenaAllocator<TypeId, CompressedBindingUndoInfo>(
- 0 /* capacity */, normalized_component_memory_pool)),
- fully_expanded_components_with_no_args(
- createLazyComponentWithNoArgsSet(
- 0 /* capacity */, normalized_component_memory_pool)),
- fully_expanded_components_with_args(
- createLazyComponentWithArgsSet(
- 0 /* capacity */, normalized_component_memory_pool)),
- component_with_no_args_replacements(
- createLazyComponentWithNoArgsReplacementMap(
- 0 /* capacity */, normalized_component_memory_pool)),
- component_with_args_replacements(
- createLazyComponentWithArgsReplacementMap(
- 0 /* capacity */, normalized_component_memory_pool)) {
+NormalizedComponentStorage::NormalizedComponentStorage(ComponentStorage&& component,
+ const std::vector<TypeId, ArenaAllocator<TypeId>>& exposed_types,
+ MemoryPool& memory_pool, WithPermanentCompression)
+ : normalized_component_memory_pool(),
+ binding_compression_info_map(createHashMapWithArenaAllocator<TypeId, CompressedBindingUndoInfo>(
+ 0 /* capacity */, normalized_component_memory_pool)),
+ fully_expanded_components_with_no_args(
+ createLazyComponentWithNoArgsSet(0 /* capacity */, normalized_component_memory_pool)),
+ fully_expanded_components_with_args(
+ createLazyComponentWithArgsSet(0 /* capacity */, normalized_component_memory_pool)),
+ component_with_no_args_replacements(
+ createLazyComponentWithNoArgsReplacementMap(0 /* capacity */, normalized_component_memory_pool)),
+ component_with_args_replacements(
+ createLazyComponentWithArgsReplacementMap(0 /* capacity */, normalized_component_memory_pool)) {
using bindings_vector_t = std::vector<ComponentStorageEntry, ArenaAllocator<ComponentStorageEntry>>;
- bindings_vector_t bindings_vector =
- bindings_vector_t(ArenaAllocator<ComponentStorageEntry>(memory_pool));
- BindingNormalization::normalizeBindingsWithPermanentBindingCompression(
- std::move(component).release(),
- fixed_size_allocator_data,
- memory_pool,
- exposed_types,
- bindings_vector,
- multibindings);
+ bindings_vector_t bindings_vector = bindings_vector_t(ArenaAllocator<ComponentStorageEntry>(memory_pool));
+ BindingNormalization::normalizeBindingsWithPermanentBindingCompression(std::move(component).release(),
+ fixed_size_allocator_data, memory_pool,
+ exposed_types, bindings_vector, multibindings);
bindings = SemistaticGraph<TypeId, NormalizedBinding>(InjectorStorage::BindingDataNodeIter{bindings_vector.begin()},
InjectorStorage::BindingDataNodeIter{bindings_vector.end()},
memory_pool);
}
-NormalizedComponentStorage::NormalizedComponentStorage(
- ComponentStorage&& component,
- const std::vector<TypeId, ArenaAllocator<TypeId>>& exposed_types,
- MemoryPool& memory_pool,
- WithUndoableCompression)
- : normalized_component_memory_pool(),
- binding_compression_info_map(
- createHashMapWithArenaAllocator<TypeId, CompressedBindingUndoInfo>(
- 20 /* capacity */, normalized_component_memory_pool)),
- fully_expanded_components_with_no_args(
- createLazyComponentWithNoArgsSet(
- 20 /* capacity */, normalized_component_memory_pool)),
- fully_expanded_components_with_args(
- createLazyComponentWithArgsSet(
- 20 /* capacity */, normalized_component_memory_pool)),
- component_with_no_args_replacements(
- createLazyComponentWithNoArgsReplacementMap(
- 20 /* capacity */, normalized_component_memory_pool)),
- component_with_args_replacements(
- createLazyComponentWithArgsReplacementMap(
- 20 /* capacity */, normalized_component_memory_pool)) {
+NormalizedComponentStorage::NormalizedComponentStorage(ComponentStorage&& component,
+ const std::vector<TypeId, ArenaAllocator<TypeId>>& exposed_types,
+ MemoryPool& memory_pool, WithUndoableCompression)
+ : normalized_component_memory_pool(),
+ binding_compression_info_map(createHashMapWithArenaAllocator<TypeId, CompressedBindingUndoInfo>(
+ 20 /* capacity */, normalized_component_memory_pool)),
+ fully_expanded_components_with_no_args(
+ createLazyComponentWithNoArgsSet(20 /* capacity */, normalized_component_memory_pool)),
+ fully_expanded_components_with_args(
+ createLazyComponentWithArgsSet(20 /* capacity */, normalized_component_memory_pool)),
+ component_with_no_args_replacements(
+ createLazyComponentWithNoArgsReplacementMap(20 /* capacity */, normalized_component_memory_pool)),
+ component_with_args_replacements(
+ createLazyComponentWithArgsReplacementMap(20 /* capacity */, normalized_component_memory_pool)) {
using bindings_vector_t = std::vector<ComponentStorageEntry, ArenaAllocator<ComponentStorageEntry>>;
- bindings_vector_t bindings_vector =
- bindings_vector_t(ArenaAllocator<ComponentStorageEntry>(memory_pool));
+ bindings_vector_t bindings_vector = bindings_vector_t(ArenaAllocator<ComponentStorageEntry>(memory_pool));
BindingNormalization::normalizeBindingsWithUndoableBindingCompression(
- std::move(component).release(),
- fixed_size_allocator_data,
- memory_pool,
- normalized_component_memory_pool,
- normalized_component_memory_pool,
- exposed_types,
- bindings_vector,
- multibindings,
- binding_compression_info_map,
- fully_expanded_components_with_no_args,
- fully_expanded_components_with_args,
- component_with_no_args_replacements,
+ std::move(component).release(), fixed_size_allocator_data, memory_pool, normalized_component_memory_pool,
+ normalized_component_memory_pool, exposed_types, bindings_vector, multibindings, binding_compression_info_map,
+ fully_expanded_components_with_no_args, fully_expanded_components_with_args, component_with_no_args_replacements,
component_with_args_replacements);
bindings = SemistaticGraph<TypeId, NormalizedBinding>(InjectorStorage::BindingDataNodeIter{bindings_vector.begin()},
@@ -141,21 +112,16 @@
}
// We must free all the memory in these before the normalized_component_memory_pool is destroyed.
- binding_compression_info_map =
- createHashMapWithArenaAllocator<TypeId, CompressedBindingUndoInfo>(
- 0 /* capacity */, normalized_component_memory_pool);
+ binding_compression_info_map = createHashMapWithArenaAllocator<TypeId, CompressedBindingUndoInfo>(
+ 0 /* capacity */, normalized_component_memory_pool);
fully_expanded_components_with_no_args =
- createLazyComponentWithNoArgsSet(
- 0 /* capacity */, normalized_component_memory_pool);
+ createLazyComponentWithNoArgsSet(0 /* capacity */, normalized_component_memory_pool);
fully_expanded_components_with_args =
- createLazyComponentWithArgsSet(
- 0 /* capacity */, normalized_component_memory_pool);
+ createLazyComponentWithArgsSet(0 /* capacity */, normalized_component_memory_pool);
component_with_no_args_replacements =
- createLazyComponentWithNoArgsReplacementMap(
- 0 /* capacity */, normalized_component_memory_pool);
+ createLazyComponentWithNoArgsReplacementMap(0 /* capacity */, normalized_component_memory_pool);
component_with_args_replacements =
- createLazyComponentWithArgsReplacementMap(
- 0 /* capacity */, normalized_component_memory_pool);
+ createLazyComponentWithArgsReplacementMap(0 /* capacity */, normalized_component_memory_pool);
}
} // namespace impl
diff --git a/src/normalized_component_storage_holder.cpp b/src/normalized_component_storage_holder.cpp
index e3d8177..b138ebd 100644
--- a/src/normalized_component_storage_holder.cpp
+++ b/src/normalized_component_storage_holder.cpp
@@ -4,9 +4,9 @@
* 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.
@@ -16,8 +16,8 @@
#define IN_FRUIT_CPP_FILE
-#include <fruit/impl/normalized_component_storage/normalized_component_storage_holder.h>
#include <fruit/impl/normalized_component_storage/normalized_component_storage.h>
+#include <fruit/impl/normalized_component_storage/normalized_component_storage_holder.h>
using namespace fruit;
using namespace fruit::impl;
@@ -26,20 +26,12 @@
namespace impl {
NormalizedComponentStorageHolder::NormalizedComponentStorageHolder(
- ComponentStorage&& component,
- const std::vector<TypeId, ArenaAllocator<TypeId>>& exposed_types,
- MemoryPool& memory_pool,
- WithUndoableCompression)
- : storage(
- new NormalizedComponentStorage(
- std::move(component),
- exposed_types,
- memory_pool,
- NormalizedComponentStorage::WithUndoableCompression())) {
-}
+ ComponentStorage&& component, const std::vector<TypeId, ArenaAllocator<TypeId>>& exposed_types,
+ MemoryPool& memory_pool, WithUndoableCompression)
+ : storage(new NormalizedComponentStorage(std::move(component), exposed_types, memory_pool,
+ NormalizedComponentStorage::WithUndoableCompression())) {}
-NormalizedComponentStorageHolder::~NormalizedComponentStorageHolder() {
-}
+NormalizedComponentStorageHolder::~NormalizedComponentStorageHolder() {}
} // namespace impl
} // namespace fruit
diff --git a/src/semistatic_graph.cpp b/src/semistatic_graph.cpp
index 92a6206..c018bbd 100644
--- a/src/semistatic_graph.cpp
+++ b/src/semistatic_graph.cpp
@@ -4,9 +4,9 @@
* 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.
@@ -19,8 +19,8 @@
#include <fruit/impl/data_structures/semistatic_graph.h>
#include <fruit/impl/data_structures/semistatic_graph.templates.h>
-#include <fruit/impl/util/type_info.h>
#include <fruit/impl/normalized_component_storage/normalized_bindings.h>
+#include <fruit/impl/util/type_info.h>
using namespace fruit::impl;
diff --git a/src/semistatic_map.cpp b/src/semistatic_map.cpp
index 86eff3a..57811f1 100644
--- a/src/semistatic_map.cpp
+++ b/src/semistatic_map.cpp
@@ -4,9 +4,9 @@
* 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.
@@ -16,9 +16,9 @@
#define IN_FRUIT_CPP_FILE
+#include <fruit/impl/data_structures/semistatic_graph.h>
#include <fruit/impl/data_structures/semistatic_map.h>
#include <fruit/impl/data_structures/semistatic_map.templates.h>
-#include <fruit/impl/data_structures/semistatic_graph.h>
#include <fruit/impl/util/type_info.h>
diff --git a/tests/class_construction_tracker.h b/tests/class_construction_tracker.h
index b5102af..03db0ab 100644
--- a/tests/class_construction_tracker.h
+++ b/tests/class_construction_tracker.h
@@ -33,15 +33,14 @@
*/
template <typename T>
struct ConstructionTracker {
- static std::size_t num_objects_constructed;
+ static std::size_t num_objects_constructed;
- ConstructionTracker() {
- ++num_objects_constructed;
- }
+ ConstructionTracker() {
+ ++num_objects_constructed;
+ }
};
template <typename T>
std::size_t ConstructionTracker<T>::num_objects_constructed = 0;
-
#endif // FRUIT_CLASS_CONSTRUCTION_TRACKER_H
diff --git a/tests/meta/common.h b/tests/meta/common.h
index 039b927..f2e3078 100644
--- a/tests/meta/common.h
+++ b/tests/meta/common.h
@@ -4,13 +4,13 @@
#define FRUIT_IN_META_TEST
-#include <fruit/impl/meta/errors.h>
-#include <fruit/impl/meta/basics.h>
-#include <fruit/impl/meta/vector.h>
-#include <fruit/impl/meta/set.h>
-#include <fruit/impl/meta/immutable_map.h>
-#include <fruit/impl/injection_errors.h>
#include <fruit/impl/injection_debug_errors.h>
+#include <fruit/impl/injection_errors.h>
+#include <fruit/impl/meta/basics.h>
+#include <fruit/impl/meta/errors.h>
+#include <fruit/impl/meta/immutable_map.h>
+#include <fruit/impl/meta/set.h>
+#include <fruit/impl/meta/vector.h>
using namespace std;
using namespace fruit;
@@ -19,17 +19,14 @@
template <typename T, typename U>
struct DifferentError {
- static_assert(AlwaysFalse<T>::value,
- "T and U are different, but should have been equal/equivalent.");
+ static_assert(AlwaysFalse<T>::value, "T and U are different, but should have been equal/equivalent.");
};
template <typename T, typename U>
struct SameError {
- static_assert(AlwaysFalse<T>::value,
- "T and U are equal/equivalent but should have been different.");
+ static_assert(AlwaysFalse<T>::value, "T and U are equal/equivalent but should have been different.");
};
-
struct DifferentErrorTag {
template <typename T, typename U>
using apply = DifferentError<T, U>;
@@ -57,16 +54,49 @@
#define Assert(...) static_assert(Eval<__VA_ARGS__>::value, "")
#define AssertNot(...) Assert(Not(__VA_ARGS__))
-#define AssertSame(...) static_assert(true || sizeof(typename CheckIfError<Eval<If(IsSame(__VA_ARGS__), True, ConstructErrorWithoutUnwrapping(DifferentErrorTag, __VA_ARGS__))>>::type), "")
-#define AssertSameType(...) static_assert(true || sizeof(typename CheckIfError<Eval<If(IsSame(__VA_ARGS__), True, ConstructError(DifferentErrorTag, __VA_ARGS__))>>::type), "")
-#define AssertSameSet(...) static_assert(true || sizeof(typename CheckIfError<Eval<If(IsSameSet(__VA_ARGS__), True, ConstructError(DifferentErrorTag, __VA_ARGS__))>>::type), "")
-#define AssertSameProof(...) static_assert(true || sizeof(typename CheckIfError<Eval<If(IsProofTreeEqualTo(__VA_ARGS__), True, ConstructError(DifferentErrorTag, __VA_ARGS__))>>::type), "")
-#define AssertSameForest(...) static_assert(true || sizeof(typename CheckIfError<Eval<CheckForestEqualTo(__VA_ARGS__)>>::type), "")
-#define AssertNotSame(...) static_assert(true || sizeof(typename CheckIfError<Eval<If(Not(IsSame(__VA_ARGS__)), True, ConstructErrorWithoutUnwrapping(SameErrorTag, __VA_ARGS__))>>::type), "")
-#define AssertNotSameType(...) static_assert(true || sizeof(typename CheckIfError<Eval<If(Not(IsSame(__VA_ARGS__)), True, ConstructError(SameErrorTag, __VA_ARGS__))>>::type), "")
-#define AssertNotSameProof(...) static_assert(true || sizeof(typename CheckIfError<Eval<If(Not(IsProofTreeEqualTo(__VA_ARGS__)), True, ConstructError(SameErrorTag, __VA_ARGS__))>>::type), "")
-#define AssertNotSameForest(...) static_assert(true || sizeof(typename CheckIfError<Eval<If(Not(IsForestEqualTo(__VA_ARGS__)), True, ConstructError(SameErrorTag, __VA_ARGS__))>>::type), "")
-
-
+#define AssertSame(...) \
+ static_assert( \
+ true || \
+ sizeof( \
+ typename CheckIfError<Eval<If(IsSame(__VA_ARGS__), True, \
+ ConstructErrorWithoutUnwrapping(DifferentErrorTag, __VA_ARGS__))>>::type), \
+ "")
+#define AssertSameType(...) \
+ static_assert( \
+ true || sizeof(typename CheckIfError< \
+ Eval<If(IsSame(__VA_ARGS__), True, ConstructError(DifferentErrorTag, __VA_ARGS__))>>::type), \
+ "")
+#define AssertSameSet(...) \
+ static_assert( \
+ true || sizeof(typename CheckIfError< \
+ Eval<If(IsSameSet(__VA_ARGS__), True, ConstructError(DifferentErrorTag, __VA_ARGS__))>>::type), \
+ "")
+#define AssertSameProof(...) \
+ static_assert(true || sizeof(typename CheckIfError<Eval<If(IsProofTreeEqualTo(__VA_ARGS__), True, \
+ ConstructError(DifferentErrorTag, __VA_ARGS__))>>::type), \
+ "")
+#define AssertSameForest(...) \
+ static_assert(true || sizeof(typename CheckIfError<Eval<CheckForestEqualTo(__VA_ARGS__)>>::type), "")
+#define AssertNotSame(...) \
+ static_assert( \
+ true || \
+ sizeof(typename CheckIfError<Eval<If(Not(IsSame(__VA_ARGS__)), True, \
+ ConstructErrorWithoutUnwrapping(SameErrorTag, __VA_ARGS__))>>::type), \
+ "")
+#define AssertNotSameType(...) \
+ static_assert( \
+ true || sizeof(typename CheckIfError< \
+ Eval<If(Not(IsSame(__VA_ARGS__)), True, ConstructError(SameErrorTag, __VA_ARGS__))>>::type), \
+ "")
+#define AssertNotSameProof(...) \
+ static_assert(true || sizeof(typename CheckIfError<Eval<If(Not(IsProofTreeEqualTo(__VA_ARGS__)), True, \
+ ConstructError(SameErrorTag, __VA_ARGS__))>>::type), \
+ "")
+#define AssertNotSameForest(...) \
+ static_assert( \
+ true || \
+ sizeof(typename CheckIfError< \
+ Eval<If(Not(IsForestEqualTo(__VA_ARGS__)), True, ConstructError(SameErrorTag, __VA_ARGS__))>>::type), \
+ "")
#endif // FRUIT_TESTS_META_COMMON_H
diff --git a/tests/test_common.h b/tests/test_common.h
index f29d564..d48f110 100644
--- a/tests/test_common.h
+++ b/tests/test_common.h
@@ -20,11 +20,11 @@
// This file includes headers used in various tests.
// This allows to improve compilation speed (and therefore test time) by pre-compiling this header.
-#include <fruit/fruit.h>
-#include <vector>
-#include <map>
-#include "test_macros.h"
#include "class_construction_tracker.h"
+#include "test_macros.h"
+#include <fruit/fruit.h>
#include <fruit/impl/injector/injector_accessor_for_tests.h>
+#include <map>
+#include <vector>
#endif // FRUIT_TEST_COMMON_H
diff --git a/tests/test_macros.h b/tests/test_macros.h
index f9bff4c..8d850e1 100644
--- a/tests/test_macros.h
+++ b/tests/test_macros.h
@@ -19,8 +19,18 @@
#include <iostream>
-#define Assert(...) do { if (!(__VA_ARGS__)) { std::cerr << __FILE__ << ":" << __LINE__ << ": " << __func__ << ": Assertion \"" << #__VA_ARGS__ << "\" failed." << std::endl; abort(); } } while(false)
+#define Assert(...) \
+ do { \
+ if (!(__VA_ARGS__)) { \
+ std::cerr << __FILE__ << ":" << __LINE__ << ": " << __func__ << ": Assertion \"" << #__VA_ARGS__ << "\" failed." \
+ << std::endl; \
+ abort(); \
+ } \
+ } while (false)
-#define InstantiateType(...) void f() { (void) sizeof(__VA_ARGS__); }
+#define InstantiateType(...) \
+ void f() { \
+ (void)sizeof(__VA_ARGS__); \
+ }
#endif // FRUIT_TEST_MACROS