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. +// +//===----------------------------------------------------------------------===// + +// + +// template +// class scoped_allocator_adaptor + +// template void construct(T* p, Args&& args); +// template +// void construct(pair* p, piecewise_construct t, tuple x, +// tuple y); +// template +// void construct(pair* p); +// template +// void construct(pair* p, U&& x, V&& y); +// template +// void construct(pair* p, const pair& x); +// template +// void construct(pair* p, pair&& x); + +#include +#include +#include +#include + +#include "instrumentingallocators.h" + +namespace scoped { + +template +using IA1 = std::scoped_allocator_adaptor>; + +template +using List1 = std::list>; + +} + +int main() +{ + Instrumentation instrumentation; + { + typedef scoped::List1 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> 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> 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); +} + Index: test/support/instrumentingallocators.h =================================================================== --- /dev/null +++ test/support/instrumentingallocators.h @@ -0,0 +1,75 @@ +//===----------------------------------------------------------------------===// +// +// 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 INSTRUMENTINGALLOCATORS_H +#define INSTRUMENTINGALLOCATORS_H + +#include +#include + +struct Instrumentation { + typedef std::unordered_map Allocations; + + Allocations allocs_; + size_t numAllocs_ = 0; + size_t numDeallocs_ = 0; + size_t numAllocsLastChecked_ = 0; + + ~Instrumentation() { + assert(allocs_.empty()); + } + + void checkAllocsIncreased() { + assert(numAllocs_ > numAllocsLastChecked_); + numAllocsLastChecked_ = numAllocs_; + } +}; + +template +struct IA1 { + Instrumentation *instrumentation_; + + typedef T value_type; + + explicit IA1(Instrumentation *instrumentation) : + instrumentation_(instrumentation) {} + + template + IA1(const IA1& 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(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); + } +}; + +template +bool operator==(const IA1& lhs, const IA1& rhs) { + return lhs.instrumentation_ == rhs.instrumentation_; +} + +template +bool operator!=(const IA1& lhs, const IA1& rhs) { + return !(lhs == rhs); +} + +#endif