Save memory and slightly improve performance by storing a BindingData in 3*sizeof(void*) bytes instead of 4*sizeof(void*).
diff --git a/include/fruit/impl/binding_data.defn.h b/include/fruit/impl/binding_data.defn.h
index f451b09..ae3e0f2 100644
--- a/include/fruit/impl/binding_data.defn.h
+++ b/include/fruit/impl/binding_data.defn.h
@@ -45,20 +45,20 @@
};
inline BindingData::BindingData(create_t create, const BindingDeps* deps, bool needs_allocation)
-: deps(deps), p(reinterpret_cast<void*>(create)), needs_allocation(needs_allocation) {
+: deps_and_needs_allocation(deps, needs_allocation), p(reinterpret_cast<void*>(create)) {
}
inline BindingData::BindingData(object_t object)
-: deps(nullptr), p(reinterpret_cast<void*>(object)), needs_allocation(false) {
+: deps_and_needs_allocation(nullptr, false), p(reinterpret_cast<void*>(object)) {
}
inline bool BindingData::isCreated() const {
- return deps == nullptr;
+ return deps_and_needs_allocation.getPointer() == nullptr;
}
inline const BindingDeps* BindingData::getDeps() const {
- FruitAssert(deps != nullptr);
- return deps;
+ FruitAssert(deps_and_needs_allocation.getPointer() != nullptr);
+ return deps_and_needs_allocation.getPointer();
}
inline BindingData::create_t BindingData::getCreate() const {
@@ -72,12 +72,12 @@
}
inline bool BindingData::needsAllocation() const {
- return needs_allocation;
+ return deps_and_needs_allocation.getBool();
}
inline bool BindingData::operator==(const BindingData& other) const {
- return std::tie(deps, p)
- == std::tie(other.deps, other.p);
+ return std::tie(deps_and_needs_allocation, p)
+ == std::tie(other.deps_and_needs_allocation, other.p);
}
inline NormalizedBindingData::NormalizedBindingData(BindingData binding_data) {
diff --git a/include/fruit/impl/binding_data.h b/include/fruit/impl/binding_data.h
index cd2e8a0..baa4741 100644
--- a/include/fruit/impl/binding_data.h
+++ b/include/fruit/impl/binding_data.h
@@ -19,6 +19,7 @@
#include <fruit/impl/util/type_info.h>
#include <fruit/impl/data_structures/semistatic_graph.h>
+#include <fruit/impl/data_structures/packed_pointer_and_bool.h>
#include <vector>
#include <memory>
@@ -58,7 +59,8 @@
private:
// `deps' stores the type IDs that this type depends on.
// If `deps' itself is nullptr, this binding stores an object instead of a create operation.
- const BindingDeps* deps;
+ // needs_allocation is false for e.g. bindings, instance bindings that don't need to allocate an object.
+ PackedPointerAndBool<const BindingDeps> deps_and_needs_allocation;
// This stores either:
//
@@ -69,9 +71,6 @@
// The stored object, a casted T*.
void* p;
- // This is false for e.g. bindings, instance bindings that don't need to allocate an object.
- bool needs_allocation;
-
public:
BindingData() = default;
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 582e597..a988ef9 100644
--- a/include/fruit/impl/data_structures/fixed_size_allocator.defn.h
+++ b/include/fruit/impl/data_structures/fixed_size_allocator.defn.h
@@ -1,5 +1,5 @@
/*
- * Topyright 2014 Google Inc. All rights reserved.
+ * Copyright 2014 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
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
new file mode 100644
index 0000000..806a53b
--- /dev/null
+++ b/include/fruit/impl/data_structures/packed_pointer_and_bool.defn.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FRUIT_PACKED_POINTER_AND_BOOL_DEFN_H
+#define FRUIT_PACKED_POINTER_AND_BOOL_DEFN_H
+
+#include <fruit/impl/data_structures/packed_pointer_and_bool.h>
+
+namespace fruit {
+namespace impl {
+
+template <typename T>
+inline std::uintptr_t PackedPointerAndBool<T>::encode(T* p, bool b) {
+ return reinterpret_cast<std::uintptr_t>(p) | b;
+}
+
+template <typename T>
+inline T* PackedPointerAndBool<T>::decodePointer(std::uintptr_t value) {
+ return reinterpret_cast<T*>(value & ~ std::uintptr_t(1));
+}
+
+template <typename T>
+inline bool PackedPointerAndBool<T>::decodeBool(std::uintptr_t value) {
+ return value & 1;
+}
+
+template <typename T>
+inline PackedPointerAndBool<T>::PackedPointerAndBool(T* p, bool b) {
+ value = encode(p, b);
+}
+
+template <typename T>
+inline T* PackedPointerAndBool<T>::getPointer() const {
+ return decodePointer(value);
+}
+
+template <typename T>
+inline void PackedPointerAndBool<T>::setPointer(T* p) {
+ value = encode(p, decodeBool(value));
+}
+
+template <typename T>
+inline bool PackedPointerAndBool<T>::getBool() const {
+ return decodeBool(value);
+}
+
+template <typename T>
+inline void PackedPointerAndBool<T>::setBool(bool b) {
+ value = encode(decodePointer(value), b);
+}
+
+template <typename T>
+inline bool PackedPointerAndBool<T>::operator==(const PackedPointerAndBool<T>& other) const {
+ return value == other.value;
+}
+
+template <typename T>
+inline bool PackedPointerAndBool<T>::operator!=(const PackedPointerAndBool<T>& other) const {
+ return value != other.value;
+}
+
+} // 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
new file mode 100644
index 0000000..e946fc1
--- /dev/null
+++ b/include/fruit/impl/data_structures/packed_pointer_and_bool.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FRUIT_PACKED_POINTER_AND_BOOL_H
+#define FRUIT_PACKED_POINTER_AND_BOOL_H
+
+namespace fruit {
+namespace impl {
+
+/**
+ * This class stores a T* and a bool in the space of a pointer.
+ * alignof(T) must be at least 2.
+ */
+template <typename T>
+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;
+};
+
+} // namespace impl
+} // namespace fruit
+
+#include <fruit/impl/data_structures/packed_pointer_and_bool.defn.h>
+
+
+#endif // FRUIT_PACKED_POINTER_AND_BOOL_H
diff --git a/src/injector_storage.cpp b/src/injector_storage.cpp
index a5efcf6..72c6ae3 100644
--- a/src/injector_storage.cpp
+++ b/src/injector_storage.cpp
@@ -26,6 +26,7 @@
#include <fruit/impl/storage/injector_storage.h>
#include <fruit/impl/storage/component_storage.h>
#include <fruit/impl/data_structures/semistatic_graph.templates.h>
+#include <fruit/impl/meta/basics.h>
using std::cout;
using std::endl;