Implemented N3644 (Null Forward Iterators)

This commit is contained in:
Ion Gaztañaga
2014-09-24 15:28:44 +02:00
parent 336b83e4b1
commit 1f24efd1ed
8 changed files with 380 additions and 110 deletions

View File

@ -3764,6 +3764,7 @@ to be inserted in intrusive containers are allocated using `std::vector` or `std
[section:release_notes_boost_1_57_00 Boost 1.57 Release]
* Experimental version of node checkers, contributed by Matei David. Many thanks!
* Implemented [@http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3644.pdf N3644: Null Forward Iterators] from C++14.
* Fixed bugs:
* [@https://github.com/boostorg/intrusive/pull/12 GitHub #12: ['Fix MSVC14 warning C4456: declaration of 'x_parent_right' hides previous local declaration]]

View File

@ -256,6 +256,7 @@ class hashtable_iterator
typedef typename iterator_traits::iterator_category iterator_category;
hashtable_iterator ()
: slist_it_() //Value initialization to achieve "null iterators" (N3644)
{}
explicit hashtable_iterator(siterator ptr, const BucketValueTraits *cont)

View File

@ -0,0 +1,137 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-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/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP
#define BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <iterator>
namespace boost {
namespace intrusive {
namespace detail {
template<class It>
class reverse_iterator
: public std::iterator<
typename std::iterator_traits<It>::iterator_category,
typename std::iterator_traits<It>::value_type,
typename std::iterator_traits<It>::difference_type,
typename std::iterator_traits<It>::pointer,
typename std::iterator_traits<It>::reference>
{
public:
typedef typename std::iterator_traits<It>::pointer pointer;
typedef typename std::iterator_traits<It>::reference reference;
typedef typename std::iterator_traits<It>::difference_type difference_type;
typedef It iterator_type;
reverse_iterator()
: m_current() //Value initialization to achieve "null iterators" (N3644)
{}
explicit reverse_iterator(It r)
: m_current(r)
{}
template<class OtherIt>
reverse_iterator(const reverse_iterator<OtherIt>& r)
: m_current(r.base())
{}
It base() const
{ return m_current; }
reference operator*() const
{ It temp(m_current); --temp; return *temp; }
pointer operator->() const
{ It temp(m_current); --temp; return temp.operator->(); }
reference operator[](difference_type off) const
{ return this->m_current[-off]; }
reverse_iterator& operator++()
{ --m_current; return *this; }
reverse_iterator operator++(int)
{
reverse_iterator temp = *this;
--m_current;
return temp;
}
reverse_iterator& operator--()
{
++m_current;
return *this;
}
reverse_iterator operator--(int)
{
reverse_iterator temp(*this);
++m_current;
return temp;
}
friend bool operator==(const reverse_iterator& l, const reverse_iterator& r)
{ return l.m_current == r.m_current; }
friend bool operator!=(const reverse_iterator& l, const reverse_iterator& r)
{ return l.m_current != r.m_current; }
friend bool operator<(const reverse_iterator& l, const reverse_iterator& r)
{ return l.m_current < r.m_current; }
friend bool operator<=(const reverse_iterator& l, const reverse_iterator& r)
{ return l.m_current <= r.m_current; }
friend bool operator>(const reverse_iterator& l, const reverse_iterator& r)
{ return l.m_current > r.m_current; }
friend bool operator>=(const reverse_iterator& l, const reverse_iterator& r)
{ return l.m_current >= r.m_current; }
reverse_iterator& operator+=(difference_type off)
{ m_current -= off; return *this; }
friend reverse_iterator operator+(const reverse_iterator & l, difference_type off)
{
reverse_iterator tmp(l.m_current);
tmp.m_current -= off;
return tmp;
}
reverse_iterator& operator-=(difference_type off)
{ m_current += off; return *this; }
friend reverse_iterator operator-(const reverse_iterator & l, difference_type off)
{
reverse_iterator tmp(l.m_current);
tmp.m_current += off;
return tmp;
}
friend difference_type operator-(const reverse_iterator& l, const reverse_iterator& r)
{ return r.m_current - l.m_current; }
private:
It m_current; // the wrapped iterator
};
} //namespace detail
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP

View File

@ -22,6 +22,7 @@
#include <boost/intrusive/detail/assert.hpp>
#include <boost/intrusive/detail/is_stateful_value_traits.hpp>
#include <boost/intrusive/detail/memory_util.hpp>
#include <boost/intrusive/detail/iterator.hpp>
#include <boost/cstdint.hpp>
#include <cstddef>
#include <climits>
@ -797,115 +798,6 @@ class array_initializer
detail::max_align rawbuf[(N*sizeof(T)-1)/sizeof(detail::max_align)+1];
};
template<class It>
class reverse_iterator
: public std::iterator<
typename std::iterator_traits<It>::iterator_category,
typename std::iterator_traits<It>::value_type,
typename std::iterator_traits<It>::difference_type,
typename std::iterator_traits<It>::pointer,
typename std::iterator_traits<It>::reference>
{
public:
typedef typename std::iterator_traits<It>::pointer pointer;
typedef typename std::iterator_traits<It>::reference reference;
typedef typename std::iterator_traits<It>::difference_type difference_type;
typedef It iterator_type;
reverse_iterator(){}
explicit reverse_iterator(It r)
: m_current(r)
{}
template<class OtherIt>
reverse_iterator(const reverse_iterator<OtherIt>& r)
: m_current(r.base())
{}
It base() const
{ return m_current; }
reference operator*() const
{ It temp(m_current); --temp; return *temp; }
pointer operator->() const
{ It temp(m_current); --temp; return temp.operator->(); }
reference operator[](difference_type off) const
{ return this->m_current[-off]; }
reverse_iterator& operator++()
{ --m_current; return *this; }
reverse_iterator operator++(int)
{
reverse_iterator temp = *this;
--m_current;
return temp;
}
reverse_iterator& operator--()
{
++m_current;
return *this;
}
reverse_iterator operator--(int)
{
reverse_iterator temp(*this);
++m_current;
return temp;
}
friend bool operator==(const reverse_iterator& l, const reverse_iterator& r)
{ return l.m_current == r.m_current; }
friend bool operator!=(const reverse_iterator& l, const reverse_iterator& r)
{ return l.m_current != r.m_current; }
friend bool operator<(const reverse_iterator& l, const reverse_iterator& r)
{ return l.m_current < r.m_current; }
friend bool operator<=(const reverse_iterator& l, const reverse_iterator& r)
{ return l.m_current <= r.m_current; }
friend bool operator>(const reverse_iterator& l, const reverse_iterator& r)
{ return l.m_current > r.m_current; }
friend bool operator>=(const reverse_iterator& l, const reverse_iterator& r)
{ return l.m_current >= r.m_current; }
reverse_iterator& operator+=(difference_type off)
{ m_current -= off; return *this; }
friend reverse_iterator operator+(const reverse_iterator & l, difference_type off)
{
reverse_iterator tmp(l.m_current);
tmp.m_current -= off;
return tmp;
}
reverse_iterator& operator-=(difference_type off)
{ m_current += off; return *this; }
friend reverse_iterator operator-(const reverse_iterator & l, difference_type off)
{
reverse_iterator tmp(l.m_current);
tmp.m_current += off;
return tmp;
}
friend difference_type operator-(const reverse_iterator& l, const reverse_iterator& r)
{ return r.m_current - l.m_current; }
private:
It m_current; // the wrapped iterator
};
template<class ConstNodePtr>
struct uncast_types
{
@ -1223,6 +1115,7 @@ struct iiterator_members
{
iiterator_members()
: nodeptr_()//Value initialization to achieve "null iterators" (N3644)
{}
iiterator_members(const NodePtr &n_ptr, const StoredPointer &data)
@ -1240,6 +1133,7 @@ template<class NodePtr, class StoredPointer>
struct iiterator_members<NodePtr, StoredPointer, false>
{
iiterator_members()
: nodeptr_()//Value initialization to achieve "null iterators" (N3644)
{}
iiterator_members(const NodePtr &n_ptr, const StoredPointer &)

View File

@ -123,6 +123,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "parent_from_member", "paren
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "null_iterator", "null_iterator\null_iterator.vcproj", "{32A79B10-B2A0-C1B8-9458-9456152413B5}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
@ -255,6 +259,10 @@ Global
{3A279B10-2A0B-B8C1-5894-9461524135B5}.Debug.Build.0 = Debug|Win32
{3A279B10-2A0B-B8C1-5894-9461524135B5}.Release.ActiveCfg = Release|Win32
{3A279B10-2A0B-B8C1-5894-9461524135B5}.Release.Build.0 = Release|Win32
{32A79B10-B2A0-C1B8-9458-9456152413B5}.Debug.ActiveCfg = Debug|Win32
{32A79B10-B2A0-C1B8-9458-9456152413B5}.Debug.Build.0 = Debug|Win32
{32A79B10-B2A0-C1B8-9458-9456152413B5}.Release.ActiveCfg = Release|Win32
{32A79B10-B2A0-C1B8-9458-9456152413B5}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection

View File

@ -259,6 +259,9 @@
<File
RelativePath="..\..\..\..\..\boost\intrusive\detail\is_stateful_value_traits.hpp">
</File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\detail\iterator.hpp">
</File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\detail\list_node.hpp">
</File>

View File

@ -0,0 +1,128 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="null_iterator"
ProjectGUID="{32A79B10-B2A0-C1B8-9458-9456152413B5}"
RootNamespace="virtual_base"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../../../"
PreprocessorDefinitions="BOOST_DATE_TIME_NO_LIB"
GeneratePreprocessedFile="0"
KeepComments="FALSE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
DisableLanguageExtensions="FALSE"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/null_iterator.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/null_iterator.pdb"
GenerateMapFile="TRUE"
SubSystem="1"
TargetMachine="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="Release"
IntermediateDirectory="Release"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../../../"
PreprocessorDefinitions="BOOST_DATE_TIME_NO_LIB"
RuntimeLibrary="4"
DisableLanguageExtensions="FALSE"
ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/null_iterator.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="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>
<References>
</References>
<Files>
<File
RelativePath="..\..\..\test\null_iterator_test.cpp">
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,98 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Howard Hinnant 2014.
// (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/intrusive/list.hpp>
#include <boost/intrusive/slist.hpp>
#include <boost/intrusive/bs_set.hpp>
#include <boost/intrusive/set.hpp>
#include <boost/intrusive/avl_set.hpp>
#include <boost/intrusive/sg_set.hpp>
#include <boost/intrusive/treap_set.hpp>
#include <boost/intrusive/splay_set.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::intrusive;
#include <boost/intrusive/detail/memory_util.hpp>
struct Type
: list_base_hook<>
, slist_base_hook<>
, set_base_hook<>
, avl_set_base_hook<>
, bs_set_base_hook<>
{};
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();
}
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(reverse_iterator)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_reverse_iterator)
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
(::, Container
,reverse_iterator, iterator) reverse_iterator;
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
(::, 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< list<Type> >();
check_null_iterators< slist<Type> >();
check_null_iterators< bs_set<Type> >();
check_null_iterators< set<Type> >();
check_null_iterators< multiset<Type> >();
check_null_iterators< avl_set<Type> >();
check_null_iterators< avl_multiset<Type> >();
check_null_iterators< sg_set<Type> >();
check_null_iterators< sg_multiset<Type> >();
check_null_iterators< treap_set<Type> >();
check_null_iterators< treap_multiset<Type> >();
check_null_iterators< splay_set<Type> >();
check_null_iterators< splay_multiset<Type> >();
return boost::report_errors();
}