Merged branch 'master' of https://github.com/Nemo1369/libcds
[libcds.git] / cds / algo / int_algo.h
index 4593f3c5f92c585a6348a80f81c2da99f0e76299..cc6cfd26702430c3e76193fe13f349bc60c58201 100644 (file)
@@ -1,7 +1,7 @@
 /*
     This file is a part of libcds - Concurrent Data Structures library
 
-    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
+    (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/
@@ -34,7 +34,7 @@
 #include <cds/algo/bitop.h>
 
 namespace cds { namespace beans {
-
+#if CDS_BUILD_BITS == 64
     /// Returns largest previous integer for <tt>log2( n )</tt>
     static inline size_t log2floor( size_t n )
     {
@@ -97,6 +97,77 @@ namespace cds { namespace beans {
     {
         return is_power2(n) ? log2floor(n) : 0;
     }
+
+#elif CDS_BUILD_BITS == 32
+    //@cond
+    // 64bit specializations
+
+/// Returns largest previous integer for <tt>log2( n )</tt>
+    static inline uint64_t log2floor( uint64_t n )
+    {
+        return n ? cds::bitop::MSBnz( n ) : 0;
+    }
+
+/// Returns smallest following integer for <tt>log2( n )</tt>
+    static inline uint64_t log2ceil( uint64_t n )
+    {
+        uint64_t i = log2floor( n );
+        return (uint64_t( 1 ) << i) < n ? i + 1 : i;
+    }
+
+/// Returns largest previous power of 2 for \p n
+    /**
+        Examples:
+        \code
+        floor2(0) == 1   // !!!
+        floor2(1) == 1
+        floor2(2) == 2
+        floor2(3) == 2
+        floor2(4) == 4
+        floor2(15) == 8
+        floor2(16) == 16
+        floor2(17) == 16
+        \endcode
+    */
+    static inline uint64_t floor2( uint64_t n )
+    {
+        return uint64_t( 1 ) << log2floor( n );
+    }
+
+/// Returns smallest following power of 2 for \p n
+    /**
+        Examples:
+        \code
+        ceil2(0) == 1   // !!!
+        ceil2(1) == 1
+        ceil2(2) == 2
+        ceil2(3) == 4
+        ceil2(4) == 4
+        ceil2(15) == 16
+        ceil2(16) == 16
+        ceil2(17) == 32
+        \endcode
+    */
+    static inline uint64_t ceil2( uint64_t n )
+    {
+        return uint64_t( 1 ) << log2ceil( n );
+    }
+
+/// Checks if \p n is power of 2
+    CDS_CONSTEXPR static inline bool is_power2( uint64_t n ) CDS_NOEXCEPT
+    {
+        return (n & (n - 1)) == 0 && n;
+    }
+
+/// Returns binary logarithm of \p n if \p n is power of two, otherwise returns 0
+    static inline uint64_t log2( uint64_t n )
+    {
+        return is_power2( n ) ? log2floor( n ) : 0;
+    }
+
+    //@endcond
+#endif
+
 }}   // namespace cds::beans
 
 #endif  // #ifndef CDSLIB_INT_ALGO_H