Added stress-map-iter-erase test for erase_at()
authorkhizmax <libcds.dev@gmail.com>
Sun, 12 Mar 2017 08:31:45 +0000 (11:31 +0300)
committerkhizmax <libcds.dev@gmail.com>
Sun, 12 Mar 2017 08:31:45 +0000 (11:31 +0300)
12 files changed:
projects/Win/vc14/cds.sln
projects/Win/vc14/stress-map-iter-erase.vcxproj [new file with mode: 0644]
projects/Win/vc141/cds.sln
projects/Win/vc141/stress-map-iter-erase.vcxproj [new file with mode: 0644]
test/stress/map/CMakeLists.txt
test/stress/map/iter_erase/CMakeLists.txt [new file with mode: 0644]
test/stress/map/iter_erase/map_iter_erase.cpp [new file with mode: 0644]
test/stress/map/iter_erase/map_iter_erase.h [new file with mode: 0644]
test/stress/map/iter_erase/map_iter_erase_feldman_hashmap.cpp [new file with mode: 0644]
test/stress/map/iter_erase/map_iter_erase_michael.cpp [new file with mode: 0644]
test/stress/map/iter_erase/map_iter_erase_split.cpp [new file with mode: 0644]
test/stress/map/map_type_feldman_hashmap.h

index dab5f4a..176148a 100644 (file)
@@ -415,7 +415,13 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stress-map-minmax", "stress
 EndProject\r
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stress-set-iter-erase", "stress-set-iter-erase.vcxproj", "{A717715D-CA08-4111-8A0E-B69A6DE3FF38}"\r
        ProjectSection(ProjectDependencies) = postProject\r
-               {79A6845E-85BF-4000-94FF-9DF2473460D4} = {79A6845E-85BF-4000-94FF-9DF2473460D4}\r
+               {A34CED07-A442-4FA1-81C4-F8B9CD3C832B} = {A34CED07-A442-4FA1-81C4-F8B9CD3C832B}\r
+               {408FE9BC-44F0-4E6A-89FA-D6F952584239} = {408FE9BC-44F0-4E6A-89FA-D6F952584239}\r
+       EndProjectSection\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stress-map-iter-erase", "stress-map-iter-erase.vcxproj", "{48B8CA78-E7A9-4666-976B-2B87F58B7906}"\r
+       ProjectSection(ProjectDependencies) = postProject\r
+               {A34CED07-A442-4FA1-81C4-F8B9CD3C832B} = {A34CED07-A442-4FA1-81C4-F8B9CD3C832B}\r
                {408FE9BC-44F0-4E6A-89FA-D6F952584239} = {408FE9BC-44F0-4E6A-89FA-D6F952584239}\r
        EndProjectSection\r
 EndProject\r
@@ -1197,6 +1203,18 @@ Global
                {A717715D-CA08-4111-8A0E-B69A6DE3FF38}.Release|Win32.Build.0 = Release|Win32\r
                {A717715D-CA08-4111-8A0E-B69A6DE3FF38}.Release|x64.ActiveCfg = Release|x64\r
                {A717715D-CA08-4111-8A0E-B69A6DE3FF38}.Release|x64.Build.0 = Release|x64\r
+               {48B8CA78-E7A9-4666-976B-2B87F58B7906}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {48B8CA78-E7A9-4666-976B-2B87F58B7906}.Debug|Win32.Build.0 = Debug|Win32\r
+               {48B8CA78-E7A9-4666-976B-2B87F58B7906}.Debug|x64.ActiveCfg = Debug|x64\r
+               {48B8CA78-E7A9-4666-976B-2B87F58B7906}.Debug|x64.Build.0 = Debug|x64\r
+               {48B8CA78-E7A9-4666-976B-2B87F58B7906}.DebugVLD|Win32.ActiveCfg = DebugVLD|Win32\r
+               {48B8CA78-E7A9-4666-976B-2B87F58B7906}.DebugVLD|Win32.Build.0 = DebugVLD|Win32\r
+               {48B8CA78-E7A9-4666-976B-2B87F58B7906}.DebugVLD|x64.ActiveCfg = DebugVLD|x64\r
+               {48B8CA78-E7A9-4666-976B-2B87F58B7906}.DebugVLD|x64.Build.0 = DebugVLD|x64\r
+               {48B8CA78-E7A9-4666-976B-2B87F58B7906}.Release|Win32.ActiveCfg = Release|Win32\r
+               {48B8CA78-E7A9-4666-976B-2B87F58B7906}.Release|Win32.Build.0 = Release|Win32\r
+               {48B8CA78-E7A9-4666-976B-2B87F58B7906}.Release|x64.ActiveCfg = Release|x64\r
+               {48B8CA78-E7A9-4666-976B-2B87F58B7906}.Release|x64.Build.0 = Release|x64\r
        EndGlobalSection\r
        GlobalSection(SolutionProperties) = preSolution\r
                HideSolutionNode = FALSE\r
@@ -1277,6 +1295,7 @@ Global
                {E91A1938-BB89-4676-9C9F-69AA697CB488} = {0D83E8C7-97D1-4BA1-928A-6846E7089652}\r
                {A0BC5155-F91B-4F89-B775-BB09A54EDB73} = {7D3EE35B-185D-40B5-88C2-7F9933426978}\r
                {A717715D-CA08-4111-8A0E-B69A6DE3FF38} = {0D83E8C7-97D1-4BA1-928A-6846E7089652}\r
+               {48B8CA78-E7A9-4666-976B-2B87F58B7906} = {7D3EE35B-185D-40B5-88C2-7F9933426978}\r
        EndGlobalSection\r
        GlobalSection(DPCodeReviewSolutionGUID) = preSolution\r
                DPCodeReviewSolutionGUID = {00000000-0000-0000-0000-000000000000}\r
diff --git a/projects/Win/vc14/stress-map-iter-erase.vcxproj b/projects/Win/vc14/stress-map-iter-erase.vcxproj
new file mode 100644 (file)
index 0000000..52a3dc9
--- /dev/null
@@ -0,0 +1,253 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="DebugVLD|Win32">
+      <Configuration>DebugVLD</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugVLD|x64">
+      <Configuration>DebugVLD</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\test\stress\main.cpp" />
+    <ClCompile Include="..\..\..\test\stress\map\iter_erase\map_iter_erase.cpp" />
+    <ClCompile Include="..\..\..\test\stress\map\iter_erase\map_iter_erase_feldman_hashmap.cpp" />
+    <ClCompile Include="..\..\..\test\stress\map\iter_erase\map_iter_erase_michael.cpp" />
+    <ClCompile Include="..\..\..\test\stress\map\iter_erase\map_iter_erase_split.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <Text Include="..\..\..\test\stress\map\iter_erase\CMakeLists.txt" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\test\stress\map\iter_erase\map_iter_erase.h" />
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{48B8CA78-E7A9-4666-976B-2B87F58B7906}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>stress_map_iter_erase</RootNamespace>
+    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+    <ProjectName>stress-map-iter-erase</ProjectName>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)\</OutDir>
+    <IntDir>$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
+    <TargetName>$(ProjectName)_d</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)\</OutDir>
+    <IntDir>$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
+    <TargetName>$(ProjectName)_d</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)\</OutDir>
+    <IntDir>$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
+    <TargetName>$(ProjectName)_d</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)\</OutDir>
+    <IntDir>$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
+    <TargetName>$(ProjectName)_d</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)-release\</OutDir>
+    <IntDir>$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)-release\</OutDir>
+    <IntDir>$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>DebugFastLink</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>$(GTEST_LIB32);$(GTEST_ROOT)/lib/x86;$(BOOST_PATH)/stage32/lib;$(BOOST_PATH)/stage/lib;$(BOOST_PATH)/bin;%(AdditionalLibraryDirectories);$(OutDir)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>gtestd.lib;stress-framework_d.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>DebugFastLink</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>$(GTEST_LIB32);$(GTEST_ROOT)/lib/x86;$(BOOST_PATH)/stage32/lib;$(BOOST_PATH)/stage/lib;$(BOOST_PATH)/bin;%(AdditionalLibraryDirectories);$(OutDir)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>gtestd.lib;stress-framework_d.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>DebugFastLink</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>$(GTEST_LIB64);$(GTEST_ROOT)/lib/x64;$(BOOST_PATH)/stage64/lib;$(BOOST_PATH)/bin;%(AdditionalLibraryDirectories);$(OutDir)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>gtestd.lib;stress-framework_d.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>DebugFastLink</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>$(GTEST_LIB64);$(GTEST_ROOT)/lib/x64;$(BOOST_PATH)/stage64/lib;$(BOOST_PATH)/bin;%(AdditionalLibraryDirectories);$(OutDir)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>gtestd.lib;stress-framework_d.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>_ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>$(GTEST_LIB32);$(GTEST_ROOT)/lib/x86;$(BOOST_PATH)/stage32/lib;$(BOOST_PATH)/stage/lib;$(BOOST_PATH)/bin;%(AdditionalLibraryDirectories);$(OutDir)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>gtest.lib;stress-framework.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>_ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>$(GTEST_LIB64);$(GTEST_ROOT)/lib/x64;$(BOOST_PATH)/stage64/lib;$(BOOST_PATH)/bin;%(AdditionalLibraryDirectories);$(OutDir)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>gtest.lib;stress-framework.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
index 5224c9d..bed5f98 100644 (file)
@@ -419,6 +419,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stress-set-iter-erase", "st
                {408FE9BC-44F0-4E6A-89FA-D6F952584239} = {408FE9BC-44F0-4E6A-89FA-D6F952584239}
        EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stress-map-iter-erase", "stress-map-iter-erase.vcxproj", "{48B8CA78-E7A9-4666-976B-2B87F58B7906}"
+       ProjectSection(ProjectDependencies) = postProject
+               {A34CED07-A442-4FA1-81C4-F8B9CD3C832B} = {A34CED07-A442-4FA1-81C4-F8B9CD3C832B}
+               {408FE9BC-44F0-4E6A-89FA-D6F952584239} = {408FE9BC-44F0-4E6A-89FA-D6F952584239}
+       EndProjectSection
+EndProject
 Global
        GlobalSection(SolutionConfigurationPlatforms) = preSolution
                Debug|Win32 = Debug|Win32
@@ -1197,6 +1203,18 @@ Global
                {A717715D-CA08-4111-8A0E-B69A6DE3FF38}.Release|Win32.Build.0 = Release|Win32
                {A717715D-CA08-4111-8A0E-B69A6DE3FF38}.Release|x64.ActiveCfg = Release|x64
                {A717715D-CA08-4111-8A0E-B69A6DE3FF38}.Release|x64.Build.0 = Release|x64
+               {48B8CA78-E7A9-4666-976B-2B87F58B7906}.Debug|Win32.ActiveCfg = Debug|Win32
+               {48B8CA78-E7A9-4666-976B-2B87F58B7906}.Debug|Win32.Build.0 = Debug|Win32
+               {48B8CA78-E7A9-4666-976B-2B87F58B7906}.Debug|x64.ActiveCfg = Debug|x64
+               {48B8CA78-E7A9-4666-976B-2B87F58B7906}.Debug|x64.Build.0 = Debug|x64
+               {48B8CA78-E7A9-4666-976B-2B87F58B7906}.DebugVLD|Win32.ActiveCfg = DebugVLD|Win32
+               {48B8CA78-E7A9-4666-976B-2B87F58B7906}.DebugVLD|Win32.Build.0 = DebugVLD|Win32
+               {48B8CA78-E7A9-4666-976B-2B87F58B7906}.DebugVLD|x64.ActiveCfg = DebugVLD|x64
+               {48B8CA78-E7A9-4666-976B-2B87F58B7906}.DebugVLD|x64.Build.0 = DebugVLD|x64
+               {48B8CA78-E7A9-4666-976B-2B87F58B7906}.Release|Win32.ActiveCfg = Release|Win32
+               {48B8CA78-E7A9-4666-976B-2B87F58B7906}.Release|Win32.Build.0 = Release|Win32
+               {48B8CA78-E7A9-4666-976B-2B87F58B7906}.Release|x64.ActiveCfg = Release|x64
+               {48B8CA78-E7A9-4666-976B-2B87F58B7906}.Release|x64.Build.0 = Release|x64
        EndGlobalSection
        GlobalSection(SolutionProperties) = preSolution
                HideSolutionNode = FALSE
@@ -1277,6 +1295,7 @@ Global
                {E91A1938-BB89-4676-9C9F-69AA697CB488} = {0D83E8C7-97D1-4BA1-928A-6846E7089652}
                {A0BC5155-F91B-4F89-B775-BB09A54EDB73} = {7D3EE35B-185D-40B5-88C2-7F9933426978}
                {A717715D-CA08-4111-8A0E-B69A6DE3FF38} = {0D83E8C7-97D1-4BA1-928A-6846E7089652}
+               {48B8CA78-E7A9-4666-976B-2B87F58B7906} = {7D3EE35B-185D-40B5-88C2-7F9933426978}
        EndGlobalSection
        GlobalSection(DPCodeReviewSolutionGUID) = preSolution
                DPCodeReviewSolutionGUID = {00000000-0000-0000-0000-000000000000}
diff --git a/projects/Win/vc141/stress-map-iter-erase.vcxproj b/projects/Win/vc141/stress-map-iter-erase.vcxproj
new file mode 100644 (file)
index 0000000..a1ab8ab
--- /dev/null
@@ -0,0 +1,253 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="DebugVLD|Win32">
+      <Configuration>DebugVLD</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugVLD|x64">
+      <Configuration>DebugVLD</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\test\stress\main.cpp" />
+    <ClCompile Include="..\..\..\test\stress\map\iter_erase\map_iter_erase.cpp" />
+    <ClCompile Include="..\..\..\test\stress\map\iter_erase\map_iter_erase_feldman_hashmap.cpp" />
+    <ClCompile Include="..\..\..\test\stress\map\iter_erase\map_iter_erase_michael.cpp" />
+    <ClCompile Include="..\..\..\test\stress\map\iter_erase\map_iter_erase_split.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <Text Include="..\..\..\test\stress\map\iter_erase\CMakeLists.txt" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\test\stress\map\iter_erase\map_iter_erase.h" />
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{48B8CA78-E7A9-4666-976B-2B87F58B7906}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>stress_map_iter_erase</RootNamespace>
+    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+    <ProjectName>stress-map-iter-erase</ProjectName>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v141</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v141</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v141</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v141</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v141</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v141</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)\</OutDir>
+    <IntDir>$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
+    <TargetName>$(ProjectName)_d</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)\</OutDir>
+    <IntDir>$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
+    <TargetName>$(ProjectName)_d</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)\</OutDir>
+    <IntDir>$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
+    <TargetName>$(ProjectName)_d</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)\</OutDir>
+    <IntDir>$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
+    <TargetName>$(ProjectName)_d</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)-release\</OutDir>
+    <IntDir>$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)-release\</OutDir>
+    <IntDir>$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>DebugFastLink</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>$(GTEST_LIB32);$(GTEST_ROOT)/lib/x86;$(BOOST_PATH)/stage32/lib;$(BOOST_PATH)/stage/lib;$(BOOST_PATH)/bin;%(AdditionalLibraryDirectories);$(OutDir)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>gtestd.lib;stress-framework_d.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>DebugFastLink</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>$(GTEST_LIB32);$(GTEST_ROOT)/lib/x86;$(BOOST_PATH)/stage32/lib;$(BOOST_PATH)/stage/lib;$(BOOST_PATH)/bin;%(AdditionalLibraryDirectories);$(OutDir)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>gtestd.lib;stress-framework_d.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>DebugFastLink</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>$(GTEST_LIB64);$(GTEST_ROOT)/lib/x64;$(BOOST_PATH)/stage64/lib;$(BOOST_PATH)/bin;%(AdditionalLibraryDirectories);$(OutDir)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>gtestd.lib;stress-framework_d.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>DebugFastLink</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>$(GTEST_LIB64);$(GTEST_ROOT)/lib/x64;$(BOOST_PATH)/stage64/lib;$(BOOST_PATH)/bin;%(AdditionalLibraryDirectories);$(OutDir)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>gtestd.lib;stress-framework_d.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>_ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>$(GTEST_LIB32);$(GTEST_ROOT)/lib/x86;$(BOOST_PATH)/stage32/lib;$(BOOST_PATH)/stage/lib;$(BOOST_PATH)/bin;%(AdditionalLibraryDirectories);$(OutDir)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>gtest.lib;stress-framework.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>_ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>$(GTEST_LIB64);$(GTEST_ROOT)/lib/x64;$(BOOST_PATH)/stage64/lib;$(BOOST_PATH)/bin;%(AdditionalLibraryDirectories);$(OutDir)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>gtest.lib;stress-framework.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
index 3103c1f..90f8011 100644 (file)
@@ -9,6 +9,7 @@ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/insdel_string)
 add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/insdel_item_int)
 add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/insdelfind)
 add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/minmax)
+add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/iter_erase)
 
 add_custom_target( stress-map
     DEPENDS
@@ -20,4 +21,5 @@ add_custom_target( stress-map
         stress-map-insdel-item-int
         stress-map-insdelfind
         stress-map-minmax
+        stress-map-iter-erase
 )
diff --git a/test/stress/map/iter_erase/CMakeLists.txt b/test/stress/map/iter_erase/CMakeLists.txt
new file mode 100644 (file)
index 0000000..d7a3488
--- /dev/null
@@ -0,0 +1,19 @@
+set(PACKAGE_NAME stress-map-iter-erase)
+
+set(CDSSTRESS_MAP_ITER_ERASE_SOURCES
+    ../../main.cpp
+    map_iter_erase.cpp
+    map_iter_erase_feldman_hashmap.cpp
+    map_iter_erase_michael.cpp
+    map_iter_erase_split.cpp
+)
+
+include_directories(
+    ${CMAKE_CURRENT_SOURCE_DIR}
+    ${CMAKE_CURRENT_SOURCE_DIR}/..
+)
+
+add_executable(${PACKAGE_NAME} ${CDSSTRESS_MAP_ITER_ERASE_SOURCES} $<TARGET_OBJECTS:${CDSSTRESS_FRAMEWORK_LIBRARY}>)
+target_link_libraries(${PACKAGE_NAME} ${CDS_TEST_LIBRARIES})
+
+add_test(NAME ${PACKAGE_NAME} COMMAND ${PACKAGE_NAME} WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH})
\ No newline at end of file
diff --git a/test/stress/map/iter_erase/map_iter_erase.cpp b/test/stress/map/iter_erase/map_iter_erase.cpp
new file mode 100644 (file)
index 0000000..70a5130
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_iter_erase.h"
+
+namespace map {
+
+    size_t  Map_Iter_Del3::s_nMapSize = 5000;
+    size_t  Map_Iter_Del3::s_nInsThreadCount = 4;
+    size_t  Map_Iter_Del3::s_nDelThreadCount = 4;
+    size_t  Map_Iter_Del3::s_nExtractThreadCount = 4;
+    size_t  Map_Iter_Del3::s_nFindThreadCount = 2;
+    size_t  Map_Iter_Del3::s_nMaxLoadFactor = 4;
+    size_t  Map_Iter_Del3::s_nInsertPassCount = 1000;
+
+    size_t Map_Iter_Del3::s_nFeldmanMap_HeadBits = 10;
+    size_t Map_Iter_Del3::s_nFeldmanMap_ArrayBits = 4;
+
+    size_t Map_Iter_Del3::s_nLoadFactor = 1;
+    std::vector<size_t> Map_Iter_Del3::m_arrElements;
+
+    void Map_Iter_Del3::SetUpTestCase()
+    {
+        cds_test::config const& cfg = get_config( "map_iter_erase" );
+
+        s_nMapSize = cfg.get_size_t( "MapSize", s_nMapSize );
+        if ( s_nMapSize < 1000 )
+            s_nMapSize = 1000;
+
+        s_nInsThreadCount = cfg.get_size_t( "InsThreadCount", s_nInsThreadCount );
+        if ( s_nInsThreadCount == 0 )
+            s_nInsThreadCount = 1;
+
+        s_nDelThreadCount = cfg.get_size_t( "DelThreadCount", s_nDelThreadCount );
+        s_nExtractThreadCount = cfg.get_size_t( "ExtractThreadCount", s_nExtractThreadCount );
+        s_nFindThreadCount = cfg.get_size_t( "FindThreadCount", s_nFindThreadCount );
+
+        s_nMaxLoadFactor = cfg.get_size_t( "MaxLoadFactor", s_nMaxLoadFactor );
+        if ( s_nMaxLoadFactor == 0 )
+            s_nMaxLoadFactor = 1;
+
+        s_nInsertPassCount = cfg.get_size_t( "PassCount", s_nInsertPassCount );
+        if ( s_nInsertPassCount == 0 )
+            s_nInsertPassCount = 1000;
+
+        s_nFeldmanMap_HeadBits = cfg.get_size_t( "FeldmanMapHeadBits", s_nFeldmanMap_HeadBits );
+        if ( s_nFeldmanMap_HeadBits == 0 )
+            s_nFeldmanMap_HeadBits = 2;
+
+        s_nFeldmanMap_ArrayBits = cfg.get_size_t( "FeldmanMapArrayBits", s_nFeldmanMap_ArrayBits );
+        if ( s_nFeldmanMap_ArrayBits == 0 )
+            s_nFeldmanMap_ArrayBits = 2;
+
+        m_arrElements.resize( s_nMapSize );
+        for ( size_t i = 0; i < s_nMapSize; ++i )
+            m_arrElements[i] = i;;
+        shuffle( m_arrElements.begin(), m_arrElements.end());
+    }
+
+    void Map_Iter_Del3::TearDownTestCase()
+    {
+        m_arrElements.clear();
+    }
+
+    std::vector<size_t> Map_Iter_Del3_LF::get_load_factors()
+    {
+        cds_test::config const& cfg = get_config( "map_iter_erase" );
+
+        s_nMaxLoadFactor = cfg.get_size_t( "MaxLoadFactor", s_nMaxLoadFactor );
+        if ( s_nMaxLoadFactor == 0 )
+            s_nMaxLoadFactor = 1;
+
+        std::vector<size_t> lf;
+        for ( size_t n = 1; n <= s_nMaxLoadFactor; n *= 2 )
+            lf.push_back( n );
+
+        return lf;
+    }
+
+    INSTANTIATE_TEST_CASE_P( a, Map_Iter_Del3_LF, ::testing::ValuesIn( Map_Iter_Del3_LF::get_load_factors()));
+} // namespace map
diff --git a/test/stress/map/iter_erase/map_iter_erase.h b/test/stress/map/iter_erase/map_iter_erase.h
new file mode 100644 (file)
index 0000000..89a1857
--- /dev/null
@@ -0,0 +1,871 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_type.h"
+#include <cds/os/topology.h>
+
+namespace map {
+
+    namespace {
+        struct key_thread
+        {
+            uint32_t  nKey;
+            uint16_t  nThread;
+
+            key_thread( size_t key, size_t threadNo )
+                : nKey( static_cast<uint32_t>(key))
+                , nThread( static_cast<uint16_t>(threadNo))
+            {}
+
+            key_thread()
+                : nKey()
+                , nThread()
+            {}
+        };
+
+        static_assert(sizeof( key_thread ) % 8 == 0, "Key size mismatch!!!");
+    } // namespace
+
+    template <>
+    struct cmp<key_thread> {
+        int operator ()(key_thread const& k1, key_thread const& k2) const
+        {
+            if ( k1.nKey < k2.nKey )
+                return -1;
+            if ( k1.nKey > k2.nKey )
+                return 1;
+            if ( k1.nThread < k2.nThread )
+                return -1;
+            if ( k1.nThread > k2.nThread )
+                return 1;
+            return 0;
+        }
+        int operator ()(key_thread const& k1, size_t k2) const
+        {
+            if ( k1.nKey < k2 )
+                return -1;
+            if ( k1.nKey > k2 )
+                return 1;
+            return 0;
+        }
+        int operator ()(size_t k1, key_thread const& k2) const
+        {
+            if ( k1 < k2.nKey )
+                return -1;
+            if ( k1 > k2.nKey )
+                return 1;
+            return 0;
+        }
+    };
+
+    template <>
+    struct less<key_thread>
+    {
+        bool operator()( key_thread const& k1, key_thread const& k2 ) const
+        {
+            if ( k1.nKey <= k2.nKey )
+                return k1.nKey < k2.nKey || k1.nThread < k2.nThread;
+            return false;
+        }
+    };
+
+    template <>
+    struct hash<key_thread>
+    {
+        typedef size_t             result_type;
+        typedef key_thread    argument_type;
+
+        size_t operator()( key_thread const& k ) const
+        {
+            return std::hash<size_t>()(k.nKey);
+        }
+        size_t operator()( size_t k ) const
+        {
+            return std::hash<size_t>()(k);
+        }
+    };
+
+    class Map_Iter_Del3: public cds_test::stress_fixture
+    {
+    public:
+        static size_t s_nInsThreadCount;      // insert thread count
+        static size_t s_nDelThreadCount;      // delete thread count
+        static size_t s_nExtractThreadCount;  // extract thread count
+        static size_t s_nMapSize;             // max map size
+        static size_t s_nMaxLoadFactor;       // maximum load factor
+        static size_t s_nInsertPassCount;
+        static size_t s_nFindThreadCount;     // find thread count
+
+        static size_t s_nFeldmanMap_HeadBits;
+        static size_t s_nFeldmanMap_ArrayBits;
+
+        static size_t  s_nLoadFactor;  // current load factor
+
+        static std::vector<size_t> m_arrElements;
+
+        static void SetUpTestCase();
+        static void TearDownTestCase();
+
+        template <typename Pred>
+        static void prepare_array( std::vector<size_t>& arr, Pred pred )
+        {
+            arr.reserve( m_arrElements.size());
+            for ( auto el : m_arrElements ) {
+                if ( pred( el ))
+                    arr.push_back( el );
+            }
+            arr.resize( arr.size());
+            shuffle( arr.begin(), arr.end());
+        }
+
+    protected:
+        typedef key_thread  key_type;
+        typedef size_t      value_type;
+        typedef std::pair<key_type const, value_type> pair_type;
+
+        atomics::atomic<size_t> m_nInsThreadCount;
+
+        enum {
+            inserter_thread,
+            deleter_thread,
+            extractor_thread,
+            find_thread,
+        };
+
+        // Inserts keys from [0..N)
+        template <class Map>
+        class Inserter: public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+            Map&     m_Map;
+
+            struct update_func
+            {
+                template <typename Q>
+                void operator()( bool /*bNew*/, Q const& ) const
+                {}
+
+                template <typename Q, typename V>
+                void operator()( bool /*bNew*/, Q const&, V& ) const
+                {}
+
+                // FeldmanHashMap
+                template <typename Q>
+                void operator()( Q&, Q*) const
+                {}
+            };
+
+            void init_data()
+            {
+                prepare_array( m_arr, []( size_t ) -> bool { return true; } );
+                for ( size_t i = 0; i < m_arr.size(); ++i ) {
+                    if ( m_Map.insert( key_type( m_arr[i], id())))
+                        ++m_nInsertInitSuccess;
+                    else
+                        ++m_nInsertInitFailed;
+                }
+            }
+
+        public:
+            size_t m_nInsertSuccess = 0;
+            size_t m_nInsertFailed = 0;
+            size_t m_nInsertInitSuccess = 0;
+            size_t m_nInsertInitFailed = 0;
+
+            std::vector<size_t> m_arr;
+
+        public:
+            Inserter( cds_test::thread_pool& pool, Map& map )
+                : base_class( pool, inserter_thread )
+                , m_Map( map )
+            {
+                init_data();
+            }
+
+            Inserter( Inserter& src )
+                : base_class( src )
+                , m_Map( src.m_Map )
+            {
+                init_data();
+            }
+
+            virtual thread * clone()
+            {
+                return new Inserter( *this );
+            }
+
+            virtual void test()
+            {
+                Map& rMap = m_Map;
+                Map_Iter_Del3& fixture = pool().template fixture<Map_Iter_Del3>();
+
+                update_func f;
+
+                for ( size_t nPass = 0; nPass < s_nInsertPassCount; ++nPass ) {
+                    if ( nPass & 1 ) {
+                        // insert pass
+                        for ( auto el : m_arr ) {
+                            if ( el & 3 ) {
+                                if ( rMap.insert( key_type( el, id())))
+                                    ++m_nInsertSuccess;
+                                else
+                                    ++m_nInsertFailed;
+                            }
+                        }
+                    }
+                    else {
+                        // update pass
+                        for ( auto el : m_arr ) {
+                            if ( el & 3 ) {
+                                bool success;
+                                bool inserted;
+                                std::tie( success, inserted ) = rMap.update( key_type( el, id()), f );
+                                if ( success && inserted )
+                                    ++m_nInsertSuccess;
+                                else
+                                    ++m_nInsertFailed;
+                            }
+                        }
+                    }
+                }
+
+                fixture.m_nInsThreadCount.fetch_sub( 1, atomics::memory_order_release );
+                m_arr.resize( 0 );
+            }
+        };
+
+        struct key_equal {
+            bool operator()( key_type const& k1, key_type const& k2 ) const
+            {
+                return k1.nKey == k2.nKey;
+            }
+            bool operator()( size_t k1, key_type const& k2 ) const
+            {
+                return k1 == k2.nKey;
+            }
+            bool operator()( key_type const& k1, size_t k2 ) const
+            {
+                return k1.nKey == k2;
+            }
+        };
+
+        struct key_less {
+            bool operator()( key_type const& k1, key_type const& k2 ) const
+            {
+                return k1.nKey < k2.nKey;
+            }
+            bool operator()( size_t k1, key_type const& k2 ) const
+            {
+                return k1 < k2.nKey;
+            }
+            bool operator()( key_type const& k1, size_t k2 ) const
+            {
+                return k1.nKey < k2;
+            }
+
+            typedef key_equal equal_to;
+        };
+
+        // Deletes odd keys from [0..N)
+        template <class Map, typename Iterator>
+        class Deleter: public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+            Map&     m_Map;
+
+            void init_data()
+            {
+                prepare_array( m_arr, []( size_t el ) ->bool { return ( el & 3 ) != 0; } );
+            }
+
+        public:
+            size_t  m_nDeleteSuccess = 0;
+            size_t  m_nDeleteFailed = 0;
+
+            std::vector<size_t> m_arr;
+
+        public:
+            Deleter( cds_test::thread_pool& pool, Map& map )
+                : base_class( pool, deleter_thread )
+                , m_Map( map )
+            {
+                init_data();
+            }
+
+            Deleter( Deleter& src )
+                : base_class( src )
+                , m_Map( src.m_Map )
+            {
+                init_data();
+            }
+
+            virtual thread * clone()
+            {
+                return new Deleter( *this );
+            }
+
+            virtual void test()
+            {
+                Map& rMap = m_Map;
+
+                Map_Iter_Del3& fixture = pool().template fixture<Map_Iter_Del3>();
+
+                do {
+                    auto itEnd = rMap.template get_end<Iterator>();
+                    for ( auto it = rMap.template get_begin<Iterator>(); it != itEnd; ++it ) {
+                        if ( it->first.nKey & 3 ) {
+                            if ( rMap.erase_at( it ) )
+                                ++m_nDeleteSuccess;
+                            else
+                                ++m_nDeleteFailed;
+                        }
+                    }
+                } while ( fixture.m_nInsThreadCount.load( atomics::memory_order_acquire ) != 0 );
+            }
+        };
+
+        // Deletes odd keys from [0..N)
+        template <class GC, class Map >
+        class Extractor: public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+            Map&     m_Map;
+
+            void init_data()
+            {
+                prepare_array( m_arr, []( size_t el ) ->bool { return ( el & 3 ) != 0; } );
+            }
+
+        public:
+            size_t  m_nDeleteSuccess = 0;
+            size_t  m_nDeleteFailed = 0;
+
+            std::vector<size_t> m_arr;
+
+        public:
+            Extractor( cds_test::thread_pool& pool, Map& map )
+                : base_class( pool, extractor_thread )
+                , m_Map( map )
+            {
+                init_data();
+            }
+
+            Extractor( Extractor& src )
+                : base_class( src )
+                , m_Map( src.m_Map )
+            {
+                init_data();
+            }
+
+            virtual thread * clone()
+            {
+                return new Extractor( *this );
+            }
+
+            virtual void test()
+            {
+                Map& rMap = m_Map;
+
+                typename Map::guarded_ptr gp;
+                Map_Iter_Del3& fixture = pool().template fixture<Map_Iter_Del3>();
+                size_t const nInsThreadCount = s_nInsThreadCount;
+
+                do {
+                    if ( id() & 1 ) {
+                        for ( auto el : m_arr ) {
+                            for ( size_t k = 0; k < nInsThreadCount; ++k ) {
+                                gp = rMap.extract( key_type( el, k ));
+                                if ( gp )
+                                    ++m_nDeleteSuccess;
+                                else
+                                    ++m_nDeleteFailed;
+                                gp.release();
+                            }
+                        }
+                    }
+                    else {
+                        for ( size_t k = 0; k < nInsThreadCount; ++k ) {
+                            for ( auto el: m_arr ) {
+                                gp = rMap.extract( key_type( el, k ));
+                                if ( gp )
+                                    ++m_nDeleteSuccess;
+                                else
+                                    ++m_nDeleteFailed;
+                                gp.release();
+                            }
+                        }
+                    }
+                } while ( fixture.m_nInsThreadCount.load( atomics::memory_order_acquire ) != 0 );
+
+                m_arr.resize( 0 );
+            }
+        };
+
+        template <class RCU, class Map >
+        class Extractor< cds::urcu::gc<RCU>, Map > : public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+            Map&     m_Map;
+
+            void init_data()
+            {
+                prepare_array( m_arr, []( size_t el ) -> bool { return ( el & 3 ) != 0; } );
+            }
+
+        public:
+            size_t  m_nDeleteSuccess = 0;
+            size_t  m_nDeleteFailed = 0;
+
+            std::vector<size_t> m_arr;
+
+        public:
+            Extractor( cds_test::thread_pool& pool, Map& map )
+                : base_class( pool, extractor_thread )
+                , m_Map( map )
+            {
+                init_data();
+            }
+
+            Extractor( Extractor& src )
+                : base_class( src )
+                , m_Map( src.m_Map )
+            {
+                init_data();
+            }
+
+            virtual thread * clone()
+            {
+                return new Extractor( *this );
+            }
+
+            virtual void test()
+            {
+                Map& rMap = m_Map;
+                Map_Iter_Del3& fixture = pool().template fixture<Map_Iter_Del3>();
+
+                typename Map::exempt_ptr xp;
+                size_t const nInsThreadCount = s_nInsThreadCount;
+
+                do {
+                    if ( id() & 1 ) {
+                        for ( size_t k = 0; k < nInsThreadCount; ++k ) {
+                            for ( auto el: m_arr ) {
+                                if ( Map::c_bExtractLockExternal ) {
+                                    typename Map::rcu_lock l;
+                                    xp = rMap.extract( key_type( el, k ));
+                                    if ( xp )
+                                        ++m_nDeleteSuccess;
+                                    else
+                                        ++m_nDeleteFailed;
+                                }
+                                else {
+                                    xp = rMap.extract( key_type( el, k ));
+                                    if ( xp )
+                                        ++m_nDeleteSuccess;
+                                    else
+                                        ++m_nDeleteFailed;
+                                }
+                                xp.release();
+                            }
+                        }
+                    }
+                    else {
+                        for ( auto el : m_arr ) {
+                            for ( size_t k = 0; k < nInsThreadCount; ++k ) {
+                                if ( Map::c_bExtractLockExternal ) {
+                                    typename Map::rcu_lock l;
+                                    xp = rMap.extract( key_type( el, k ));
+                                    if ( xp )
+                                        ++m_nDeleteSuccess;
+                                    else
+                                        ++m_nDeleteFailed;
+                                }
+                                else {
+                                    xp = rMap.extract( key_type( el, k ));
+                                    if ( xp )
+                                        ++m_nDeleteSuccess;
+                                    else
+                                        ++m_nDeleteFailed;
+                                }
+                                xp.release();
+                            }
+                        }
+                    }
+                } while ( fixture.m_nInsThreadCount.load( atomics::memory_order_acquire ) != 0 );
+
+                m_arr.resize( 0 );
+            }
+        };
+
+        // Finds keys
+        template <class Map>
+        class Observer: public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+            Map&                m_Map;
+
+        public:
+            size_t m_nFindEvenSuccess = 0;
+            size_t m_nFindEvenFailed  = 0;
+            size_t m_nFindOddSuccess  = 0;
+            size_t m_nFindOddFailed   = 0;
+
+        public:
+            Observer( cds_test::thread_pool& pool, Map& map )
+                : base_class( pool, find_thread )
+                , m_Map( map )
+            {}
+
+            Observer( Observer& src )
+                : base_class( src )
+                , m_Map( src.m_Map )
+            {}
+
+            virtual thread * clone()
+            {
+                return new Observer( *this );
+            }
+
+            virtual void test()
+            {
+                Map& map = m_Map;
+                Map_Iter_Del3& fixture = pool().template fixture<Map_Iter_Del3>();
+                std::vector<size_t> const& arr = m_arrElements;
+                size_t const nInsThreadCount = s_nInsThreadCount;
+
+                do {
+                    for ( size_t key : arr ) {
+                        if ( key & 3 ) {
+                            for ( size_t k = 0; k < nInsThreadCount; ++k ) {
+                                if ( map.contains( key_thread( key, k )))
+                                    ++m_nFindOddSuccess;
+                                else
+                                    ++m_nFindOddFailed;
+                            }
+                        }
+                        else {
+                            // even keys MUST be in the map
+                            for ( size_t k = 0; k < nInsThreadCount; ++k ) {
+                                if ( map.contains( key_thread( key, k )))
+                                    ++m_nFindEvenSuccess;
+                                else
+                                    ++m_nFindEvenFailed;
+                            }
+                        }
+                    }
+                } while ( fixture.m_nInsThreadCount.load( atomics::memory_order_acquire ) != 0 );
+            }
+        };
+
+    protected:
+        template <typename Iterator, class Map>
+        void do_test( Map& testMap )
+        {
+            typedef Inserter<Map> insert_thread;
+            typedef Deleter<Map, Iterator>  delete_thread;
+            typedef Observer<Map> observer_thread;
+
+            m_nInsThreadCount.store( s_nInsThreadCount, atomics::memory_order_release );
+
+            cds_test::thread_pool& pool = get_pool();
+            pool.add( new insert_thread( pool, testMap ), s_nInsThreadCount );
+            pool.add( new delete_thread( pool, testMap ), s_nDelThreadCount ? s_nDelThreadCount : cds::OS::topology::processor_count());
+            if ( s_nFindThreadCount )
+                pool.add( new observer_thread( pool, testMap ), s_nFindThreadCount );
+
+            propout() << std::make_pair( "insert_thread_count", s_nInsThreadCount )
+                << std::make_pair( "delete_thread_count", s_nDelThreadCount )
+                << std::make_pair( "find_thread_count", s_nFindThreadCount )
+                << std::make_pair( "map_size", s_nMapSize )
+                << std::make_pair( "pass_count", s_nInsertPassCount );
+
+            std::chrono::milliseconds duration = pool.run();
+
+            propout() << std::make_pair( "duration", duration );
+
+            size_t nInsertInitFailed = 0;
+            size_t nInsertInitSuccess = 0;
+            size_t nInsertSuccess = 0;
+            size_t nInsertFailed = 0;
+            size_t nDeleteSuccess = 0;
+            size_t nDeleteFailed = 0;
+
+            size_t nFindEvenSuccess = 0;
+            size_t nFindEvenFailed = 0;
+            size_t nFindOddSuccess = 0;
+            size_t nFindOddFailed = 0;
+
+            for ( size_t i = 0; i < pool.size(); ++i ) {
+                cds_test::thread& thr = pool.get( i );
+                switch ( thr.type()) {
+                case inserter_thread:
+                    {
+                        insert_thread& inserter = static_cast<insert_thread&>( thr );
+                        nInsertSuccess += inserter.m_nInsertSuccess;
+                        nInsertFailed += inserter.m_nInsertFailed;
+                        nInsertInitSuccess += inserter.m_nInsertInitSuccess;
+                        nInsertInitFailed += inserter.m_nInsertInitFailed;
+                    }
+                    break;
+                case deleter_thread:
+                    {
+                        delete_thread& deleter = static_cast<delete_thread&>( thr );
+                        nDeleteSuccess += deleter.m_nDeleteSuccess;
+                        nDeleteFailed += deleter.m_nDeleteFailed;
+                    }
+                    break;
+                case find_thread:
+                    {
+                        observer_thread& observer = static_cast<observer_thread&>( thr );
+                        nFindEvenSuccess = observer.m_nFindEvenSuccess;
+                        nFindEvenFailed = observer.m_nFindEvenFailed;
+                        nFindOddSuccess = observer.m_nFindOddSuccess;
+                        nFindOddFailed = observer.m_nFindOddFailed;
+                    }
+                    break;
+                }
+            }
+
+            size_t const nInitialOddKeys = ( s_nMapSize * s_nInsThreadCount ) * 3 / 4;
+
+            EXPECT_EQ( nInsertInitFailed, 0u );
+            EXPECT_EQ( nInsertInitSuccess, s_nMapSize * s_nInsThreadCount );
+            EXPECT_EQ( nFindEvenFailed, 0u );
+            EXPECT_GE( nInsertSuccess + nInitialOddKeys, nDeleteSuccess );
+            EXPECT_LE( nInsertSuccess, nDeleteSuccess );
+
+            propout()
+                << std::make_pair( "insert_init_success", nInsertInitSuccess )
+                << std::make_pair( "insert_init_failed", nInsertInitFailed )
+                << std::make_pair( "insert_success", nInsertSuccess )
+                << std::make_pair( "insert_failed", nInsertFailed )
+                << std::make_pair( "delete_success", nDeleteSuccess )
+                << std::make_pair( "delete_failed", nDeleteFailed )
+                << std::make_pair( "find_even_success", nFindEvenSuccess )
+                << std::make_pair( "find_even_failed", nFindEvenFailed )
+                << std::make_pair( "find_odd_success", nFindOddSuccess )
+                << std::make_pair( "find_odd_failed", nFindOddFailed );
+
+            analyze( testMap );
+        }
+
+        template <typename Iterator, class Map>
+        void do_test_extract( Map& testMap )
+        {
+            typedef Inserter<Map> insert_thread;
+            typedef Deleter<Map, Iterator> delete_thread;
+            typedef Extractor< typename Map::gc, Map > extract_thread;
+            typedef Observer<Map> observer_thread;
+
+            m_nInsThreadCount.store( s_nInsThreadCount, atomics::memory_order_release );
+
+            cds_test::thread_pool& pool = get_pool();
+            pool.add( new insert_thread( pool, testMap ), s_nInsThreadCount );
+            if ( s_nDelThreadCount )
+                pool.add( new delete_thread( pool, testMap ), s_nDelThreadCount );
+            if ( s_nExtractThreadCount )
+                pool.add( new extract_thread( pool, testMap ), s_nExtractThreadCount );
+            if ( s_nFindThreadCount )
+                pool.add( new observer_thread( pool, testMap ), s_nFindThreadCount );
+
+            propout() << std::make_pair( "insert_thread_count", s_nInsThreadCount )
+                << std::make_pair( "delete_thread_count", s_nDelThreadCount )
+                << std::make_pair( "extract_thread_count", s_nExtractThreadCount )
+                << std::make_pair( "find_thread_count", s_nFindThreadCount )
+                << std::make_pair( "map_size", s_nMapSize )
+                << std::make_pair( "pass_count", s_nInsertPassCount );
+
+            std::chrono::milliseconds duration = pool.run();
+
+            propout() << std::make_pair( "duration", duration );
+
+            size_t nInsertInitFailed = 0;
+            size_t nInsertInitSuccess = 0;
+            size_t nInsertSuccess = 0;
+            size_t nInsertFailed = 0;
+            size_t nDeleteSuccess = 0;
+            size_t nDeleteFailed = 0;
+            size_t nExtractSuccess = 0;
+            size_t nExtractFailed = 0;
+
+            size_t nFindEvenSuccess = 0;
+            size_t nFindEvenFailed = 0;
+            size_t nFindOddSuccess = 0;
+            size_t nFindOddFailed = 0;
+
+            for ( size_t i = 0; i < pool.size(); ++i ) {
+                cds_test::thread& thr = pool.get( i );
+                switch ( thr.type()) {
+                case inserter_thread:
+                {
+                    insert_thread& inserter = static_cast<insert_thread&>(thr);
+                    nInsertSuccess += inserter.m_nInsertSuccess;
+                    nInsertFailed += inserter.m_nInsertFailed;
+                    nInsertInitSuccess += inserter.m_nInsertInitSuccess;
+                    nInsertInitFailed += inserter.m_nInsertInitFailed;
+                }
+                break;
+                case deleter_thread:
+                {
+                    delete_thread& deleter = static_cast<delete_thread&>(thr);
+                    nDeleteSuccess += deleter.m_nDeleteSuccess;
+                    nDeleteFailed += deleter.m_nDeleteFailed;
+                }
+                break;
+                case extractor_thread:
+                {
+                    extract_thread& extractor = static_cast<extract_thread&>(thr);
+                    nExtractSuccess += extractor.m_nDeleteSuccess;
+                    nExtractFailed += extractor.m_nDeleteFailed;
+                }
+                break;
+                case find_thread:
+                {
+                    observer_thread& observer = static_cast<observer_thread&>( thr );
+                    nFindEvenSuccess = observer.m_nFindEvenSuccess;
+                    nFindEvenFailed = observer.m_nFindEvenFailed;
+                    nFindOddSuccess = observer.m_nFindOddSuccess;
+                    nFindOddFailed = observer.m_nFindOddFailed;
+                }
+                break;
+                default:
+                    assert( false );
+                }
+            }
+
+            size_t const nInitialOddKeys = ( s_nMapSize * s_nInsThreadCount ) * 3 / 4;
+
+            EXPECT_EQ( nInsertInitFailed, 0u );
+            EXPECT_EQ( nInsertInitSuccess, s_nMapSize * s_nInsThreadCount );
+            EXPECT_EQ( nFindEvenFailed, 0u );
+            EXPECT_GE( nInsertSuccess + nInitialOddKeys, nDeleteSuccess + nExtractSuccess );
+            EXPECT_LE( nInsertSuccess, nDeleteSuccess + nExtractSuccess );
+
+            propout()
+                << std::make_pair( "insert_init_success", nInsertInitSuccess )
+                << std::make_pair( "insert_init_failed", nInsertInitFailed )
+                << std::make_pair( "insert_success", nInsertSuccess )
+                << std::make_pair( "insert_failed", nInsertFailed )
+                << std::make_pair( "delete_success", nDeleteSuccess )
+                << std::make_pair( "delete_failed", nDeleteFailed )
+                << std::make_pair( "extract_success", nExtractSuccess )
+                << std::make_pair( "extract_failed", nExtractFailed )
+                << std::make_pair( "find_even_success", nFindEvenSuccess )
+                << std::make_pair( "find_even_failed", nFindEvenFailed )
+                << std::make_pair( "find_odd_success", nFindOddSuccess )
+                << std::make_pair( "find_odd_failed", nFindOddFailed );
+
+            analyze( testMap );
+        }
+
+        template <class Map>
+        void analyze( Map& testMap )
+        {
+            // All even keys must be in the map
+            {
+                for ( size_t n = 0; n < s_nMapSize; n +=4 ) {
+                    for ( size_t i = 0; i < s_nInsThreadCount; ++i ) {
+                        EXPECT_TRUE( testMap.contains( key_type( n, i ))) << "key=" << n << "/" << i;
+                    }
+                }
+            }
+
+            print_stat( propout(), testMap );
+
+            check_before_cleanup( testMap );
+            testMap.clear();
+            EXPECT_TRUE( testMap.empty()) << "map.size=" << testMap.size();
+
+            additional_check( testMap );
+            additional_cleanup( testMap );
+        }
+
+        template <class Map, typename Iterator=typename Map::iterator>
+        void run_test_extract()
+        {
+            static_assert( Map::c_bExtractSupported, "Map class must support extract() method" );
+
+            size_t nMapSize = s_nMapSize;
+            s_nMapSize *= s_nInsThreadCount;
+
+            Map testMap( *this );
+
+            s_nMapSize = nMapSize;
+            do_test_extract<Iterator>( testMap );
+        }
+
+        template <class Map, typename Iterator=typename Map::iterator>
+        void run_test()
+        {
+            size_t nMapSize = s_nMapSize;
+            s_nMapSize *= s_nInsThreadCount;
+
+            Map testMap( *this );
+
+            s_nMapSize = nMapSize;
+            do_test<Iterator>( testMap );
+        }
+
+        template <class Map>
+        void run_feldman();
+    };
+
+    class Map_Iter_Del3_reverse: public Map_Iter_Del3
+    {
+    public:
+        template <class Map>
+        void run_feldman();
+    };
+
+
+    class Map_Iter_Del3_LF: public Map_Iter_Del3
+        , public ::testing::WithParamInterface<size_t>
+    {
+    public:
+        template <class Map>
+        void run_test()
+        {
+            s_nLoadFactor = GetParam();
+            propout() << std::make_pair( "load_factor", s_nLoadFactor );
+            Map_Iter_Del3::run_test<Map>();
+        }
+
+        template <class Map>
+        void run_test_extract()
+        {
+            s_nLoadFactor = GetParam();
+            propout() << std::make_pair( "load_factor", s_nLoadFactor );
+            Map_Iter_Del3::run_test_extract<Map>();
+        }
+
+        static std::vector<size_t> get_load_factors();
+    };
+
+} // namespace map
diff --git a/test/stress/map/iter_erase/map_iter_erase_feldman_hashmap.cpp b/test/stress/map/iter_erase/map_iter_erase_feldman_hashmap.cpp
new file mode 100644 (file)
index 0000000..23522ca
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_iter_erase.h"
+#include "map_type_feldman_hashmap.h"
+
+namespace map {
+
+    template <class Map>
+    void Map_Iter_Del3::run_feldman()
+    {
+        typedef typename Map::traits original_traits;
+        struct traits: public original_traits {
+            enum { hash_size = sizeof( uint32_t ) + sizeof( uint16_t ) };
+        };
+        typedef typename Map::template rebind_traits< traits >::result map_type;
+
+        run_test_extract<map_type>();
+    }
+
+    template <class Map>
+    void Map_Iter_Del3_reverse::run_feldman()
+    {
+        typedef typename Map::traits original_traits;
+        struct traits: public original_traits {
+            enum { hash_size = sizeof( uint32_t ) + sizeof( uint16_t ) };
+        };
+        typedef typename Map::template rebind_traits< traits >::result map_type;
+
+        run_test_extract<map_type, typename map_type::reverse_iterator>();
+    }
+
+    CDSSTRESS_FeldmanHashMap_fixed_HP( Map_Iter_Del3, run_feldman, key_thread, size_t )
+    CDSSTRESS_FeldmanHashMap_fixed_HP( Map_Iter_Del3_reverse, run_feldman, key_thread, size_t )
+
+} // namespace map
diff --git a/test/stress/map/iter_erase/map_iter_erase_michael.cpp b/test/stress/map/iter_erase/map_iter_erase_michael.cpp
new file mode 100644 (file)
index 0000000..d933d8e
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_iter_erase.h"
+#include "map_type_michael.h"
+
+namespace map {
+    //TODO add erase_at() to MichaelHashMap based on IterableList
+#if 0
+    CDSSTRESS_MichaelMap( Map_Iter_Del3_LF, run_test_extract, key_thread, size_t )
+#endif
+
+} // namespace map
diff --git a/test/stress/map/iter_erase/map_iter_erase_split.cpp b/test/stress/map/iter_erase/map_iter_erase_split.cpp
new file mode 100644 (file)
index 0000000..4ffdb6b
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "map_iter_erase.h"
+#include "map_type_split_list.h"
+
+namespace map {
+    //TODO: add erase_at() to SplitList based on IterableList
+#if 0
+    CDSSTRESS_SplitListIterableMap( Map_Iter_Del3_LF, run_test_extract, key_thread, size_t )
+#endif
+} // namespace map
index 39b9f7c..1c5907a 100644 (file)
@@ -58,6 +58,34 @@ namespace map {
             : base_class( cfg.s_nFeldmanMap_HeadBits, cfg.s_nFeldmanMap_ArrayBits )
         {}
 
+        template <typename Iterator>
+        typename std::enable_if< std::is_same< Iterator, typename base_class::iterator>::value, Iterator>::type
+            get_begin()
+        {
+            return base_class::begin();
+        }
+
+        template <typename Iterator>
+        typename std::enable_if< std::is_same< Iterator, typename base_class::iterator>::value, Iterator>::type
+            get_end()
+        {
+            return base_class::end();
+        }
+
+        template <typename Iterator>
+        typename std::enable_if< std::is_same< Iterator, typename base_class::reverse_iterator>::value, Iterator>::type
+            get_begin()
+        {
+            return base_class::rbegin();
+        }
+
+        template <typename Iterator>
+        typename std::enable_if< std::is_same< Iterator, typename base_class::reverse_iterator>::value, Iterator>::type
+            get_end()
+        {
+            return base_class::rend();
+        }
+
         // for testing
         static CDS_CONSTEXPR bool const c_bExtractSupported = true;
         static CDS_CONSTEXPR bool const c_bLoadFactorDepended = false;