[UBsan] Fixed signed integer overflow
[libcds.git] / test / include / cds_test / fc_hevy_value.h
index b53e98a..4159bd7 100644 (file)
@@ -8,68 +8,72 @@
 #ifndef SOURCE_DIRECTORY__TEST_INCLUDE_CDS_TEST_FC_HEAVY_VALUE_H_
 #define SOURCE_DIRECTORY__TEST_INCLUDE_CDS_TEST_FC_HEAVY_VALUE_H_
 
-#include <math.h>
+#include <cmath>
 #include <vector>
 
-namespace{
+namespace fc_test {
+
+    // SFINAE test
+    template <typename T>
+    class has_set_array_size {
+        typedef char select_small;
+        class select_big {
+            char dummy[2];
+        };
+
+        template <typename C, void (C::*) (size_t)> class selector
+        {};
+
+        template <typename C> static select_small test( selector<C, &C::set_array>* ) ;
+        template <typename C> static select_big   test(...);
+
+    public:
+        static constexpr bool value = sizeof(test<T>(0)) == sizeof(char) ;
+    };
+
     template<int DefaultSize = 10>
-    struct HeavyValue {
+    struct heavy_value {
 
         int value;
-        size_t buffer_size;
 
         size_t nNo;
         size_t nWriterNo;
+
         static std::vector<int> pop_buff;
+        static size_t buffer_size;
 
-        explicit HeavyValue(int new_value = 0, size_t new_bufer_size = DefaultSize)
+        explicit heavy_value(int new_value = 0)
         : value(new_value),
-          buffer_size(new_bufer_size),
           nNo(0),
           nWriterNo(0)
+        {};
+
+        heavy_value( heavy_value const& other)
+            : value(other.value)
+            , nNo(other.nNo)
+            , nWriterNo(other.nWriterNo)
         {
-            if( buffer_size != pop_buff.size() ){
-                pop_buff.resize(buffer_size);
-                for(size_t i = 0; i < buffer_size; ++i)
-                   pop_buff[i] = i;
-            }
-        };
-        HeavyValue(const HeavyValue &other)
-            : value(other.value),
-              buffer_size(other.buffer_size),
-              nNo(other.nNo),
-              nWriterNo(other.nWriterNo)
-        {
+            // This is an imitation of heavy copy ctor
             for(size_t i = 0; i < buffer_size; ++i)
-                pop_buff[i] =  static_cast<int>(std::sqrt(other.pop_buff[i]));
+                pop_buff[i] = static_cast<int>( std::sqrt( std::abs( static_cast<double>( pop_buff[i] ) * rand())));
         }
-        void operator=(const int& new_value)
-        {
-            value = new_value;
-        }
-        bool operator==(const int new_value) const
-        {
-            return value == new_value;
-        }
-        bool operator<=(const int new_value) const
-        {
-            return value <= new_value;
-        }
-        bool operator<(const int new_value) const
-        {
-            return value < new_value;
-        }
-        bool operator>(const int new_value) const
+
+        void set_array(size_t new_size) 
         {
-            return value > new_value;
+            set_array_size(new_size);
         }
-        bool operator>=(const int new_value) const
+
+        static void set_array_size(size_t new_size)
         {
-            return value >= new_value;
+            if (buffer_size == new_size) return;
+            buffer_size = new_size;
+            pop_buff.resize(buffer_size, rand());
         }
     };
 
     template<int DefaultSize>
-    std::vector<int> HeavyValue< DefaultSize >::pop_buff = {};
+    std::vector<int> heavy_value< DefaultSize >::pop_buff(DefaultSize, rand());
+    template<int DefaultSize>
+    std::vector<int>::size_type heavy_value< DefaultSize >::buffer_size = DefaultSize;
 }
 #endif /* SOURCE_DIRECTORY__TEST_INCLUDE_CDS_TEST_FC_HEVY_VALUE_H_ */