Skip to content

Commit

Permalink
Reimplement the storage for PartialComponent to:
Browse files Browse the repository at this point in the history
* Reduce code size
* Remove the need for thread_local (this allows sharing Component objects across threads, and allows supporting using Fruit with older versions of XCode that don't support thread_local).
* Support the new best practice of defining components as constants in get*Component() functions.
  • Loading branch information
poletti-marco committed Aug 29, 2016
1 parent 677df8d commit 0316a00
Show file tree
Hide file tree
Showing 64 changed files with 756 additions and 670 deletions.
28 changes: 13 additions & 15 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,18 @@ matrix:
# Not sure if that's a limitation of Clang 3.7 on OS X or just of the brew-provided binaries.
env: COMPILER=clang-3.7 STL=libc++ NO_ASAN=1 NO_UBSAN=1
# AppleClang (from XCode)
- os: osx
compiler: clang
# OS X 10.10
osx_image: xcode7.1
# UBSan is disabled because AppleClang does not support -fsanitize=undefined.
env: COMPILER=clang-default STL=libc++ NO_UBSAN=1
- os: osx
compiler: clang
# OS X 10.11
osx_image: xcode7.3
# UBSan is disabled because AppleClang does not support -fsanitize=undefined.
env: COMPILER=clang-default STL=libc++ NO_UBSAN=1
- os: osx
compiler: clang
# OS X >=10.11
Expand Down Expand Up @@ -164,18 +176,4 @@ matrix:
# - os: linux
# compiler: clang
# env: UBUNTU=16.04 COMPILER=clang-3.8 STL=libc++ NO_ASAN=1 NO_UBSAN=1
#
# These fail with "error: thread-local storage is not supported for the current target".
# See http://stackoverflow.com/questions/28094794/why-does-apple-clang-disallow-c11-thread-local-when-official-clang-supports
# - os: osx
# compiler: clang
# # OS X 10.10
# osx_image: xcode7.1
# # UBSan is disabled because AppleClang does not support -fsanitize=undefined.
# env: COMPILER=clang-default STL=libc++ NO_UBSAN=1
# - os: osx
# compiler: clang
# # OS X 10.11
# osx_image: xcode7.3
# # UBSan is disabled because AppleClang does not support -fsanitize=undefined.
# env: COMPILER=clang-default STL=libc++ NO_UBSAN=1
#
5 changes: 3 additions & 2 deletions examples/annotated_injection/car.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,10 @@ class CarImpl : public Car {
}
};

fruit::Component<Car> getCarComponent() {
return fruit::createComponent()
const fruit::Component<Car>& getCarComponent() {
static const fruit::Component<Car> comp = fruit::createComponent()
.bind<Car, CarImpl>()
.install(getMainBrakeComponent())
.install(getEmergencyBrakeComponent());
return comp;
}
2 changes: 1 addition & 1 deletion examples/annotated_injection/car.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ class Car {
virtual void brake() = 0;
};

fruit::Component<Car> getCarComponent();
const fruit::Component<Car>& getCarComponent();

#endif // CAR_H
5 changes: 3 additions & 2 deletions examples/annotated_injection/emergency_brake.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ class EmergencyBrakeImpl : public Brake {
}
};

fruit::Component<fruit::Annotated<EmergencyBrake, Brake>> getEmergencyBrakeComponent() {
return fruit::createComponent()
const fruit::Component<fruit::Annotated<EmergencyBrake, Brake>>& getEmergencyBrakeComponent() {
static const fruit::Component<fruit::Annotated<EmergencyBrake, Brake>> comp = fruit::createComponent()
.bind<fruit::Annotated<EmergencyBrake, Brake>, EmergencyBrakeImpl>();
return comp;
}
2 changes: 1 addition & 1 deletion examples/annotated_injection/emergency_brake.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@
// This marks a the Brake instance that represents the main brake.
struct EmergencyBrake {};

fruit::Component<fruit::Annotated<EmergencyBrake, Brake>> getEmergencyBrakeComponent();
const fruit::Component<fruit::Annotated<EmergencyBrake, Brake>>& getEmergencyBrakeComponent();

#endif // EMERGENCY_BRAKE_H
5 changes: 3 additions & 2 deletions examples/annotated_injection/main_brake.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ class MainBrakeImpl : public Brake {
}
};

fruit::Component<fruit::Annotated<MainBrake, Brake>> getMainBrakeComponent() {
return fruit::createComponent()
const fruit::Component<fruit::Annotated<MainBrake, Brake>>& getMainBrakeComponent() {
static const fruit::Component<fruit::Annotated<MainBrake, Brake>> comp = fruit::createComponent()
.bind<fruit::Annotated<MainBrake, Brake>, MainBrakeImpl>();
return comp;
}
2 changes: 1 addition & 1 deletion examples/annotated_injection/main_brake.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@
// This marks a the Brake instance that represents the main brake.
struct MainBrake {};

fruit::Component<fruit::Annotated<MainBrake, Brake>> getMainBrakeComponent();
const fruit::Component<fruit::Annotated<MainBrake, Brake>>& getMainBrakeComponent();

#endif // MAIN_BRAKE_H
5 changes: 3 additions & 2 deletions examples/hello_world/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,11 @@ class GreeterImpl : public Greeter {
}
};

Component<Greeter> getGreeterComponent() {
return fruit::createComponent()
const Component<Greeter>& getGreeterComponent() {
static const Component<Greeter> comp = fruit::createComponent()
.bind<Writer, StdoutWriter>()
.bind<Greeter, GreeterImpl>();
return comp;
}

int main() {
Expand Down
11 changes: 6 additions & 5 deletions examples/multibindings/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,13 @@ class Listener2 : public Listener {
}
};

Component<> getListenersComponent() {
const Component<>& getListenersComponent() {
// 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>()
.addMultibinding<Listener, Listener2>();
static const Component<> comp = fruit::createComponent()
.bind<Writer, StdoutWriter>()
.addMultibinding<Listener, Listener1>()
.addMultibinding<Listener, Listener2>();
return comp;
}

int main() {
Expand Down
5 changes: 3 additions & 2 deletions examples/scaling_doubles/multiplier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ class MultiplierImpl : public Multiplier {
}
};

fruit::Component<Multiplier> getMultiplierComponent() {
return fruit::createComponent()
const fruit::Component<Multiplier>& getMultiplierComponent() {
static const fruit::Component<Multiplier> comp = fruit::createComponent()
.bind<Multiplier, MultiplierImpl>()
.registerConstructor<MultiplierImpl()>();
return comp;
}
2 changes: 1 addition & 1 deletion examples/scaling_doubles/multiplier.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ class Multiplier {
virtual double multiply(double x, double y) = 0;
};

fruit::Component<Multiplier> getMultiplierComponent();
const fruit::Component<Multiplier>& getMultiplierComponent();

#endif // MULTIPLIER_H
5 changes: 3 additions & 2 deletions examples/scaling_doubles/scaler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ class ScalerImpl : public Scaler {
};


Component<ScalerFactory> getScalerComponent() {
return createComponent()
const Component<ScalerFactory>& getScalerComponent() {
static const Component<ScalerFactory> comp = createComponent()
.bind<Scaler, ScalerImpl>()
.install(getMultiplierComponent());
return comp;
}
2 changes: 1 addition & 1 deletion examples/scaling_doubles/scaler.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ class Scaler {

using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>;

fruit::Component<ScalerFactory> getScalerComponent();
const fruit::Component<ScalerFactory>& getScalerComponent();

#endif // SCALER_H
5 changes: 3 additions & 2 deletions examples/server/bar_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ class BarHandlerImpl : public BarHandler {
}
};

Component<Required<Request, ServerContext>, BarHandler> getBarHandlerComponent() {
return fruit::createComponent()
const Component<Required<Request, ServerContext>, BarHandler>& getBarHandlerComponent() {
static const Component<Required<Request, ServerContext>, BarHandler> comp = fruit::createComponent()
.bind<BarHandler, BarHandlerImpl>();
return comp;
}

2 changes: 1 addition & 1 deletion examples/server/bar_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,6 @@ class BarHandler {
virtual void handleRequest() = 0;
};

fruit::Component<fruit::Required<Request, ServerContext>, BarHandler> getBarHandlerComponent();
const fruit::Component<fruit::Required<Request, ServerContext>, BarHandler>& getBarHandlerComponent();

#endif // BAR_HANDLER_H
5 changes: 3 additions & 2 deletions examples/server/foo_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ class FooHandlerImpl : public FooHandler {
}
};

Component<Required<Request, ServerContext>, FooHandler> getFooHandlerComponent() {
return fruit::createComponent()
const Component<Required<Request, ServerContext>, FooHandler>& getFooHandlerComponent() {
static const Component<Required<Request, ServerContext>, FooHandler> comp = fruit::createComponent()
.bind<FooHandler, FooHandlerImpl>();
return comp;
}

2 changes: 1 addition & 1 deletion examples/server/foo_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,6 @@ class FooHandler {
virtual void handleRequest() = 0;
};

fruit::Component<fruit::Required<Request, ServerContext>, FooHandler> getFooHandlerComponent();
const fruit::Component<fruit::Required<Request, ServerContext>, FooHandler>& getFooHandlerComponent();

#endif // FOO_HANDLER_H
5 changes: 3 additions & 2 deletions examples/server/request_dispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,10 @@ class RequestDispatcherImpl : public RequestDispatcher {
}
};

Component<Required<Request, ServerContext>, RequestDispatcher> getRequestDispatcherComponent() {
return createComponent()
const Component<Required<Request, ServerContext>, RequestDispatcher>& getRequestDispatcherComponent() {
static const Component<Required<Request, ServerContext>, RequestDispatcher> comp = createComponent()
.bind<RequestDispatcher, RequestDispatcherImpl>()
.install(getFooHandlerComponent())
.install(getBarHandlerComponent());
return comp;
}
2 changes: 1 addition & 1 deletion examples/server/request_dispatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,6 @@ class RequestDispatcher {
virtual void handleRequest() = 0;
};

fruit::Component<fruit::Required<Request, ServerContext>, RequestDispatcher> getRequestDispatcherComponent();
const fruit::Component<fruit::Required<Request, ServerContext>, RequestDispatcher>& getRequestDispatcherComponent();

#endif // REQUEST_DISPATCHER_H
5 changes: 3 additions & 2 deletions examples/server/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ class ServerImpl : public Server {
}
};

fruit::Component<Server> getServerComponent() {
return fruit::createComponent()
const fruit::Component<Server>& getServerComponent() {
static const fruit::Component<Server> comp = fruit::createComponent()
.bind<Server, ServerImpl>();
return comp;
}
2 changes: 1 addition & 1 deletion examples/server/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,6 @@ class Server {
virtual void run(fruit::Component<fruit::Required<Request, ServerContext>, RequestDispatcher> requestDispatcherComponent) = 0;
};

fruit::Component<Server> getServerComponent();
const fruit::Component<Server>& getServerComponent();

#endif // SERVER_H
5 changes: 3 additions & 2 deletions examples/simple_injection/checked_adder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ class CheckedAdder : public Adder {
}
};

fruit::Component<Adder> getCheckedAdderComponent() {
return fruit::createComponent()
const fruit::Component<Adder>& getCheckedAdderComponent() {
static const fruit::Component<Adder> comp = fruit::createComponent()
.bind<Adder, CheckedAdder>();
return comp;
}
2 changes: 1 addition & 1 deletion examples/simple_injection/checked_adder.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@
#include <fruit/fruit.h>
#include "adder.h"

fruit::Component<Adder> getCheckedAdderComponent();
const fruit::Component<Adder>& getCheckedAdderComponent();

#endif // CHECKED_ADDER_H
5 changes: 3 additions & 2 deletions examples/simple_injection/checked_incrementer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@
#include "incrementer_impl.h"
#include "checked_adder.h"

fruit::Component<Incrementer> getCheckedIncrementerComponent() {
return fruit::createComponent()
const fruit::Component<Incrementer>& getCheckedIncrementerComponent() {
static const fruit::Component<Incrementer> comp = fruit::createComponent()
.install(getIncrementerImplComponent())
.install(getCheckedAdderComponent());
return comp;
}
2 changes: 1 addition & 1 deletion examples/simple_injection/checked_incrementer.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@
#include <fruit/fruit.h>
#include "incrementer.h"

fruit::Component<Incrementer> getCheckedIncrementerComponent();
const fruit::Component<Incrementer>& getCheckedIncrementerComponent();

#endif // CHECKED_INCREMENTER_H
2 changes: 1 addition & 1 deletion examples/simple_injection/incrementer_component.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#include "simple_incrementer.h"
#include "checked_incrementer.h"

fruit::Component<Incrementer> getIncrementerComponent(bool checked) {
const fruit::Component<Incrementer>& getIncrementerComponent(bool checked) {
if (checked)
return getCheckedIncrementerComponent();
else
Expand Down
2 changes: 1 addition & 1 deletion examples/simple_injection/incrementer_component.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@

#include <fruit/fruit.h>

fruit::Component<Incrementer> getIncrementerComponent(bool checked);
const fruit::Component<Incrementer>& getIncrementerComponent(bool checked);

#endif // INCREMENTER_COMPONENT_H
5 changes: 3 additions & 2 deletions examples/simple_injection/incrementer_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ class IncrementerImpl : public Incrementer {
}
};

fruit::Component<fruit::Required<Adder>, Incrementer> getIncrementerImplComponent() {
return fruit::createComponent()
const fruit::Component<fruit::Required<Adder>, Incrementer>& getIncrementerImplComponent() {
static const fruit::Component<fruit::Required<Adder>, Incrementer> comp = fruit::createComponent()
.bind<Incrementer, IncrementerImpl>();
return comp;
}
2 changes: 1 addition & 1 deletion examples/simple_injection/incrementer_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@
#include "incrementer.h"
#include "adder.h"

fruit::Component<fruit::Required<Adder>, Incrementer> getIncrementerImplComponent();
const fruit::Component<fruit::Required<Adder>, Incrementer>& getIncrementerImplComponent();

#endif // INCREMENTER_IMPL_H
5 changes: 3 additions & 2 deletions examples/simple_injection/simple_adder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ class SimpleAdder : public Adder {
}
};

fruit::Component<Adder> getSimpleAdderComponent() {
return fruit::createComponent()
const fruit::Component<Adder>& getSimpleAdderComponent() {
static const fruit::Component<Adder> comp = fruit::createComponent()
.bind<Adder, SimpleAdder>();
return comp;
}
2 changes: 1 addition & 1 deletion examples/simple_injection/simple_adder.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@
#include <fruit/fruit.h>
#include "adder.h"

fruit::Component<Adder> getSimpleAdderComponent();
const fruit::Component<Adder>& getSimpleAdderComponent();

#endif // SIMPLE_ADDER_H
5 changes: 3 additions & 2 deletions examples/simple_injection/simple_incrementer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@
#include "incrementer_impl.h"
#include "simple_adder.h"

fruit::Component<Incrementer> getSimpleIncrementerComponent() {
return fruit::createComponent()
const fruit::Component<Incrementer>& getSimpleIncrementerComponent() {
static const fruit::Component<Incrementer> comp = fruit::createComponent()
.install(getIncrementerImplComponent())
.install(getSimpleAdderComponent());
return comp;
}
2 changes: 1 addition & 1 deletion examples/simple_injection/simple_incrementer.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@
#include <fruit/fruit.h>
#include "incrementer.h"

fruit::Component<Incrementer> getSimpleIncrementerComponent();
const fruit::Component<Incrementer>& getSimpleIncrementerComponent();

#endif // SIMPLE_INCREMENTER_H
7 changes: 4 additions & 3 deletions extras/benchmark/compile_time_benchmark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ struct Y##N { \
struct Z##N { \
}; \
\
Component<Required<Y##N>, Z##N> getZ##N##Component(); \
const Component<Required<Y##N>, Z##N>& getZ##N##Component(); \

#define REQUIREMENTS(N) \
C##N,
Expand All @@ -142,8 +142,9 @@ B##N& b##N,

EVAL(REPEAT(DEFINITIONS))

Component<Required<EVAL(REPEAT(REQUIREMENTS)) int>> getComponent(EVAL(REPEAT(PARAMETERS)) int) {
return createComponent()
const Component<Required<EVAL(REPEAT(REQUIREMENTS)) int>>& getComponent(EVAL(REPEAT(PARAMETERS)) int) {
static const Component<Required<EVAL(REPEAT(REQUIREMENTS)) int>> comp = createComponent()
EVAL(REPEAT(BINDINGS))
;
return comp;
}
Loading

0 comments on commit 0316a00

Please sign in to comment.