[UBsan] Fixed signed integer overflow
[libcds.git] / test / include / cds_test / fc_hevy_value.h
index 71693f72a92b9e08378d8e625f1494d3cff0de13..4159bd7f45bcb8dd980adfc61fda21548b59df53 100644 (file)
@@ -8,51 +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{
-       template<int DefaultSize = 10000>
-       struct HeavyValue {
-               static std::vector<int> pop_buff;
-               int value;
-               size_t buffer_size;
-
-               size_t nNo;
-               size_t nWriterNo;
-
-               explicit HeavyValue(int new_value = 0, size_t new_bufer_size = DefaultSize)
-               : value(new_value),
-                 buffer_size(new_bufer_size),
-                 nNo(0),
-                 nWriterNo(0)
-
-               {
-                       if( buffer_size != pop_buff.size() ){
-                               pop_buff.resize(buffer_size);
-                       }
-               };
-               HeavyValue(const HeavyValue &other)
-                       : value(other.value),
-                         buffer_size(other.buffer_size)
-               {
-                       working(other);
-               }
-               void operator=(const int& new_value)
-               {
-                       value = new_value;
-               }
-               bool operator==(const int new_value) const
-               {
-                       return value == new_value;
-               }
-               void working(const HeavyValue &other) {
-                       for (size_t i = 0; i < buffer_size; ++i)
-                               pop_buff[i] =  static_cast<int>(std::sqrt(other.pop_buff[i]));
-               }
-       };
-
-       template<int DefaultSize>
-       std::vector<int> HeavyValue< DefaultSize >::pop_buff = {};
+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 heavy_value {
+
+        int value;
+
+        size_t nNo;
+        size_t nWriterNo;
+
+        static std::vector<int> pop_buff;
+        static size_t buffer_size;
+
+        explicit heavy_value(int new_value = 0)
+        : value(new_value),
+          nNo(0),
+          nWriterNo(0)
+        {};
+
+        heavy_value( heavy_value const& other)
+            : value(other.value)
+            , 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( std::abs( static_cast<double>( pop_buff[i] ) * rand())));
+        }
+
+        void set_array(size_t new_size) 
+        {
+            set_array_size(new_size);
+        }
+
+        static void set_array_size(size_t new_size)
+        {
+            if (buffer_size == new_size) return;
+            buffer_size = new_size;
+            pop_buff.resize(buffer_size, rand());
+        }
+    };
+
+    template<int DefaultSize>
+    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_ */