mirror of
https://github.com/boostorg/stl_interfaces.git
synced 2025-05-12 14:11:41 +00:00
Pass an rvalue to emplace_back() in unevaluated contexts that are testing its
existence. This is important for containers derived from sequence_container that constrain emplace_back() itself, and have a move-only value_type. Fixes #48.
This commit is contained in:
parent
29b990ba00
commit
e98536344d
@ -297,7 +297,7 @@ namespace boost { namespace stl_interfaces { BOOST_STL_INTERFACES_NAMESPACE_V1 {
|
||||
template<typename D = Derived>
|
||||
constexpr auto pop_back() noexcept -> decltype(
|
||||
std::declval<D &>().emplace_back(
|
||||
std::declval<typename D::value_type &>()),
|
||||
std::declval<typename D::value_type>()),
|
||||
(void)std::declval<D &>().erase(
|
||||
std::prev(std::declval<D &>().end())))
|
||||
{
|
||||
@ -806,8 +806,8 @@ namespace boost { namespace stl_interfaces { BOOST_STL_INTERFACES_NAMESPACE_V2 {
|
||||
}
|
||||
constexpr void pop_back() noexcept
|
||||
requires std::ranges::bidirectional_range<D> && std::ranges::common_range<D> &&
|
||||
requires (const std::ranges::range_value_t<D>& x, std::ranges::iterator_t<D> position) {
|
||||
derived().emplace_back(x);
|
||||
requires (std::ranges::range_value_t<D> x, std::ranges::iterator_t<D> position) {
|
||||
derived().emplace_back(std::move(x));
|
||||
derived().erase(position);
|
||||
} {
|
||||
return derived().erase(std::ranges::prev(std::ranges::end(derived())));
|
||||
|
@ -43,3 +43,13 @@ add_test_executable(detail)
|
||||
add_test_executable(static_vec)
|
||||
add_test_executable(static_vec_noncopyable)
|
||||
add_test_executable(array)
|
||||
|
||||
add_executable(
|
||||
compile_tests
|
||||
compile_tests_main.cpp
|
||||
compile_seq_cont_rvalue_constrained_pop_back.cpp
|
||||
)
|
||||
target_link_libraries(compile_tests stl_interfaces)
|
||||
if (clang_on_linux)
|
||||
target_link_libraries(compile_tests c++)
|
||||
endif ()
|
||||
|
@ -24,3 +24,5 @@ run static_vec_noncopyable.cpp ;
|
||||
run bidirectional.cpp ;
|
||||
run random_access.cpp ;
|
||||
run static_vec.cpp ;
|
||||
|
||||
compile compile_seq_cont_rvalue_constrained_pop_back.cpp ;
|
||||
|
116
test/compile_seq_cont_rvalue_constrained_pop_back.cpp
Normal file
116
test/compile_seq_cont_rvalue_constrained_pop_back.cpp
Normal file
@ -0,0 +1,116 @@
|
||||
// Copyright (C) 2021 T. Zachary Laine
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_STL_INTERFACES_USE_CONCEPTS
|
||||
|
||||
void compile_seq_cont_constrained_pop_back() {}
|
||||
|
||||
#else
|
||||
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/stl_interfaces/sequence_container_interface.hpp>
|
||||
|
||||
template<class T>
|
||||
struct container : boost::stl_interfaces::sequence_container_interface<
|
||||
container<T>,
|
||||
boost::stl_interfaces::element_layout::contiguous>
|
||||
{
|
||||
public:
|
||||
using super = boost::stl_interfaces::sequence_container_interface<
|
||||
container<T>,
|
||||
boost::stl_interfaces::element_layout::contiguous>;
|
||||
using container_type = std::vector<T>;
|
||||
|
||||
using value_type = typename container_type::value_type;
|
||||
using reference = typename container_type::reference;
|
||||
using const_reference = typename container_type::const_reference;
|
||||
using iterator = typename container_type::iterator;
|
||||
using const_iterator = typename container_type::const_iterator;
|
||||
using difference_type = typename container_type::difference_type;
|
||||
using size_type = typename container_type::size_type;
|
||||
|
||||
container() = default;
|
||||
container(const container &) = default;
|
||||
container(container &&) = default;
|
||||
~container() = default;
|
||||
container & operator=(const container &) = default;
|
||||
container & operator=(container &&) = default;
|
||||
|
||||
container(size_type count, const_reference value) : c(count, value) {}
|
||||
container(std::initializer_list<value_type> init) : c(init) {}
|
||||
|
||||
template<class InputIt>
|
||||
container(InputIt first, InputIt last) : c(first, last)
|
||||
{}
|
||||
|
||||
iterator begin() noexcept { return c.begin(); }
|
||||
iterator end() noexcept { return c.end(); }
|
||||
|
||||
size_type max_size() const noexcept { return c.max_size(); }
|
||||
|
||||
template<class InputIt>
|
||||
iterator insert(const_iterator pos, InputIt first, InputIt last)
|
||||
{
|
||||
return c.insert(pos, first, last);
|
||||
}
|
||||
|
||||
template<class... Args>
|
||||
iterator emplace(const_iterator pos, Args &&... args)
|
||||
{
|
||||
return c.emplace(pos, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
iterator erase(const_iterator first, const_iterator last)
|
||||
{
|
||||
return c.erase(first, last);
|
||||
}
|
||||
|
||||
template<class... Args>
|
||||
requires(std::constructible_from<value_type, Args &&...>) reference
|
||||
emplace_back(Args &&... args)
|
||||
{
|
||||
return c.emplace_back(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
void swap(container & other) { c.swap(other.c); }
|
||||
|
||||
using super::begin;
|
||||
using super::end;
|
||||
using super::insert;
|
||||
using super::erase;
|
||||
|
||||
private:
|
||||
container_type c;
|
||||
};
|
||||
|
||||
void compile_seq_cont_constrained_pop_back()
|
||||
{
|
||||
{
|
||||
std::vector<int> v;
|
||||
v.emplace_back(0);
|
||||
v.pop_back();
|
||||
|
||||
container<int> c;
|
||||
c.emplace_back(0);
|
||||
c.pop_back();
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<std::unique_ptr<int>> v;
|
||||
v.emplace_back(new int);
|
||||
v.pop_back();
|
||||
|
||||
container<std::unique_ptr<int>> c;
|
||||
c.emplace_back(new int);
|
||||
c.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
11
test/compile_tests_main.cpp
Normal file
11
test/compile_tests_main.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
// Copyright (C) 2021 T. Zachary Laine
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
void compile_seq_cont_constrained_pop_back();
|
||||
|
||||
int main()
|
||||
{
|
||||
compile_seq_cont_constrained_pop_back();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user