mirror of
https://github.com/boostorg/container.git
synced 2025-08-02 05:54:28 +02:00
Fixes #150 ("Use std::contiguous_iterator_tag if available"), tested in MSVC and GCC.
This commit is contained in:
@@ -1341,6 +1341,7 @@ use [*Boost.Container]? There are several reasons for that:
|
|||||||
[section:release_notes_boost_1_77_00 Boost 1.77 Release]
|
[section:release_notes_boost_1_77_00 Boost 1.77 Release]
|
||||||
|
|
||||||
* Fixed bugs/issues:
|
* Fixed bugs/issues:
|
||||||
|
* [@https://github.com/boostorg/container/issues/150 GitHub #150: ['"Use std::contiguous_iterator_tag if available"]].
|
||||||
* [@https://github.com/boostorg/container/issues/184 GitHub #184: ['"Issues with custom exceptions implementation"]].
|
* [@https://github.com/boostorg/container/issues/184 GitHub #184: ['"Issues with custom exceptions implementation"]].
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
@@ -53,6 +53,9 @@ struct allocator_arg_t;
|
|||||||
|
|
||||||
struct piecewise_construct_t;
|
struct piecewise_construct_t;
|
||||||
|
|
||||||
|
template <class Ptr>
|
||||||
|
struct pointer_traits;
|
||||||
|
|
||||||
BOOST_MOVE_STD_NS_END
|
BOOST_MOVE_STD_NS_END
|
||||||
#include <boost/move/detail/std_ns_end.hpp>
|
#include <boost/move/detail/std_ns_end.hpp>
|
||||||
|
|
||||||
|
@@ -82,7 +82,17 @@ class vec_iterator
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::random_access_iterator_tag iterator_category;
|
typedef std::random_access_iterator_tag iterator_category;
|
||||||
|
typedef std::contiguous_iterator_tag iterator_concept;
|
||||||
typedef typename boost::intrusive::pointer_traits<Pointer>::element_type value_type;
|
typedef typename boost::intrusive::pointer_traits<Pointer>::element_type value_type;
|
||||||
|
|
||||||
|
//Defining element_type to make libstdc++'s std::pointer_traits well-formed leads to ambiguity
|
||||||
|
//due to LWG3446. So we need to specialize std::pointer_traits. See
|
||||||
|
//https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96416 for details. /Many thanks to Jonathan Wakely
|
||||||
|
//for explaning the issue.
|
||||||
|
#ifndef BOOST_GNU_STDLIB
|
||||||
|
//Define element_
|
||||||
|
typedef typename boost::intrusive::pointer_traits<Pointer>::element_type element_type;
|
||||||
|
#endif
|
||||||
typedef typename boost::intrusive::pointer_traits<Pointer>::difference_type difference_type;
|
typedef typename boost::intrusive::pointer_traits<Pointer>::difference_type difference_type;
|
||||||
typedef typename dtl::if_c
|
typedef typename dtl::if_c
|
||||||
< IsConst
|
< IsConst
|
||||||
@@ -3378,6 +3388,20 @@ struct has_trivial_destructor_after_move<boost::container::vector<T, Allocator,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//See comments on vec_iterator::element_type to know why is this needed
|
||||||
|
#ifdef BOOST_GNU_STDLIB
|
||||||
|
|
||||||
|
BOOST_MOVE_STD_NS_BEG
|
||||||
|
|
||||||
|
template <class Pointer, bool IsConst>
|
||||||
|
struct pointer_traits< boost::container::vec_iterator<Pointer, IsConst> >
|
||||||
|
: public boost::intrusive::pointer_traits< boost::container::vec_iterator<Pointer, IsConst> >
|
||||||
|
{};
|
||||||
|
|
||||||
|
BOOST_MOVE_STD_NS_END
|
||||||
|
|
||||||
|
#endif //BOOST_GNU_STDLIB
|
||||||
|
|
||||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||||
|
|
||||||
#include <boost/container/detail/config_end.hpp>
|
#include <boost/container/detail/config_end.hpp>
|
||||||
|
@@ -194,7 +194,25 @@ bool test_merge_empty_free()
|
|||||||
vector< int, check_dealloc_allocator<int> > empty;
|
vector< int, check_dealloc_allocator<int> > empty;
|
||||||
empty.merge(source.begin(), source.end());
|
empty.merge(source.begin(), source.end());
|
||||||
|
|
||||||
return empty.get_stored_allocator().deallocate_called_without_allocate_;
|
return !empty.get_stored_allocator().deallocate_called_without_allocate_;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cpp_lib_span
|
||||||
|
#include <span>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool test_span_conversion()
|
||||||
|
{
|
||||||
|
#ifdef __cpp_lib_span
|
||||||
|
{
|
||||||
|
boost::container::vector myVec{1, 2, 3, 4, 5};
|
||||||
|
std::span mySpan1{myVec}; // (1)
|
||||||
|
std::span mySpan2{myVec.data(), myVec.size()}; // (2)
|
||||||
|
return mySpan1.size() == myVec.size() && mySpan1.size() == mySpan2.size();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
@@ -331,11 +349,16 @@ int main()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (test_merge_empty_free()) {
|
if (!test_merge_empty_free()) {
|
||||||
std::cerr << "Merge into empty vector test failed" << std::endl;
|
std::cerr << "Merge into empty vector test failed" << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!test_span_conversion()) {
|
||||||
|
std::cerr << "Span conversion failed" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////
|
////////////////////////////////////
|
||||||
// has_trivial_destructor_after_move testing
|
// has_trivial_destructor_after_move testing
|
||||||
////////////////////////////////////
|
////////////////////////////////////
|
||||||
|
Reference in New Issue
Block a user