Import Cobalt 10.49488
diff --git a/src/nb/std_allocator.h b/src/nb/std_allocator.h
index ce3a818..318a1b9 100644
--- a/src/nb/std_allocator.h
+++ b/src/nb/std_allocator.h
@@ -19,6 +19,8 @@
#include <memory>
+#include "nb/allocator.h"
+#include "starboard/configuration.h"
#include "starboard/types.h"
namespace nb {
@@ -60,10 +62,11 @@
// Constructor used for rebinding
template <typename U, typename V>
- StdAllocator(const StdAllocator<U, V>& x) {}
+ StdAllocator(const StdAllocator<U, V>&) {}
pointer allocate(size_type n,
std::allocator<void>::const_pointer hint = NULL) {
+ SB_UNREFERENCED_PARAMETER(hint);
void* ptr = AllocatorT::Allocate(n * sizeof(value_type));
return static_cast<pointer>(ptr);
}
@@ -77,6 +80,91 @@
};
};
+// A standard container compatible allocator that delegates allocations to a
+// custom allocator via a shared pointer. This differs from StdAllocator since
+// StdAllocator binds to static functions. This important difference allows
+// StdDynamicAllocator to keep memory accounting on a per-instance basis, but
+// otherwise is a tad slower, harder to instantiate and produces less readable
+// code.
+//
+// When in doubt, use StdAllocator over StdDynamicAllocator.
+//
+// Passed in nb::Allocator:
+// Even though nb::Allocator has many functions for alignment, only the two
+// are used within StdDynamicAllocator:
+// void* nb::Allocator::Allocate() -and-
+// void nb::FreeWithSize(void* ptr, size_t optional_size)
+//
+// Example of Allocator Definition:
+// class MyAllocator : public SimpleAllocator {
+// public:
+// void* Allocate(size_t size) SB_OVERRIDE {
+// return SbMemoryAllocate(size);
+// }
+//
+// // Second argument can be used for accounting, but is otherwise optional.
+// void FreeWithSize(void* ptr, size_t optional_size) SB_OVERRIDE {
+// SbMemoryDeallocate(ptr);
+// }
+//
+// // ... other functions
+// };
+//
+// Example of std::vector<int>:
+// typedef StdDynamicAllocator<int> IntAllocator;
+// typedef std::vector<int, IntAllocator> IntVector;
+//
+// MyAllocator my_allocator;
+// // Note that IntVector is not default constructible!
+// IntVector int_vector(IntAllocator(&my_allocator));
+//
+// Example of std::map<int, int>:
+// // Note that maps require std::less() instance to be passed in whenever
+// // a custom allocator is passed in.
+// typedef std::map<int, int, std::less<int>, MyAllocator> IntMap;
+// IntMap int_map(std::less<int>(), /* std::less<int> required pre-C++11 */
+// IntAllocator(&my_allocator));
+template <typename T>
+class StdDynamicAllocator : public std::allocator<T> {
+ public:
+ typedef typename std::allocator<T>::pointer pointer;
+ typedef typename std::allocator<T>::const_pointer const_pointer;
+ typedef typename std::allocator<T>::reference reference;
+ typedef typename std::allocator<T>::const_reference const_reference;
+ typedef typename std::allocator<T>::size_type size_type;
+ typedef typename std::allocator<T>::value_type value_type;
+ typedef typename std::allocator<T>::difference_type difference_type;
+
+ explicit StdDynamicAllocator(Allocator* allocator) : allocator_(allocator) {}
+ StdDynamicAllocator(StdDynamicAllocator& std_allocator)
+ : allocator_(std_allocator.allocator_) {}
+
+ // Constructor used for rebinding
+ template <typename U>
+ StdDynamicAllocator(const StdDynamicAllocator<U>& x)
+ : allocator_(x.allocator()) {}
+
+ pointer allocate(size_type n,
+ std::allocator<void>::const_pointer hint = NULL) {
+ SB_UNREFERENCED_PARAMETER(hint);
+ void* ptr = allocator_->Allocate(n * sizeof(value_type));
+ return static_cast<pointer>(ptr);
+ }
+
+ void deallocate(pointer ptr, size_type n) {
+ allocator_->FreeWithSize(ptr, n * sizeof(value_type));
+ }
+ template <typename U>
+ struct rebind {
+ typedef StdDynamicAllocator<U> other;
+ };
+
+ Allocator* allocator() const { return allocator_; }
+
+ private:
+ Allocator* allocator_;
+};
+
} // namespace nb
#endif // NB_STD_ALLOCATOR_H_