Implements N3644.

- Avoid deriving from std::iterator_traits as iterators become too fat.
- Use intrusive's reverse_iterator some std::reverse_iterator-s don't value initialize base.
This commit is contained in:
Ion Gaztañaga
2014-09-24 16:09:56 +02:00
parent 92e81fcf77
commit 3af96e0801
15 changed files with 298 additions and 42 deletions

View File

@@ -19,6 +19,8 @@
#include <boost/container/detail/workaround.hpp>
#include <boost/container/detail/preprocessor.hpp>
#include <boost/container/detail/iterators.hpp>
#include "varray_util.hpp"
#ifndef BOOST_NO_EXCEPTIONS
@@ -36,7 +38,6 @@
#include <boost/type_traits/alignment_of.hpp>
#include <boost/type_traits/aligned_storage.hpp>
#include <iterator>
/**
* @defgroup varray_non_member varray non-member functions
@@ -267,9 +268,9 @@ public:
//! @brief The const iterator type.
typedef const_pointer const_iterator;
//! @brief The reverse iterator type.
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef container_detail::reverse_iterator<iterator> reverse_iterator;
//! @brief The const reverse iterator.
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef container_detail::reverse_iterator<const_iterator> const_reverse_iterator;
//! @brief The type of a strategy used by the varray.
typedef Strategy strategy_type;
@@ -1895,8 +1896,8 @@ public:
typedef pointer iterator;
typedef const_pointer const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef container_detail::reverse_iterator<iterator> reverse_iterator;
typedef container_detail::reverse_iterator<const_iterator> const_reverse_iterator;
// nothrow
varray() {}

View File

@@ -712,7 +712,7 @@ Use them simply specifying the new allocator in the corresponding template argum
[endsect]
[section:Cpp11_conformance C++11 Conformance]
[section:Cpp11_conformance C++11/C++14 Conformance]
[*Boost.Container] aims for full C++11 conformance except reasoned deviations,
backporting as much as possible for C++03. Obviously, this conformance is a work
@@ -807,7 +807,28 @@ implements the C++11 changes that were specified in [@http://www.open-std.org/jt
[section:initializer_lists Initializer lists]
[*Boost.Container] supports initialization, assignments and insertions from initializer lists
but only in compilers that implement this feature.
in compilers that implement this feature.
[endsect]
[section:null_iterators Null Forward Iterators]
[*Boost.Container] implements
[@http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3644.pdf C++14 Null Forward Iterators],
which means that value-initialized iterators may be compared and compare equal
to other value-initialized iterators of the same type. Value initialized iterators behave as if they refer
past the end of the same empty sequence (example taken from N3644):
[c++]
vector<int> v = { ... };
auto ni = vector<int>::iterator();
auto nd = vector<double>::iterator();
ni == ni; // True.
nd != nd; // False.
v.begin() == ni; // ??? (likely false in practice).
v.end() == ni; // ??? (likely false in practice).
ni == nd; // Won<6F>t compile.
[endsect]

View File

@@ -146,7 +146,7 @@ class deque_iterator
{}
deque_iterator() BOOST_CONTAINER_NOEXCEPT
: m_cur(), m_first(), m_last(), m_node()
: m_cur(), m_first(), m_last(), m_node() //Value initialization to achieve "null iterators" (N3644)
{}
deque_iterator(deque_iterator<Pointer, false> const& x) BOOST_CONTAINER_NOEXCEPT
@@ -504,8 +504,8 @@ class deque : protected deque_base<Allocator>
typedef BOOST_CONTAINER_IMPDEF(allocator_type) stored_allocator_type;
typedef BOOST_CONTAINER_IMPDEF(typename Base::iterator) iterator;
typedef BOOST_CONTAINER_IMPDEF(typename Base::const_iterator) const_iterator;
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<iterator>) reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<const_iterator>) const_reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(container_detail::reverse_iterator<iterator>) reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(container_detail::reverse_iterator<const_iterator>) const_reverse_iterator;
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED

View File

@@ -85,13 +85,15 @@ struct get_flat_tree_iterators
pointer_traits<Pointer>:: template
rebind_pointer<const iterator_element_type>::type const_iterator;
#else //BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER
typedef typename container_detail::
typedef typename boost::container::container_detail::
vec_iterator<Pointer, false> iterator;
typedef typename container_detail::
typedef typename boost::container::container_detail::
vec_iterator<Pointer, true > const_iterator;
#endif //BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef boost::container::container_detail::
reverse_iterator<iterator> reverse_iterator;
typedef boost::container::container_detail::
reverse_iterator<const_iterator> const_reverse_iterator;
};
template <class Key, class Value, class KeyOfValue,

View File

@@ -20,10 +20,11 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/static_assert.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/intrusive/detail/iterator.hpp>
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/container/detail/variadic_templates_tools.hpp>
@@ -745,14 +746,15 @@ struct std_iterator<IIterator, false>
template<class IIterator, bool IsConst>
class iterator
: public std_iterator<IIterator, IsConst>::type
{
typedef typename std_iterator<IIterator, IsConst>::type types_t;
public:
typedef typename types_t::value_type value_type;
typedef typename types_t::pointer pointer;
typedef typename types_t::reference reference;
typedef typename types_t::difference_type difference_type;
typedef typename types_t::iterator_category iterator_category;
typedef typename types_t::value_type value_type;
iterator()
{}
@@ -808,6 +810,8 @@ class iterator
IIterator m_iit;
};
using ::boost::intrusive::detail::reverse_iterator;
} //namespace container_detail {
} //namespace container {
} //namespace boost {

View File

@@ -517,8 +517,8 @@ class tree
public:
typedef container_detail::iterator<iiterator, false> iterator;
typedef container_detail::iterator<iiterator, true > const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef container_detail::reverse_iterator<iterator> reverse_iterator;
typedef container_detail::reverse_iterator<const_iterator> const_reverse_iterator;
tree()
: AllocHolder(ValComp(key_compare()))

View File

@@ -199,8 +199,8 @@ class list
typedef BOOST_CONTAINER_IMPDEF(NodeAlloc) stored_allocator_type;
typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator;
typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator;
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<iterator>) reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<const_iterator>) const_reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(container_detail::reverse_iterator<iterator>) reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(container_detail::reverse_iterator<const_iterator>) const_reverse_iterator;
//////////////////////////////////////////////
//

View File

@@ -265,6 +265,7 @@ class stable_vector_iterator
{}
stable_vector_iterator() BOOST_CONTAINER_NOEXCEPT
: m_pn() //Value initialization to achieve "null iterators" (N3644)
{}
stable_vector_iterator(stable_vector_iterator<Pointer, false> const& other) BOOST_CONTAINER_NOEXCEPT
@@ -504,8 +505,8 @@ class stable_vector
typedef node_allocator_type stored_allocator_type;
typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator;
typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator;
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<iterator>) reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<const_iterator>) const_reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(container_detail::reverse_iterator<iterator>) reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(container_detail::reverse_iterator<const_iterator>) const_reverse_iterator;
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:

View File

@@ -539,8 +539,8 @@ class basic_string
typedef BOOST_CONTAINER_IMPDEF(allocator_type) stored_allocator_type;
typedef BOOST_CONTAINER_IMPDEF(pointer) iterator;
typedef BOOST_CONTAINER_IMPDEF(const_pointer) const_iterator;
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<iterator>) reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<const_iterator>) const_reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(container_detail::reverse_iterator<iterator>) reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(container_detail::reverse_iterator<const_iterator>) const_reverse_iterator;
static const size_type npos = size_type(-1);
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED

View File

@@ -102,11 +102,7 @@ class vec_iterator
//Constructors
vec_iterator() BOOST_CONTAINER_NOEXCEPT
#ifndef NDEBUG
: m_ptr()
#else
// No value initialization of m_ptr() to speed up things a bit:
#endif
: m_ptr() //Value initialization to achieve "null iterators" (N3644)
{}
vec_iterator(vec_iterator<Pointer, false> const& other) BOOST_CONTAINER_NOEXCEPT
@@ -573,8 +569,8 @@ class vector
typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator;
typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator;
#endif
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<iterator>) reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<const_iterator>) const_reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(container_detail::reverse_iterator<iterator>) reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(container_detail::reverse_iterator<const_iterator>) const_reverse_iterator;
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:

View File

@@ -171,6 +171,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "insert_vs_emplace_test", "i
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "null_iterators_test", "null_iterators_test.vcproj", "{C90520E3-B8A9-EB54-76E2-25DFA3C7762A}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
@@ -347,10 +351,12 @@ Global
{5C2D1813-24CE-A826-4FE5-5732251A3FAF}.Debug.Build.0 = Debug|Win32
{5C2D1813-24CE-A826-4FE5-5732251A3FAF}.Release.ActiveCfg = Release|Win32
{5C2D1813-24CE-A826-4FE5-5732251A3FAF}.Release.Build.0 = Release|Win32
{5E1C1C23-26A9-4FE5-A24E-DA735271C32B}.Debug.ActiveCfg = Debug|Win32
{5E1C1C23-26A9-4FE5-A24E-DA735271C32B}.Debug.Build.0 = Debug|Win32
{5E1C1C23-26A9-4FE5-A24E-DA735271C32B}.Release.ActiveCfg = Release|Win32
{5E1C1C23-26A9-4FE5-A24E-DA735271C32B}.Release.Build.0 = Release|Win32
{A1C1C223-26A9-A20E-4CE5-D3325271A7CB}.Debug.ActiveCfg = Debug|Win32
{A1C1C223-26A9-A20E-4CE5-D3325271A7CB}.Release.ActiveCfg = Release|Win32
{C90520E3-B8A9-EB54-76E2-25DFA3C7762A}.Debug.ActiveCfg = Debug|Win32
{C90520E3-B8A9-EB54-76E2-25DFA3C7762A}.Debug.Build.0 = Debug|Win32
{C90520E3-B8A9-EB54-76E2-25DFA3C7762A}.Release.ActiveCfg = Release|Win32
{C90520E3-B8A9-EB54-76E2-25DFA3C7762A}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection

View File

@@ -0,0 +1,128 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="null_iterators_test"
ProjectGUID="{C90520E3-B8A9-EB54-76E2-25DFA3C7762A}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/null_iterators_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
ExceptionHandling="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/null_iterators_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/null_iterators_test.pdb"
SubSystem="1"
TargetMachine="1"
FixedBaseAddress="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../Bin/Win32/Release"
IntermediateDirectory="Release/null_iterators_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/null_iterators_test.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
FixedBaseAddress="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<Files>
<File
RelativePath="..\..\test\null_iterators_test.cpp">
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -86,7 +86,7 @@ bool test_insert_with_expand_bwd()
value_type *memory = (value_type*)memptr.get();
std::vector<non_volatile_value_type> initial_data;
initial_data.resize(InitialSize[iteration]);
for(int i = 0; i < InitialSize[iteration]; ++i){
for(unsigned int i = 0; i < InitialSize[iteration]; ++i){
initial_data[i] = i;
}

View File

@@ -0,0 +1,97 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2014. 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)
//
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/vector.hpp>
#include <boost/container/deque.hpp>
#include <boost/container/stable_vector.hpp>
#include <boost/container/static_vector.hpp>
#include <boost/container/string.hpp>
#include <boost/container/list.hpp>
#include <boost/container/slist.hpp>
#include <boost/container/map.hpp>
#include <boost/container/set.hpp>
#include <boost/container/flat_set.hpp>
#include <boost/container/flat_map.hpp>
#include <boost/intrusive/detail/memory_util.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/aligned_storage.hpp>
#include <boost/static_assert.hpp>
#include <cstring>
#include <new>
using namespace boost::container;
typedef boost::aligned_storage<sizeof(void*)*4>::type buffer_t;
static buffer_t buffer_0x00;
static buffer_t buffer_0xFF;
template<class Iterator>
const Iterator &on_0x00_buffer()
{
BOOST_STATIC_ASSERT(sizeof(buffer_t) >= sizeof(Iterator));
return * ::new(std::memset(&buffer_0x00, 0x00, sizeof(buffer_0x00))) Iterator();
}
template<class Iterator>
const Iterator &on_0xFF_buffer()
{
BOOST_STATIC_ASSERT(sizeof(buffer_t) >= sizeof(Iterator));
return * ::new(std::memset(&buffer_0xFF, 0xFF, sizeof(buffer_0xFF))) Iterator();
}
namespace boost {
namespace container {
namespace test {
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(reverse_iterator)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_reverse_iterator)
}}} //namespace boost::container::test {
template<class Container>
void check_null_iterators()
{
typedef typename Container::iterator iterator;
typedef typename Container::const_iterator const_iterator;
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
(boost::container::test::, Container
,reverse_iterator, iterator) reverse_iterator;
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
(boost::container::test::, Container
,const_reverse_iterator, const_iterator) const_reverse_iterator;
BOOST_TEST(on_0xFF_buffer<iterator>() == on_0x00_buffer<iterator>());
BOOST_TEST(on_0xFF_buffer<const_iterator>() == on_0x00_buffer<const_iterator>());
BOOST_TEST(on_0xFF_buffer<reverse_iterator>() == on_0x00_buffer<reverse_iterator>());
BOOST_TEST(on_0xFF_buffer<const_reverse_iterator>() == on_0x00_buffer<const_reverse_iterator>());
}
int main()
{
check_null_iterators< vector<int> >();
check_null_iterators< deque<int> >();
check_null_iterators< stable_vector<int> >();
check_null_iterators< static_vector<int, 1> >();
check_null_iterators< string >();
check_null_iterators< list<int> >();
check_null_iterators< slist<int> >();
check_null_iterators< map<int, int> >();
check_null_iterators< multimap<int, int> >();
check_null_iterators< set<int> >();
check_null_iterators< multiset<int> >();
check_null_iterators< flat_set<int> >();
check_null_iterators< flat_multiset<int> >();
check_null_iterators< flat_map<int, int> >();
check_null_iterators< flat_multimap<int, int> >();
return boost::report_errors();
}

View File

@@ -115,7 +115,7 @@ enum ConstructionTypeEnum
{
ConstructiblePrefix,
ConstructibleSuffix,
NotUsesAllocator,
NotUsesAllocator
};
//This base class provices types for