// Copyright (C) 2016-2022 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 // . // { dg-do compile { target c++11 } } #include template struct alloc { using value_type = T; alloc() = default; template alloc(alloc) { } T* allocate(std::size_t); void deallocate(T*, std::size_t); }; template bool operator==(alloc, alloc) { return true; } template bool operator!=(alloc, alloc) { return false; } struct X { using allocator_type = alloc; X(const allocator_type&); }; template struct nested_alloc : A { nested_alloc() = default; template nested_alloc(nested_alloc) { } // Need to customize rebind, otherwise nested_alloc> gets rebound // to nested_alloc. template struct rebind { using other = typename std::allocator_traits::template rebind_alloc; }; A& outer_allocator() { return *this; } template void construct(U*, Args&&...) { static_assert(!std::is_same::value, "OUTERMOST should recurse and use alloc to construct X"); } }; template bool operator==(nested_alloc l, nested_alloc r) { return l.outer_allocator() == r.outer_allocator(); } template bool operator!=(nested_alloc l, nested_alloc r) { return !(l == r); } template using scoped_alloc = std::scoped_allocator_adaptor; void test01() { scoped_alloc>> a; alignas(X) char buf[sizeof(X)]; X* p = (X*)buf; // Test that OUTERMOST is recursive and doesn't just unwrap one level: a.construct(p); } void test02() { scoped_alloc>>> a; alignas(X) char buf[sizeof(X)]; X* p = (X*)buf; // Test that OUTERMOST is recursive and doesn't just unwrap one level: a.construct(p); }