Moved queue unit test to gtest framework
authorkhizmax <libcds.dev@gmail.com>
Sat, 23 Jan 2016 14:34:34 +0000 (17:34 +0300)
committerkhizmax <libcds.dev@gmail.com>
Sat, 23 Jan 2016 14:34:34 +0000 (17:34 +0300)
13 files changed:
projects/Win/vc14/gtest-deque.vcxproj
projects/Win/vc14/gtest-pqueue.vcxproj
projects/Win/vc14/gtest-queue.vcxproj
projects/Win/vc14/gtest-queue.vcxproj.filters
projects/Win/vc14/gtest-stack.vcxproj
test/unit/queue/CMakeLists.txt
test/unit/queue/segmented_queue_dhp.cpp [new file with mode: 0644]
test/unit/queue/segmented_queue_hp.cpp [new file with mode: 0644]
test/unit/queue/test_bounded_queue.h [new file with mode: 0644]
test/unit/queue/test_generic_queue.h
test/unit/queue/test_segmented_queue.h [new file with mode: 0644]
test/unit/queue/tsigas_queue.cpp [new file with mode: 0644]
test/unit/queue/vyukov_mpmc_queue.cpp [new file with mode: 0644]

index 7861f82b0f887a50d95fbf7c363d3fdbb78a1d41..a3824281dbed182f50d3b7bb47fd329535329e2b 100644 (file)
   </PropertyGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
     <ClCompile>\r
-      <PrecompiledHeader>\r
-      </PrecompiledHeader>\r
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
       <WarningLevel>Level3</WarningLevel>\r
       <Optimization>Disabled</Optimization>\r
       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
   </ItemDefinitionGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'">\r
     <ClCompile>\r
-      <PrecompiledHeader>\r
-      </PrecompiledHeader>\r
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
       <WarningLevel>Level3</WarningLevel>\r
       <Optimization>Disabled</Optimization>\r
       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
   </ItemDefinitionGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
     <ClCompile>\r
-      <PrecompiledHeader>\r
-      </PrecompiledHeader>\r
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
       <WarningLevel>Level3</WarningLevel>\r
       <Optimization>Disabled</Optimization>\r
       <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
   </ItemDefinitionGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'">\r
     <ClCompile>\r
-      <PrecompiledHeader>\r
-      </PrecompiledHeader>\r
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
       <WarningLevel>Level3</WarningLevel>\r
       <Optimization>Disabled</Optimization>\r
       <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
     <ClCompile>\r
       <WarningLevel>Level3</WarningLevel>\r
-      <PrecompiledHeader>\r
-      </PrecompiledHeader>\r
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
       <Optimization>MaxSpeed</Optimization>\r
       <FunctionLevelLinking>true</FunctionLevelLinking>\r
       <IntrinsicFunctions>true</IntrinsicFunctions>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
     <ClCompile>\r
       <WarningLevel>Level3</WarningLevel>\r
-      <PrecompiledHeader>\r
-      </PrecompiledHeader>\r
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
       <Optimization>MaxSpeed</Optimization>\r
       <FunctionLevelLinking>true</FunctionLevelLinking>\r
       <IntrinsicFunctions>true</IntrinsicFunctions>\r
index cb3ddb695b26bb952a51ee3103dcb3218bab585a..ffc22f8d1b4aa4394ea4508a6dbf6201cf655e3c 100644 (file)
   </PropertyGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
     <ClCompile>\r
-      <PrecompiledHeader>\r
-      </PrecompiledHeader>\r
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
       <WarningLevel>Level3</WarningLevel>\r
       <Optimization>Disabled</Optimization>\r
       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
   </ItemDefinitionGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'">\r
     <ClCompile>\r
-      <PrecompiledHeader>\r
-      </PrecompiledHeader>\r
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
       <WarningLevel>Level3</WarningLevel>\r
       <Optimization>Disabled</Optimization>\r
       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
   </ItemDefinitionGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
     <ClCompile>\r
-      <PrecompiledHeader>\r
-      </PrecompiledHeader>\r
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
       <WarningLevel>Level3</WarningLevel>\r
       <Optimization>Disabled</Optimization>\r
       <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
   </ItemDefinitionGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'">\r
     <ClCompile>\r
-      <PrecompiledHeader>\r
-      </PrecompiledHeader>\r
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
       <WarningLevel>Level3</WarningLevel>\r
       <Optimization>Disabled</Optimization>\r
       <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
     <ClCompile>\r
       <WarningLevel>Level3</WarningLevel>\r
-      <PrecompiledHeader>\r
-      </PrecompiledHeader>\r
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
       <Optimization>MaxSpeed</Optimization>\r
       <FunctionLevelLinking>true</FunctionLevelLinking>\r
       <IntrinsicFunctions>true</IntrinsicFunctions>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
     <ClCompile>\r
       <WarningLevel>Level3</WarningLevel>\r
-      <PrecompiledHeader>\r
-      </PrecompiledHeader>\r
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
       <Optimization>MaxSpeed</Optimization>\r
       <FunctionLevelLinking>true</FunctionLevelLinking>\r
       <IntrinsicFunctions>true</IntrinsicFunctions>\r
index f4d2a7f5ffae5f84a5a13085c3a8a34f1e087217..edb20c69db93b559329d51f4c696ec5e77b07b6c 100644 (file)
     <ClCompile Include="..\..\..\test\unit\queue\optimistic_queue_dhp.cpp" />\r
     <ClCompile Include="..\..\..\test\unit\queue\optimistic_queue_hp.cpp" />\r
     <ClCompile Include="..\..\..\test\unit\queue\rwqueue.cpp" />\r
+    <ClCompile Include="..\..\..\test\unit\queue\segmented_queue_dhp.cpp">\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\test\unit\queue\segmented_queue_hp.cpp" />\r
+    <ClCompile Include="..\..\..\test\unit\queue\tsigas_queue.cpp" />\r
+    <ClCompile Include="..\..\..\test\unit\queue\vyukov_mpmc_queue.cpp" />\r
   </ItemGroup>\r
   <ItemGroup>\r
+    <ClInclude Include="..\..\..\test\unit\queue\test_bounded_queue.h" />\r
     <ClInclude Include="..\..\..\test\unit\queue\test_generic_queue.h" />\r
+    <ClInclude Include="..\..\..\test\unit\queue\test_segmented_queue.h" />\r
   </ItemGroup>\r
   <PropertyGroup Label="Globals">\r
     <ProjectGuid>{9EB8FAB6-78E8-48B6-9589-85985CE8D33D}</ProjectGuid>\r
   </PropertyGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
     <ClCompile>\r
-      <PrecompiledHeader>\r
-      </PrecompiledHeader>\r
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
       <WarningLevel>Level3</WarningLevel>\r
       <Optimization>Disabled</Optimization>\r
       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
   </ItemDefinitionGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'">\r
     <ClCompile>\r
-      <PrecompiledHeader>\r
-      </PrecompiledHeader>\r
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
       <WarningLevel>Level3</WarningLevel>\r
       <Optimization>Disabled</Optimization>\r
       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
   </ItemDefinitionGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
     <ClCompile>\r
-      <PrecompiledHeader>\r
-      </PrecompiledHeader>\r
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
       <WarningLevel>Level3</WarningLevel>\r
       <Optimization>Disabled</Optimization>\r
       <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
   </ItemDefinitionGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'">\r
     <ClCompile>\r
-      <PrecompiledHeader>\r
-      </PrecompiledHeader>\r
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
       <WarningLevel>Level3</WarningLevel>\r
       <Optimization>Disabled</Optimization>\r
       <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
     <ClCompile>\r
       <WarningLevel>Level3</WarningLevel>\r
-      <PrecompiledHeader>\r
-      </PrecompiledHeader>\r
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
       <Optimization>MaxSpeed</Optimization>\r
       <FunctionLevelLinking>true</FunctionLevelLinking>\r
       <IntrinsicFunctions>true</IntrinsicFunctions>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
     <ClCompile>\r
       <WarningLevel>Level3</WarningLevel>\r
-      <PrecompiledHeader>\r
-      </PrecompiledHeader>\r
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
       <Optimization>MaxSpeed</Optimization>\r
       <FunctionLevelLinking>true</FunctionLevelLinking>\r
       <IntrinsicFunctions>true</IntrinsicFunctions>\r
index b766f092b39d825a2d3485b866aa8f79e8318569..2158a14d7bfe75805dd3c499ca7e6dd6161fb41c 100644 (file)
     <ClCompile Include="..\..\..\test\unit\queue\rwqueue.cpp">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\test\unit\queue\segmented_queue_hp.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\test\unit\queue\segmented_queue_dhp.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\test\unit\queue\vyukov_mpmc_queue.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\test\unit\queue\tsigas_queue.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClInclude Include="..\..\..\test\unit\queue\test_generic_queue.h">\r
       <Filter>Header Files</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\..\..\test\unit\queue\test_segmented_queue.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\..\..\test\unit\queue\test_bounded_queue.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
 </Project>
\ No newline at end of file
index 39cd7ea88bae81532dba28125604048518df7794..4680d2e42ae34a4f88a0d6e0322b6f4851f55f2a 100644 (file)
   </PropertyGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
     <ClCompile>\r
-      <PrecompiledHeader>\r
-      </PrecompiledHeader>\r
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
       <WarningLevel>Level3</WarningLevel>\r
       <Optimization>Disabled</Optimization>\r
       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
   </ItemDefinitionGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'">\r
     <ClCompile>\r
-      <PrecompiledHeader>\r
-      </PrecompiledHeader>\r
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
       <WarningLevel>Level3</WarningLevel>\r
       <Optimization>Disabled</Optimization>\r
       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
   </ItemDefinitionGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
     <ClCompile>\r
-      <PrecompiledHeader>\r
-      </PrecompiledHeader>\r
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
       <WarningLevel>Level3</WarningLevel>\r
       <Optimization>Disabled</Optimization>\r
       <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
   </ItemDefinitionGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'">\r
     <ClCompile>\r
-      <PrecompiledHeader>\r
-      </PrecompiledHeader>\r
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
       <WarningLevel>Level3</WarningLevel>\r
       <Optimization>Disabled</Optimization>\r
       <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
     <ClCompile>\r
       <WarningLevel>Level3</WarningLevel>\r
-      <PrecompiledHeader>\r
-      </PrecompiledHeader>\r
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
       <Optimization>MaxSpeed</Optimization>\r
       <FunctionLevelLinking>true</FunctionLevelLinking>\r
       <IntrinsicFunctions>true</IntrinsicFunctions>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
     <ClCompile>\r
       <WarningLevel>Level3</WarningLevel>\r
-      <PrecompiledHeader>\r
-      </PrecompiledHeader>\r
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
       <Optimization>MaxSpeed</Optimization>\r
       <FunctionLevelLinking>true</FunctionLevelLinking>\r
       <IntrinsicFunctions>true</IntrinsicFunctions>\r
index 947edc37b1ed6b8500d7faf0df669c26685c5c8b..163a108266a2f6d834e09e4ac45bb8fed25d90a6 100644 (file)
@@ -12,6 +12,10 @@ set(CDSGTEST_QUEUE_SOURCES
     optimistic_queue_hp.cpp
     optimistic_queue_dhp.cpp
     rwqueue.cpp
+    segmented_queue_hp.cpp
+    segmented_queue_dhp.cpp
+    tsigas_queue.cpp
+    vyukov_mpmc_queue.cpp
 )
 
 include_directories(
diff --git a/test/unit/queue/segmented_queue_dhp.cpp b/test/unit/queue/segmented_queue_dhp.cpp
new file mode 100644 (file)
index 0000000..fff7e29
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
+
+    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 "test_segmented_queue.h"
+
+#include <cds/gc/dhp.h>
+#include <cds/container/segmented_queue.h>
+
+namespace {
+    namespace cc = cds::container;
+    typedef cds::gc::DHP gc_type;
+
+
+    class SegmentedQueue_DHP : public cds_test::segmented_queue
+    {
+    protected:
+        static const size_t c_QuasiFactor = 15;
+        void SetUp()
+        {
+            typedef cc::SegmentedQueue< gc_type, int > queue_type;
+
+            cds::gc::dhp::GarbageCollector::Construct( 16, queue_type::c_nHazardPtrCount );
+            cds::threading::Manager::attachThread();
+        }
+
+        void TearDown()
+        {
+            cds::threading::Manager::detachThread();
+            cds::gc::hp::GarbageCollector::Destruct();
+        }
+    };
+
+    TEST_F( SegmentedQueue_DHP, defaulted )
+    {
+        typedef cds::container::SegmentedQueue< gc_type, int > test_queue;
+
+        test_queue q( c_QuasiFactor );
+        ASSERT_EQ( q.quasi_factor(), cds::beans::ceil2( c_QuasiFactor ));
+        test(q);
+    }
+
+    TEST_F( SegmentedQueue_DHP, mutex )
+    {
+        struct traits : public cds::container::segmented_queue::traits
+        {
+            typedef cds::atomicity::item_counter item_counter;
+            typedef cds::opt::v::random_shuffle_permutation<> permutation_generator;
+        };
+        typedef cds::container::SegmentedQueue< gc_type, int, traits > test_queue;
+
+        test_queue q( c_QuasiFactor );
+        ASSERT_EQ( q.quasi_factor(), cds::beans::ceil2( c_QuasiFactor ) );
+        test( q );
+    }
+
+    TEST_F( SegmentedQueue_DHP, shuffle )
+    {
+        struct traits : public cds::container::segmented_queue::traits
+        {
+            typedef cds::atomicity::item_counter item_counter;
+            typedef cds::opt::v::random_shuffle_permutation<> permutation_generator;
+        };
+        typedef cds::container::SegmentedQueue< gc_type, int, traits > test_queue;
+
+        test_queue q( c_QuasiFactor );
+        ASSERT_EQ( q.quasi_factor(), cds::beans::ceil2( c_QuasiFactor ) );
+        test( q );
+    }
+
+    TEST_F( SegmentedQueue_DHP, stat )
+    {
+        struct traits : public
+            cds::container::segmented_queue::make_traits <
+                cds::opt::item_counter< cds::atomicity::item_counter >
+                , cds::opt::permutation_generator< cds::opt::v::random_permutation<> >
+                , cds::opt::stat < cds::container::segmented_queue::stat<> >
+            > ::type
+        {};
+        typedef cds::container::SegmentedQueue< gc_type, int, traits > test_queue;
+
+        test_queue q( c_QuasiFactor );
+        ASSERT_EQ( q.quasi_factor(), cds::beans::ceil2( c_QuasiFactor ) );
+        test( q );
+    }
+
+    TEST_F( SegmentedQueue_DHP, move )
+    {
+        typedef cds::container::SegmentedQueue< gc_type, std::string > test_queue;
+
+        test_queue q( c_QuasiFactor );
+        ASSERT_EQ( q.quasi_factor(), cds::beans::ceil2( c_QuasiFactor ) );
+        test_string( q );
+    }
+
+    TEST_F( SegmentedQueue_DHP, move_item_counting )
+    {
+        struct traits : public cds::container::segmented_queue::traits
+        {
+            typedef cds::atomicity::item_counter item_counter;
+        };
+        typedef cds::container::SegmentedQueue< gc_type, std::string, traits > test_queue;
+
+        test_queue q( c_QuasiFactor );
+        ASSERT_EQ( q.quasi_factor(), cds::beans::ceil2( c_QuasiFactor ) );
+        test_string( q );
+    }
+
+} // namespace
+
diff --git a/test/unit/queue/segmented_queue_hp.cpp b/test/unit/queue/segmented_queue_hp.cpp
new file mode 100644 (file)
index 0000000..1af21f4
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
+
+    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 "test_segmented_queue.h"
+
+#include <cds/gc/hp.h>
+#include <cds/container/segmented_queue.h>
+
+namespace {
+    namespace cc = cds::container;
+    typedef cds::gc::HP gc_type;
+
+
+    class SegmentedQueue_HP : public cds_test::segmented_queue
+    {
+    protected:
+        static const size_t c_QuasiFactor = 15;
+        void SetUp()
+        {
+            typedef cc::SegmentedQueue< gc_type, int > queue_type;
+
+            cds::gc::hp::GarbageCollector::Construct( queue_type::c_nHazardPtrCount, 1, 16 );
+            cds::threading::Manager::attachThread();
+        }
+
+        void TearDown()
+        {
+            cds::threading::Manager::detachThread();
+            cds::gc::hp::GarbageCollector::Destruct( true );
+        }
+    };
+
+    TEST_F( SegmentedQueue_HP, defaulted )
+    {
+        typedef cds::container::SegmentedQueue< gc_type, int > test_queue;
+
+        test_queue q( c_QuasiFactor );
+        ASSERT_EQ( q.quasi_factor(), cds::beans::ceil2( c_QuasiFactor ));
+        test(q);
+    }
+
+    TEST_F( SegmentedQueue_HP, mutex )
+    {
+        struct traits : public cds::container::segmented_queue::traits
+        {
+            typedef cds::atomicity::item_counter item_counter;
+            typedef cds::opt::v::random_shuffle_permutation<> permutation_generator;
+        };
+        typedef cds::container::SegmentedQueue< cds::gc::HP, int, traits > test_queue;
+
+        test_queue q( c_QuasiFactor );
+        ASSERT_EQ( q.quasi_factor(), cds::beans::ceil2( c_QuasiFactor ) );
+        test( q );
+    }
+
+    TEST_F( SegmentedQueue_HP, shuffle )
+    {
+        struct traits : public cds::container::segmented_queue::traits
+        {
+            typedef cds::atomicity::item_counter item_counter;
+            typedef cds::opt::v::random_shuffle_permutation<> permutation_generator;
+        };
+        typedef cds::container::SegmentedQueue< cds::gc::HP, int, traits > test_queue;
+
+        test_queue q( c_QuasiFactor );
+        ASSERT_EQ( q.quasi_factor(), cds::beans::ceil2( c_QuasiFactor ) );
+        test( q );
+    }
+
+    TEST_F( SegmentedQueue_HP, stat )
+    {
+        struct traits : public
+            cds::container::segmented_queue::make_traits <
+                cds::opt::item_counter< cds::atomicity::item_counter >
+                , cds::opt::permutation_generator< cds::opt::v::random_permutation<> >
+                , cds::opt::stat < cds::container::segmented_queue::stat<> >
+            > ::type
+        {};
+        typedef cds::container::SegmentedQueue< cds::gc::HP, int, traits > test_queue;
+
+        test_queue q( c_QuasiFactor );
+        ASSERT_EQ( q.quasi_factor(), cds::beans::ceil2( c_QuasiFactor ) );
+        test( q );
+    }
+
+    TEST_F( SegmentedQueue_HP, move )
+    {
+        typedef cds::container::SegmentedQueue< gc_type, std::string > test_queue;
+
+        test_queue q( c_QuasiFactor );
+        ASSERT_EQ( q.quasi_factor(), cds::beans::ceil2( c_QuasiFactor ) );
+        test_string( q );
+    }
+
+    TEST_F( SegmentedQueue_HP, move_item_counting )
+    {
+        struct traits : public cds::container::segmented_queue::traits
+        {
+            typedef cds::atomicity::item_counter item_counter;
+        };
+        typedef cds::container::SegmentedQueue< gc_type, std::string, traits > test_queue;
+
+        test_queue q( c_QuasiFactor );
+        ASSERT_EQ( q.quasi_factor(), cds::beans::ceil2( c_QuasiFactor ) );
+        test_string( q );
+    }
+
+} // namespace
+
diff --git a/test/unit/queue/test_bounded_queue.h b/test/unit/queue/test_bounded_queue.h
new file mode 100644 (file)
index 0000000..49de2bb
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
+
+    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.     
+*/
+
+#ifndef CDSUNIT_QUEUE_TEST_BOUNDED_QUEUE_H
+#define CDSUNIT_QUEUE_TEST_BOUNDED_QUEUE_H
+
+#include <cds_test/check_size.h>
+\r
+namespace cds_test {\r
+\r
+    class bounded_queue : public ::testing::Test\r
+    {\r
+    protected:\r
+        template <typename Queue>\r
+        void test( Queue& q )\r
+        {\r
+            typedef typename Queue::value_type value_type;
+            value_type it;
+
+            const size_t nSize = q.capacity();
+
+            ASSERT_TRUE( q.empty() );
+            ASSERT_CONTAINER_SIZE( q, 0 );
+
+            // enqueue/dequeue
+            for ( size_t i = 0; i < nSize; ++i ) {
+                it = static_cast<value_type>(i);
+                ASSERT_TRUE( q.enqueue( it ));
+                ASSERT_CONTAINER_SIZE( q, i + 1 );
+            }
+            ASSERT_FALSE( q.empty() );
+            ASSERT_CONTAINER_SIZE( q, nSize );
+
+            for ( size_t i = 0; i < nSize; ++i ) {
+                it = -1;
+                ASSERT_TRUE( q.dequeue( it ) );
+                ASSERT_EQ( it, i );
+                ASSERT_CONTAINER_SIZE( q, nSize - i - 1 );
+            }
+            ASSERT_TRUE( q.empty() );
+            ASSERT_CONTAINER_SIZE( q, 0 );
+
+            // push/pop
+            for ( size_t i = 0; i < nSize; ++i ) {
+                it = static_cast<value_type>(i);
+                ASSERT_TRUE( q.push( it ));
+                ASSERT_CONTAINER_SIZE( q, i + 1 );
+            }
+            ASSERT_FALSE( q.empty() );
+            ASSERT_CONTAINER_SIZE( q, nSize );
+
+            for ( size_t i = 0; i < nSize; ++i ) {
+                it = -1;
+                ASSERT_TRUE( q.pop( it ) );
+                ASSERT_EQ( it, i );
+                ASSERT_CONTAINER_SIZE( q, nSize - i - 1 );
+            }
+            ASSERT_TRUE( q.empty() );
+            ASSERT_CONTAINER_SIZE( q, 0 );
+
+            // push/pop with lambda
+            for ( size_t i = 0; i < nSize; ++i ) {
+                it = static_cast<value_type>(i);
+                ASSERT_NE( it, -1 );
+                auto f = [&it]( value_type& dest ) { dest = it; it = -1; };
+                if ( i & 1 )
+                    ASSERT_TRUE( q.enqueue_with( f ));
+                else
+                    ASSERT_TRUE( q.push_with( f ));
+                ASSERT_EQ( it, -1 );
+                ASSERT_CONTAINER_SIZE( q, i + 1 );
+            }
+            ASSERT_FALSE( q.empty() );
+            ASSERT_CONTAINER_SIZE( q, nSize );
+
+            for ( size_t i = 0; i < nSize; ++i ) {
+                it = -1;
+                auto f = [&it]( value_type& src ) { it = src; src = -1; };
+                if ( i & 1 )
+                    ASSERT_TRUE( q.pop_with( f ));
+                else
+                    ASSERT_TRUE( q.dequeue_with( f ));
+                ASSERT_EQ( it, i );
+                ASSERT_CONTAINER_SIZE( q, nSize - i - 1 );
+            }
+            ASSERT_TRUE( q.empty() );
+            ASSERT_CONTAINER_SIZE( q, 0 );
+
+            for ( size_t i = 0; i < nSize; ++i ) {
+                ASSERT_TRUE( q.push( static_cast<value_type>(i) ) );
+            }
+            ASSERT_FALSE( q.empty() );
+            ASSERT_CONTAINER_SIZE( q, nSize );
+
+            // push in full queue
+            ASSERT_FALSE( q.push( static_cast<int>(nSize * 2 )));
+            ASSERT_FALSE( q.empty() );
+            ASSERT_CONTAINER_SIZE( q, nSize );
+            it = static_cast<int>( nSize * 2 );
+            ASSERT_FALSE( q.enqueue( it ));
+            ASSERT_FALSE( q.empty() );
+            ASSERT_CONTAINER_SIZE( q, nSize );
+
+            // clear
+            q.clear();
+            ASSERT_TRUE( q.empty() );
+            ASSERT_CONTAINER_SIZE( q, 0 );
+
+            // pop from empty queue
+            it = static_cast<int>(nSize * 2);
+            ASSERT_FALSE( q.pop( it ) );
+            ASSERT_EQ( it, nSize * 2 );
+            ASSERT_TRUE( q.empty() );
+            ASSERT_CONTAINER_SIZE( q, 0 );
+
+            ASSERT_FALSE( q.dequeue( it ) );
+            ASSERT_EQ( it, nSize * 2 );
+            ASSERT_TRUE( q.empty() );
+            ASSERT_CONTAINER_SIZE( q, 0 );
+        }\r
+\r
+        template <class Queue>
+        void test_string( Queue& q )
+        {
+            std::string str[3];
+            str[0] = "one";
+            str[1] = "two";
+            str[2] = "three";
+            const size_t nSize = sizeof( str ) / sizeof( str[0] );
+
+            // emplace
+            for ( size_t i = 0; i < nSize; ++i ) {
+                ASSERT_TRUE( q.emplace( str[i].c_str()));
+                ASSERT_CONTAINER_SIZE( q, i + 1 );
+            }
+            ASSERT_FALSE( q.empty() );
+            ASSERT_CONTAINER_SIZE( q, nSize );
+
+            {
+                std::string s;
+                auto f = [&s]( std::string& src ) {
+                    ASSERT_FALSE( src.empty() );
+                    s = std::move( src );
+                    ASSERT_NE( s, src );
+                };
+                for ( size_t i = 0; i < nSize; ++i ) {
+                    if ( i & 1 )
+                        ASSERT_TRUE( q.pop_with( f ));
+                    else
+                        ASSERT_TRUE( q.dequeue_with( f ));
+
+                    ASSERT_CONTAINER_SIZE( q, nSize - i - 1 );
+                    ASSERT_EQ( s, str[i] );
+                }
+            }
+            ASSERT_TRUE( q.empty() );
+            ASSERT_CONTAINER_SIZE( q, 0 );
+
+
+            // move push
+            for ( size_t i = 0; i < nSize; ++i ) {
+                std::string s = str[i];
+                ASSERT_FALSE( s.empty());
+                if ( i & 1 )
+                    ASSERT_TRUE( q.enqueue( std::move( s )));
+                else
+                    ASSERT_TRUE( q.push( std::move( s )));
+                ASSERT_TRUE( s.empty() );
+                ASSERT_CONTAINER_SIZE( q, i + 1 );
+            }
+            ASSERT_FALSE( q.empty() );
+            ASSERT_CONTAINER_SIZE( q, nSize );
+
+            for ( size_t i = 0; i < nSize; ++i ) {
+                std::string s;
+                ASSERT_TRUE( q.pop( s ) );
+                ASSERT_CONTAINER_SIZE( q, nSize - i - 1 );
+                ASSERT_EQ( s, str[i] );
+            }
+            ASSERT_TRUE( q.empty() );
+            ASSERT_CONTAINER_SIZE( q, 0 );
+        }
+\r
+    };\r
+\r
+} // namespace cds_test\r
+\r
+#endif // CDSUNIT_QUEUE_TEST_BOUNDED_QUEUE_H\r
index 28554f06aa84db1f24e132d0691e02dc02d0e987..5efc72cb92f11c6f305fbab26a28b5bbeaa9b7e1 100644 (file)
 #define CDSUNIT_QUEUE_TEST_GENERIC_QUEUE_H
 
 #include <cds_test/check_size.h>
-\r
-namespace cds_test {\r
-\r
-    class generic_queue : public ::testing::Test\r
-    {\r
-    protected:\r
-        template <typename Queue>\r
-        void test( Queue& q )\r
-        {\r
+
+namespace cds_test {
+
+    class generic_queue : public ::testing::Test
+    {
+    protected:
+        template <typename Queue>
+        void test( Queue& q )
+        {
             typedef typename Queue::value_type value_type;
             value_type it;
 
@@ -135,8 +135,8 @@ namespace cds_test {
             ASSERT_EQ( it, nSize * 2 );
             ASSERT_TRUE( q.empty() );
             ASSERT_CONTAINER_SIZE( q, 0 );
-        }\r
-\r
+        }
+
         template <class Queue>
         void test_string( Queue& q )
         {
@@ -159,7 +159,7 @@ namespace cds_test {
                 auto f = [&s]( std::string& src ) {
                     ASSERT_FALSE( src.empty() );
                     s = std::move( src );
-                    ASSERT_TRUE( src.empty() );
+                    ASSERT_NE( s, src );
                 };
                 for ( size_t i = 0; i < nSize; ++i ) {
                     if ( i & 1 )
@@ -198,9 +198,9 @@ namespace cds_test {
             ASSERT_TRUE( q.empty() );
             ASSERT_CONTAINER_SIZE( q, 0 );
         }
-\r
-    };\r
-\r
-} // namespace cds_test\r
-\r
-#endif // CDSUNIT_QUEUE_TEST_GENERIC_QUEUE_H\r
+
+    };
+
+} // namespace cds_test
+
+#endif // CDSUNIT_QUEUE_TEST_GENERIC_QUEUE_H
diff --git a/test/unit/queue/test_segmented_queue.h b/test/unit/queue/test_segmented_queue.h
new file mode 100644 (file)
index 0000000..0ad17b5
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
+
+    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.     
+*/
+
+#ifndef CDSUNIT_QUEUE_TEST_SEGMENTED_QUEUE_H
+#define CDSUNIT_QUEUE_TEST_SEGMENTED_QUEUE_H
+
+#include <cds_test/check_size.h>
+\r
+namespace cds_test {\r
+\r
+    class segmented_queue : public ::testing::Test\r
+    {\r
+    protected:\r
+        template <typename Queue>\r
+        void test( Queue& q )\r
+        {\r
+            typedef typename Queue::value_type value_type;
+            value_type it;
+
+            const size_t nSize = 100;
+
+            ASSERT_TRUE( q.empty() );
+            ASSERT_CONTAINER_SIZE( q, 0 );
+
+            // enqueue/dequeue
+            for ( size_t i = 0; i < nSize; ++i ) {
+                it = static_cast<value_type>(i);
+                ASSERT_TRUE( q.enqueue( it ));
+                ASSERT_CONTAINER_SIZE( q, i + 1 );
+            }
+            ASSERT_FALSE( q.empty() );
+            ASSERT_CONTAINER_SIZE( q, nSize );
+
+            for ( size_t i = 0; i < nSize; ++i ) {
+                it = -1;
+                ASSERT_TRUE( q.dequeue( it ) );
+                ASSERT_CONTAINER_SIZE( q, nSize - i - 1 );
+
+                int nSegment = int( i / q.quasi_factor() );
+                int nMin = nSegment * int( q.quasi_factor() );
+                int nMax = nMin + int( q.quasi_factor() ) - 1;
+                EXPECT_LE( nMin, it );
+                EXPECT_LE( it, nMax );
+            }
+            ASSERT_TRUE( q.empty() );
+            ASSERT_CONTAINER_SIZE( q, 0 );
+
+            // push/pop
+            for ( size_t i = 0; i < nSize; ++i ) {
+                it = static_cast<value_type>(i);
+                ASSERT_TRUE( q.push( it ));
+                ASSERT_CONTAINER_SIZE( q, i + 1 );
+            }
+            ASSERT_FALSE( q.empty() );
+            ASSERT_CONTAINER_SIZE( q, nSize );
+
+            size_t nPushed = nSize;
+            size_t nStartSegment = nPushed / q.quasi_factor();
+            size_t nOffset = nPushed % q.quasi_factor();
+            for ( size_t i = 0; i < nSize; ++i ) {
+                it = -1;
+                ASSERT_TRUE( q.pop( it ) );
+                ASSERT_CONTAINER_SIZE( q, nSize - i - 1 );
+
+                int nSegment = static_cast<int>((i + nPushed) / q.quasi_factor() - nStartSegment );
+                int nMin = nSegment * static_cast<int>( q.quasi_factor());
+                if ( nSegment )
+                    nMin -= static_cast<int>( nOffset );
+                int nMax = nMin + static_cast<int>( q.quasi_factor()) - 1;
+                EXPECT_LE( nMin, it );
+                EXPECT_LE( it, nMax );
+            }
+            ASSERT_TRUE( q.empty() );
+            ASSERT_CONTAINER_SIZE( q, 0 );
+
+            // push/pop with lambda
+            for ( size_t i = 0; i < nSize; ++i ) {
+                it = static_cast<value_type>(i);
+                EXPECT_NE( it, -1 );
+                auto f = [&it]( value_type& dest ) { dest = it; it = -1; };
+                if ( i & 1 )
+                    ASSERT_TRUE( q.enqueue_with( f ));
+                else
+                    ASSERT_TRUE( q.push_with( f ));
+                ASSERT_EQ( it, -1 );
+                ASSERT_CONTAINER_SIZE( q, i + 1 );
+            }
+            ASSERT_FALSE( q.empty() );
+            ASSERT_CONTAINER_SIZE( q, nSize );
+
+            nPushed += nSize;
+            nStartSegment = nPushed / q.quasi_factor();
+            nOffset = nPushed % q.quasi_factor();
+            for ( size_t i = 0; i < nSize; ++i ) {
+                it = -1;
+                auto f = [&it]( value_type& src ) { it = src; src = -1; };
+                if ( i & 1 )
+                    ASSERT_TRUE( q.pop_with( f ));
+                else
+                    ASSERT_TRUE( q.dequeue_with( f ));
+                ASSERT_CONTAINER_SIZE( q, nSize - i - 1 );
+
+                int nSegment = static_cast<int>((i + nPushed) / q.quasi_factor() - nStartSegment);
+                int nMin = nSegment * static_cast<int>(q.quasi_factor());
+                if ( nSegment )
+                    nMin -= static_cast<int>(nOffset);
+                int nMax = nMin + static_cast<int>(q.quasi_factor()) - 1;
+                EXPECT_LE( nMin, it );
+                EXPECT_LE( it, nMax );
+            }
+            ASSERT_TRUE( q.empty() );
+            ASSERT_CONTAINER_SIZE( q, 0 );
+
+            // clear
+            for ( size_t i = 0; i < nSize; ++i ) {
+                ASSERT_TRUE( q.push( static_cast<value_type>(i) ) );
+            }
+            ASSERT_FALSE( q.empty() );
+            ASSERT_CONTAINER_SIZE( q, nSize );
+
+            q.clear();
+            ASSERT_TRUE( q.empty() );
+            ASSERT_CONTAINER_SIZE( q, 0 );
+
+            // pop from empty queue
+            it = nSize * 2;
+            ASSERT_FALSE( q.pop( it ) );
+            ASSERT_EQ( it, nSize * 2 );
+            ASSERT_TRUE( q.empty() );
+            ASSERT_CONTAINER_SIZE( q, 0 );
+
+            ASSERT_FALSE( q.dequeue( it ) );
+            ASSERT_EQ( it, nSize * 2 );
+            ASSERT_TRUE( q.empty() );
+            ASSERT_CONTAINER_SIZE( q, 0 );
+        }\r
+\r
+        template <class Queue>
+        void test_string( Queue& q )
+        {
+            std::string str[3];
+            str[0] = "one";
+            str[1] = "two";
+            str[2] = "three";
+            const size_t nSize = sizeof( str ) / sizeof( str[0] );
+
+            // emplace
+            for ( size_t i = 0; i < nSize; ++i ) {
+                ASSERT_TRUE( q.emplace( str[i].c_str()));
+                ASSERT_CONTAINER_SIZE( q, i + 1 );
+            }
+            ASSERT_FALSE( q.empty() );
+            ASSERT_CONTAINER_SIZE( q, nSize );
+
+            {
+                std::string s;
+                auto f = [&s]( std::string& src ) {
+                    ASSERT_FALSE( src.empty() );
+                    s = std::move( src );
+                    ASSERT_NE( s, src );
+                };
+                for ( size_t i = 0; i < nSize; ++i ) {
+                    if ( i & 1 )
+                        ASSERT_TRUE( q.pop_with( f ));
+                    else
+                        ASSERT_TRUE( q.dequeue_with( f ));
+
+                    ASSERT_CONTAINER_SIZE( q, nSize - i - 1 );
+                    ASSERT_TRUE( s == str[0] || s == str[1] || s == str[2] );
+                }
+            }
+            ASSERT_TRUE( q.empty() );
+            ASSERT_CONTAINER_SIZE( q, 0 );
+
+
+            // move push
+            for ( size_t i = 0; i < nSize; ++i ) {
+                std::string s = str[i];
+                ASSERT_FALSE( s.empty() );
+                if ( i & 1 )
+                    ASSERT_TRUE( q.enqueue( std::move( s )));
+                else
+                    ASSERT_TRUE( q.push( std::move( s )));
+                ASSERT_TRUE( s.empty() );
+                ASSERT_CONTAINER_SIZE( q, i + 1 );
+            }
+            ASSERT_FALSE( q.empty() );
+            ASSERT_CONTAINER_SIZE( q, nSize );
+
+            for ( size_t i = 0; i < nSize; ++i ) {
+                std::string s;
+                ASSERT_TRUE( q.pop( s ) );
+                ASSERT_CONTAINER_SIZE( q, nSize - i - 1 );
+                ASSERT_TRUE( s == str[0] || s == str[1] || s == str[2] );
+            }
+            ASSERT_TRUE( q.empty() );
+            ASSERT_CONTAINER_SIZE( q, 0 );
+        }
+\r
+    };\r
+\r
+} // namespace cds_test\r
+\r
+#endif // CDSUNIT_QUEUE_TEST_SEGMENTED_QUEUE_H\r
diff --git a/test/unit/queue/tsigas_queue.cpp b/test/unit/queue/tsigas_queue.cpp
new file mode 100644 (file)
index 0000000..f82e2d5
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
+
+    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 "test_bounded_queue.h"
+
+#include <cds/container/tsigas_cycle_queue.h>
+
+namespace {
+    namespace cc = cds::container;
+
+    class TsigasCycleQueue: public cds_test::bounded_queue
+    {};
+
+    TEST_F( TsigasCycleQueue, defaulted )
+    {
+        typedef cds::container::TsigasCycleQueue< int > test_queue;
+
+        test_queue q( 128 );
+        test(q);
+    }
+
+    TEST_F( TsigasCycleQueue, stat )
+    {
+        struct traits: public cds::container::tsigas_queue::traits
+        {
+            typedef cds::opt::v::static_buffer<int, 128> buffer;
+        };
+        typedef cds::container::TsigasCycleQueue< int, traits > test_queue;
+
+        test_queue q;
+        test( q );
+    }
+
+    TEST_F( TsigasCycleQueue, stat_item_counting )
+    {
+        
+        typedef cds::container::TsigasCycleQueue< int,
+            cds::container::tsigas_queue::make_traits<
+                cds::opt::buffer< cds::opt::v::static_buffer<int, 128>>
+                , cds::opt::item_counter< cds::atomicity::item_counter>
+            >::type
+        > test_queue;
+
+        test_queue q;
+        test( q );
+    }
+
+    TEST_F( TsigasCycleQueue, dynamic )
+    {
+        struct traits : public cds::container::tsigas_queue::traits
+        {
+            typedef cds::opt::v::dynamic_buffer<int> buffer;
+        };
+        typedef cds::container::TsigasCycleQueue< int, traits > test_queue;
+
+        test_queue q( 128 );
+        test( q );
+    }
+
+    TEST_F( TsigasCycleQueue, dynamic_item_counting )
+    {
+        typedef cds::container::TsigasCycleQueue< int,
+            cds::container::tsigas_queue::make_traits<
+                cds::opt::buffer< cds::opt::v::dynamic_buffer<int>>
+                , cds::opt::item_counter< cds::atomicity::item_counter>
+            >::type
+        > test_queue;
+
+        test_queue q( 128 );
+        test( q );
+    }
+
+    TEST_F( TsigasCycleQueue, dynamic_padding )
+    {
+        struct traits : public cds::container::tsigas_queue::traits
+        {
+            typedef cds::opt::v::dynamic_buffer<int> buffer;
+            enum { alignment = 16 };
+        };
+        typedef cds::container::TsigasCycleQueue< int, traits > test_queue;
+
+        test_queue q( 128 );
+        test( q );
+    }
+
+    TEST_F( TsigasCycleQueue, move )
+    {
+        typedef cds::container::TsigasCycleQueue< std::string > test_queue;
+
+        test_queue q( 128 );
+        test_string( q );
+    }
+
+    TEST_F( TsigasCycleQueue, move_item_counting )
+    {
+        struct traits : public cds::container::tsigas_queue::traits
+        {
+            typedef cds::atomicity::item_counter item_counter;
+        };
+        typedef cds::container::TsigasCycleQueue< std::string, traits > test_queue;
+
+        test_queue q( 128 );
+        test_string( q );
+    }
+
+} // namespace
+
diff --git a/test/unit/queue/vyukov_mpmc_queue.cpp b/test/unit/queue/vyukov_mpmc_queue.cpp
new file mode 100644 (file)
index 0000000..c9aa9c1
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
+
+    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 "test_bounded_queue.h"
+
+#include <cds/container/vyukov_mpmc_cycle_queue.h>
+
+namespace {
+    namespace cc = cds::container;
+
+    class VyukovMPMCCycleQueue: public cds_test::bounded_queue
+    {};
+
+    TEST_F( VyukovMPMCCycleQueue, defaulted )
+    {
+        typedef cds::container::VyukovMPMCCycleQueue< int > test_queue;
+
+        test_queue q( 128 );
+        test(q);
+    }
+
+    TEST_F( VyukovMPMCCycleQueue, stat )
+    {
+        struct traits: public cds::container::vyukov_queue::traits
+        {
+            typedef cds::opt::v::static_buffer<int, 128> buffer;
+        };
+        typedef cds::container::VyukovMPMCCycleQueue< int, traits > test_queue;
+
+        test_queue q;
+        test( q );
+    }
+
+    TEST_F( VyukovMPMCCycleQueue, stat_item_counting )
+    {
+        
+        typedef cds::container::VyukovMPMCCycleQueue< int,
+            cds::container::vyukov_queue::make_traits<
+                cds::opt::buffer< cds::opt::v::static_buffer<int, 128>>
+                , cds::opt::item_counter< cds::atomicity::item_counter>
+            >::type
+        > test_queue;
+
+        test_queue q;
+        test( q );
+    }
+
+    TEST_F( VyukovMPMCCycleQueue, dynamic )
+    {
+        struct traits : public cds::container::vyukov_queue::traits
+        {
+            typedef cds::opt::v::dynamic_buffer<int> buffer;
+        };
+        typedef cds::container::VyukovMPMCCycleQueue< int, traits > test_queue;
+
+        test_queue q( 128 );
+        test( q );
+    }
+
+    TEST_F( VyukovMPMCCycleQueue, dynamic_item_counting )
+    {
+        typedef cds::container::VyukovMPMCCycleQueue< int,
+            cds::container::vyukov_queue::make_traits<
+                cds::opt::buffer< cds::opt::v::dynamic_buffer<int>>
+                , cds::opt::item_counter< cds::atomicity::item_counter>
+            >::type
+        > test_queue;
+
+        test_queue q( 128 );
+        test( q );
+    }
+
+    TEST_F( VyukovMPMCCycleQueue, dynamic_padding )
+    {
+        struct traits : public cds::container::vyukov_queue::traits
+        {
+            typedef cds::opt::v::dynamic_buffer<int> buffer;
+            enum { padding = 64 };
+        };
+        typedef cds::container::VyukovMPMCCycleQueue< int, traits > test_queue;
+
+        test_queue q( 128 );
+        test( q );
+    }
+
+    TEST_F( VyukovMPMCCycleQueue, move )
+    {
+        typedef cds::container::VyukovMPMCCycleQueue< std::string > test_queue;
+
+        test_queue q( 128 );
+        test_string( q );
+    }
+
+    TEST_F( VyukovMPMCCycleQueue, move_item_counting )
+    {
+        struct traits : public cds::container::vyukov_queue::traits
+        {
+            typedef cds::atomicity::item_counter item_counter;
+        };
+        typedef cds::container::VyukovMPMCCycleQueue< std::string, traits > test_queue;
+
+        test_queue q( 128 );
+        test_string( q );
+    }
+
+} // namespace
+