Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r63786 - in sandbox/SOC/2010/bits_and_ints: boost/integer libs/integer/test
From: muriloufg_at_[hidden]
Date: 2010-07-09 14:44:58


Author: murilov
Date: 2010-07-09 14:44:56 EDT (Fri, 09 Jul 2010)
New Revision: 63786
URL: http://svn.boost.org/trac/boost/changeset/63786

Log:
Added static_safe_avg<> and mpl::safe_avg<> metafunctions
Added:
   sandbox/SOC/2010/bits_and_ints/boost/integer/static_safe_avg.hpp (contents, props changed)
   sandbox/SOC/2010/bits_and_ints/libs/integer/test/safe_avg_test.cpp (contents, props changed)
Text files modified:
   sandbox/SOC/2010/bits_and_ints/libs/integer/test/Jamfile.v2 | 1 +
   sandbox/SOC/2010/bits_and_ints/libs/integer/test/clear_least_bit_set_test.cpp | 2 +-
   sandbox/SOC/2010/bits_and_ints/libs/integer/test/count_trailing_zeros_test.cpp | 2 +-
   3 files changed, 3 insertions(+), 2 deletions(-)

Added: sandbox/SOC/2010/bits_and_ints/boost/integer/static_safe_avg.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/bits_and_ints/boost/integer/static_safe_avg.hpp 2010-07-09 14:44:56 EDT (Fri, 09 Jul 2010)
@@ -0,0 +1,58 @@
+// Boost integer/static_safe_avg.hpp header file ------------------------------//
+
+// (C) Copyright Murilo Adriano Vasconcelos 2010.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#ifndef BOOST_STATIC_SAFE_AVG_INCLUDED
+#define BOOST_STATIC_SAFE_AVG_INCLUDED
+
+#include <boost/mpl/and.hpp>
+#include <boost/mpl/integral_c.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/integer/is_integral_constant.hpp>
+
+namespace boost {
+
+/*
+ * Given two constant values x and y, the (floor of the) average normally
+ * would be computed by (x+y)/2 unfortunately,
+ * this can yield incorrect results due to overflow.
+ *
+ * `static_safe_avg<T, x, y>::value' and mpl::safe_avg<IC1, IC2>::value ensures
+ * that no overflow will happen even if (x+y) overflows the range of T.
+ */
+
+namespace mpl {
+
+template <typename IC1, typename IC2,
+ class Enable = typename enable_if<
+ and_<
+ is_integral_constant<IC1>,
+ is_integral_constant<IC2>
+ >
+ >::type
+>
+struct safe_avg : integral_c<
+ typename IC1::value_type,
+ ((IC1::value & IC2::value) + ((IC1::value ^ IC2::value) >> 1))
+>
+{};
+
+}
+
+template <typename T, T Value1, T Value2,
+ class Enable = typename enable_if< is_integral<T> >::type>
+struct static_safe_avg : mpl::safe_avg<
+ mpl::integral_c<T, Value1>,
+ mpl::integral_c<T, Value2>
+>
+{};
+
+} // boost
+
+#endif

Modified: sandbox/SOC/2010/bits_and_ints/libs/integer/test/Jamfile.v2
==============================================================================
--- sandbox/SOC/2010/bits_and_ints/libs/integer/test/Jamfile.v2 (original)
+++ sandbox/SOC/2010/bits_and_ints/libs/integer/test/Jamfile.v2 2010-07-09 14:44:56 EDT (Fri, 09 Jul 2010)
@@ -24,6 +24,7 @@
                 [ run pop_count_test.cpp ]
                 [ run count_trailing_zeros_test.cpp ]
                 [ run clear_least_bit_set_test.cpp ]
+ [ run safe_avg_test.cpp ]
         [ compile cstdint_include_test.cpp ]
         [ compile integer_traits_include_test.cpp ]
         [ compile integer_include_test.cpp ]

Modified: sandbox/SOC/2010/bits_and_ints/libs/integer/test/clear_least_bit_set_test.cpp
==============================================================================
--- sandbox/SOC/2010/bits_and_ints/libs/integer/test/clear_least_bit_set_test.cpp (original)
+++ sandbox/SOC/2010/bits_and_ints/libs/integer/test/clear_least_bit_set_test.cpp 2010-07-09 14:44:56 EDT (Fri, 09 Jul 2010)
@@ -20,7 +20,7 @@
 // Main testing function
 int main(int, char* [])
 {
- std::cout << "Doing tests on pop_count functions." << std::endl;
+ std::cout << "Doing tests on clear_least_bit_set functions." << std::endl;
         
         CLEAR_LEAST_BIT_SET_TEST(0x0, 0);
         CLEAR_LEAST_BIT_SET_TEST(0x1, 0);

Modified: sandbox/SOC/2010/bits_and_ints/libs/integer/test/count_trailing_zeros_test.cpp
==============================================================================
--- sandbox/SOC/2010/bits_and_ints/libs/integer/test/count_trailing_zeros_test.cpp (original)
+++ sandbox/SOC/2010/bits_and_ints/libs/integer/test/count_trailing_zeros_test.cpp 2010-07-09 14:44:56 EDT (Fri, 09 Jul 2010)
@@ -20,7 +20,7 @@
 // Main testing function
 int main(int, char* [])
 {
- std::cout << "Doing tests on pop_count functions." << std::endl;
+ std::cout << "Doing tests on count_trailing_zeros functions." << std::endl;
         
         COUNT_ZEROS_TEST(0xF00000000, 32);
         COUNT_ZEROS_TEST(0x1, 0);

Added: sandbox/SOC/2010/bits_and_ints/libs/integer/test/safe_avg_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/bits_and_ints/libs/integer/test/safe_avg_test.cpp 2010-07-09 14:44:56 EDT (Fri, 09 Jul 2010)
@@ -0,0 +1,37 @@
+// Boost safe_avg_test.hpp test program --------------------------------------//
+
+// (C) Copyright Murilo Adriano Vasconcelos 2010.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/integer/safe_avg.hpp>
+#include <boost/integer/static_safe_avg.hpp>
+#include <boost/mpl/integral_c.hpp>
+
+#include <iostream>
+
+#define SAFE_AVG_TEST(x, y, z) \
+BOOST_TEST((::boost::safe_avg(x, y) == z)); \
+BOOST_TEST(((::boost::mpl::safe_avg< ::boost::mpl::integral_c<int, x>, ::boost::mpl::integral_c<int, y> >::value) == z))
+
+
+// Main testing function
+int main(int, char* [])
+{
+ std::cout << "Doing tests on safe_avg functions." << std::endl;
+
+ SAFE_AVG_TEST(0, 0, 0);
+ SAFE_AVG_TEST(0, 1, 0);
+ SAFE_AVG_TEST(1, 1, 1);
+ SAFE_AVG_TEST(1, 2, 1);
+ SAFE_AVG_TEST(3, 1, 2);
+ SAFE_AVG_TEST(1000, 200, 600);
+ SAFE_AVG_TEST(1000000000, 2000000000, 1500000000);
+ SAFE_AVG_TEST(2000000000, 2000000000, 2000000000);
+ SAFE_AVG_TEST(-1000000000, 2000000000, 500000000);
+ SAFE_AVG_TEST(-2000000000, -2000000000, -2000000000);
+
+ return boost::report_errors();
+}


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk