frutiger created this revision. frutiger added reviewers: EricWF, mclow.lists. frutiger added a subscriber: cfe-commits.
This commit introduces a new supporting allocator 'IA1' in 'support/instrumentingallocators.h' which tracks allocations and deallocations. This commit also introduces a new test driver 'construct.pass.cpp' which tests using the 'scoped_allocator_adaptor' with three types which take allocators in different ways: 1. container-style with the allocator at the end 2. std::function-style with the allocator at the start 3. allocator-unaware types This will provide a starting point for scenarios where argument lists need to be adapted before being forwarded for 'pair<T1, T2>' where 'T1' and 'T2' may be combinations of the above three classes of types. http://reviews.llvm.org/D16970 Files: test/std/utilities/allocator.adaptor/scoped.adaptor.operators/construct.pass.cpp test/support/instrumentingallocators.h
Index: test/support/instrumentingallocators.h =================================================================== --- /dev/null +++ test/support/instrumentingallocators.h @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef ALLOCATORS_H +#define ALLOCATORS_H + +#include <cstdlib> +#include <unordered_map> + +struct Instrumentation { + typedef std::unordered_map<void *, size_t> Allocations; + + Allocations allocs_; + size_t numAllocs_ = 0; + size_t numDeallocs_ = 0; + size_t numAllocsLastChecked_ = 0; + + void checkAllocsIncreased() { + assert(numAllocs_ > numAllocsLastChecked_); + numAllocsLastChecked_ = numAllocs_; + } +}; + +template <typename T> +struct IA1 { + Instrumentation *instrumentation_; + + typedef T value_type; + + explicit IA1(Instrumentation *instrumentation) : + instrumentation_(instrumentation) {} + + template <typename U> + IA1(const IA1<U>& other) : instrumentation_(other.instrumentation_) {} + + T *allocate(size_t n) { + void *result = std::malloc(sizeof(T) * n); + assert(instrumentation_->allocs_.find(result) == + instrumentation_->allocs_.end()); + instrumentation_->allocs_[result] = n; + ++instrumentation_->numAllocs_; + return static_cast<T *>(result); + } + + void deallocate(T *ptr, size_t n) { + auto alloc = instrumentation_->allocs_.find(ptr); + assert(alloc != instrumentation_->allocs_.end()); + assert(alloc->second == n); + instrumentation_->allocs_.erase(alloc); + ++instrumentation_->numDeallocs_; + std::free(ptr); + } +}; + +#endif Index: test/std/utilities/allocator.adaptor/scoped.adaptor.operators/construct.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/allocator.adaptor/scoped.adaptor.operators/construct.pass.cpp @@ -0,0 +1,82 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <memory> + +// template <class OuterAlloc, class... InnerAllocs> +// class scoped_allocator_adaptor + +// template <class T, class... Args> void construct(T* p, Args&& args); +// template <class T1, class T2, class... Args1, class... Args2> +// void construct(pair<T1, T2>* p, piecewise_construct t, tuple<Args1...> x, +// tuple<Args2...> y); +// template <class T1, class T2> +// void construct(pair<T1, T2>* p); +// template <class T1, class T2, class U, class V> +// void construct(pair<T1, T2>* p, U&& x, V&& y); +// template <class T1, class T2, class U, class V> +// void construct(pair<T1, T2>* p, const pair<U, V>& x); +// template <class T1, class T2, class U, class V> +// void construct(pair<T1, T2>* p, pair<U, V>&& x); + +#include <functional> +#include <list> +#include <scoped_allocator> +#include <cassert> + +#include "instrumentingallocators.h" + +namespace scoped { + +template <typename T> +using IA1 = std::scoped_allocator_adaptor<IA1<T>>; + +template <typename T> +using List1 = std::list<T, IA1<T>>; + +} + +int main() +{ + Instrumentation instrumentation; + { + typedef scoped::List1<int> List; + + List::allocator_type alloc(&instrumentation); + List list(alloc); + list.emplace_back(); + instrumentation.checkAllocsIncreased(); + list.emplace_back(list.back()); + instrumentation.checkAllocsIncreased(); + } + assert(instrumentation.allocs_.size() == 0); + { + typedef scoped::List1<scoped::List1<int>> List; + + List::allocator_type alloc(&instrumentation); + List list(alloc); + list.emplace_back(); + instrumentation.checkAllocsIncreased(); + list.emplace_back(list.back()); + instrumentation.checkAllocsIncreased(); + } + assert(instrumentation.allocs_.size() == 0); + { + typedef scoped::List1<std::function<int ()>> List; + + List::allocator_type alloc(&instrumentation); + List list(alloc); + list.emplace_back(); + instrumentation.checkAllocsIncreased(); + list.emplace_back(list.back()); + instrumentation.checkAllocsIncreased(); + } + assert(instrumentation.allocs_.size() == 0); +} +
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits