//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// <list>
// UNSUPPORTED: c++03, no-exceptions
// TODO:
// - throwing upon moving;
// - initializer lists;
// - throwing when constructing the element in place.
// list(size_type n, const value_type& v);
// list(size_type n, const value_type& v, const allocator_type& a);
// template <class InputIterator>
// list(InputIterator first, InputIterator last);
// template <class InputIterator>
// list(InputIterator first, InputIterator last, const allocator_type& a);
// template<container-compatible-range<T> R>
// list(from_range_t, R&& rg, const Allocator& = Allocator()); // C++23
// list(const list& x);
// list(const list& x, const allocator_type& a);
//
// list& operator=(const list& x);
//
// template <class InputIterator>
// void assign(InputIterator first, InputIterator last);
// void assign(size_type n, const value_type& v);
// template<container-compatible-range<T> R>
// void assign_range(R&& rg); // C++23
//
// template<container-compatible-range<T> R>
// void prepend_range(R&& rg); // C++23
// void push_back(const value_type& x);
// template<container-compatible-range<T> R>
// void append_range(R&& rg); // C++23
// void push_front(const value_type& v);
//
// iterator insert(const_iterator p, const value_type& v);
// iterator insert(const_iterator p, size_type n, const value_type& v);
// template <class InputIterator>
// iterator insert(const_iterator p,
// InputIterator first, InputIterator last);
// template<container-compatible-range<T> R>
// iterator insert_range(const_iterator position, R&& rg); // C++23
//
// void resize(size_type n, const value_type& v);
#include <list>
#include <cassert>
#include "../../exception_safety_helpers.h"
#include "test_macros.h"
#if TEST_STD_VER >= 23
#include <ranges>
#endif
int main(int, char**) {
{
constexpr int ThrowOn = 1;
constexpr int Size = 1;
using T = ThrowingCopy<ThrowOn>;
// void push_front(const value_type& v);
test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T*){
std::list<T> c;
c.push_front(*from);
});
// void push_back(const value_type& v);
test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T*){
std::list<T> c;
c.push_back(*from);
});
// iterator insert(const_iterator p, const value_type& v);
test_exception_safety_throwing_copy</*ThrowOn=*/1, Size>([](T* from, T*){
std::list<T> c;
c.insert(c.end(), *from);
});
}
{
constexpr int ThrowOn = 3;
constexpr int Size = 5;
using T = ThrowingCopy<ThrowOn>;
using C = std::list<T>;
using Alloc = std::allocator<T>;
// list(size_type n, const value_type& v);
test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T*){
std::list<T> c(Size, *from);
(void)c;
});
// list(size_type n, const value_type& v, const allocator_type& a);
test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T*){
std::list<T> c(Size, *from, Alloc());
(void)c;
});
// template <class InputIterator>
// list(InputIterator first, InputIterator last);
test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T* to){
std::list<T> c(from, to);
(void)c;
});
// template <class InputIterator>
// list(InputIterator first, InputIterator last, const allocator_type& a);
test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T* to){
std::list<T> c(from, to, Alloc());
(void)c;
});
#if TEST_STD_VER >= 23
// template<container-compatible-range<T> R>
// list(from_range_t, R&& rg, const Allocator& = Allocator()); // C++23
test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T* to){
{
std::list<T> c(std::from_range, std::ranges::subrange(from, to));
(void)c;
}
{
std::list<T> c(std::from_range, std::ranges::subrange(from, to), Alloc());
(void)c;
}
});
#endif
// list(const list& x);
test_exception_safety_throwing_copy_container<C, ThrowOn, Size>([](C&& in) {
std::list<T> c(in);
(void)c;
});
// list(const list& x, const allocator_type& a);
test_exception_safety_throwing_copy_container<C, ThrowOn, Size>([](C&& in) {
std::list<T> c(in, Alloc());
(void)c;
});
// list& operator=(const list& x);
test_exception_safety_throwing_copy_container<C, ThrowOn, Size>([](C&& in) {
std::list<T> c;
c = in;
});
// template <class InputIterator>
// void assign(InputIterator first, InputIterator last);
test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T* to) {
std::list<T> c;
c.assign(from, to);
});
#if TEST_STD_VER >= 23
// template<container-compatible-range<T> R>
// void assign_range(R&& rg); // C++23
test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T* to) {
std::list<T> c;
c.assign_range(std::ranges::subrange(from, to));
});
#endif
// void assign(size_type n, const value_type& v);
test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T*) {
std::list<T> c;
c.assign(Size, *from);
});
#if TEST_STD_VER >= 23
// template<container-compatible-range<T> R>
// void prepend_range(R&& rg); // C++23
test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T* to) {
std::list<T> c;
c.prepend_range(std::ranges::subrange(from, to));
});
// template<container-compatible-range<T> R>
// void append_range(R&& rg); // C++23
test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T* to) {
std::list<T> c;
c.append_range(std::ranges::subrange(from, to));
});
#endif
// iterator insert(const_iterator p, size_type n, const value_type& v);
test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T*) {
std::list<T> c;
c.insert(c.end(), Size, *from);
});
// template <class InputIterator>
// iterator insert(const_iterator p,
// InputIterator first, InputIterator last);
test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T* to) {
std::list<T> c;
c.insert(c.end(), from, to);
});
#if TEST_STD_VER >= 23
// template<container-compatible-range<T> R>
// iterator insert_range(const_iterator position, R&& rg); // C++23
test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T* to) {
std::list<T> c;
c.insert_range(c.end(), std::ranges::subrange(from, to));
});
#endif
// void resize(size_type n, const value_type& v);
test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T*) {
std::list<T> c;
c.resize(Size, *from);
});
}
return 0;
}