blob: 9a437cfedbe5f865cf82d2cdaf3e76635415ab23 [file] [log] [blame]
// Copyright (C) 2016-2021 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// { dg-do compile { target c++11 } }
#include <vector>
struct Tag { };
template<typename T>
struct TaggingAllocator
{
using value_type = T;
TaggingAllocator() = default;
template<typename U>
TaggingAllocator(const TaggingAllocator<U>&) { }
T*
allocate(std::size_t n) { return std::allocator<T>{}.allocate(n); }
void
deallocate(T* p, std::size_t n) { std::allocator<T>{}.deallocate(p, n); }
template<typename U, typename... Args>
void
construct(U* p, Args&&... args)
{ ::new((void*)p) U(Tag{}, std::forward<Args>(args)...); }
template<typename U, typename... Args>
void
destroy(U* p)
{ p->~U(); }
};
template<typename T, typename U>
bool
operator==(const TaggingAllocator<T>&, const TaggingAllocator<U>&)
{ return true; }
template<typename T, typename U>
bool
operator!=(const TaggingAllocator<T>&, const TaggingAllocator<U>&)
{ return false; }
struct X
{
// All constructors must be passed the Tag type.
// DefaultInsertable into vector<X, TaggingAllocator<X>>,
X(Tag) { }
// CopyInsertable into vector<X, TaggingAllocator<X>>,
X(Tag, const X&) { }
// MoveInsertable into vector<X, TaggingAllocator<X>>, and
X(Tag, X&&) { }
// EmplaceConstructible into vector<X, TaggingAllocator<X>> from args.
template<typename... Args>
X(Tag, Args&&...) { }
// not DefaultConstructible, CopyConstructible or MoveConstructible.
X() = delete;
X(const X&) = delete;
X(X&&) = delete;
// CopyAssignable.
X& operator=(const X&) { return *this; }
// MoveAssignable.
X& operator=(X&&) { return *this; }
private:
// Not Destructible.
~X() { }
// Erasable from vector<X, TaggingAllocator<X>>.
friend class TaggingAllocator<X>;
};
template class std::vector<X, TaggingAllocator<X>>;
void test01()
{
std::vector<X, TaggingAllocator<X>> v;
v.reserve(3);
v.emplace_back();
v.emplace(v.begin());
v.emplace(v.begin(), 1, 2, 3);
}