diff --git a/doc/integer.qbk b/doc/integer.qbk index 334b84e..d1d9acb 100644 --- a/doc/integer.qbk +++ b/doc/integer.qbk @@ -728,7 +728,7 @@ Simple examples of finding the minimum and maximum values are [integer_min_max_example_1] -A more complex example showing static compiler-time computation of the biggest size of two arrays, plus 1, using a class adder. +A more complex example showing static compile-time computation of the biggest size of two arrays, plus 1, using a class `adder`. [integer_min_max_example_0] diff --git a/example/integer_common_factor_example.cpp b/example/integer_common_factor_example.cpp new file mode 100644 index 0000000..96c83fe --- /dev/null +++ b/example/integer_common_factor_example.cpp @@ -0,0 +1,60 @@ +// boost integer_common_factor_example.cpp + +// Copyright Paul A. Bristow 2015 +// Use, modification and distribution are subject to 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) + +// Caution: this file contains Quickbook markup as well as code +// and comments, don't change any of the special comment markups! + +//[integer_common_factor_example_0 + +// #include + +#include // For compile-time GCD & LCM Determination +#include // For run-time GCD & LCM Determination + +//] [/integer_common_factor_example_0] +#include +#include +#include + +#include // for numeric_limits min and max. + +int main() +{ +//[integer_common_factor_example_1 + std::cout << "The run-time GCD and LCM of 6 and 15 are " + << boost::integer::gcd(6, 15) << " and " + << boost::integer::lcm(6, 15) << ", respectively." + << std::endl; + // The GCD and LCM of 6 and 15 are 3 and 30, respectively. +//] [/integer_common_factor_example_1] + +//[integer_common_factor_example_2 + + std::cout << "The compile-time GCD and LCM of 8 and 9 are " + << boost::integer::static_gcd<8, 9>::value + << " and " + << boost::integer::static_lcm<8, 9>::value + << ", respectively." << std::endl; + // The GCD and LCM of 8 and 9 are 1 and 72, respectively. +//] [/integer_common_factor_example_2] + +//[integer_common_factor_example_3 + int a[] = { 4, 5, 6 }, b[] = { 7, 8, 9 }, c[3]; + std::transform(a, a + 3, b, c, boost::integer::gcd_evaluator()); + std::copy(c, c + 3, std::ostream_iterator(std::cout, " ")); +//] [/integer_common_factor_example_3] + +} // int main + +/* +//[integer_common_factor_example_output +The run-time GCD and LCM of 6 and 15 are 3 and 30, respectively. +The compile-time GCD and LCM of 8 and 9 are 1 and 72, respectively. +1 1 3 +//] [/integer_common_factor_example_output] +*/ diff --git a/example/integer_log2_example.cpp b/example/integer_log2_example.cpp new file mode 100644 index 0000000..b41e40a --- /dev/null +++ b/example/integer_log2_example.cpp @@ -0,0 +1,41 @@ +// boost integer_log2_example.cpp + +// Copyright Paul A. Bristow 2015 +// Use, modification and distribution are subject to 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) + +// Caution: this file contains Quickbook markup as well as code +// and comments, don't change any of the special comment markups! + +//[integer_log2_example_0 +#include // For boost::static_log2 +//] [/integer_log2s_example_0] +#include +#include // for numeric_limits min and max. + +//[integer_log2_example_ +//] [/integer_log2s_example_] + +int main() +{ +//[integer_log2_example_1 + int n = boost::static_log2<256>::value; +//] [/integer_log2_example_1] + + std::cout << n << std::endl; // 8 + + //[integer_log2_example_2 + int n2 = boost::static_log2<65536>::value; +//] [/integer_log2_example_2] + + std::cout << n2 << std::endl; // 16 + +} // int main + +/* +//[integer_log2_example_output +8 +//] [/integer_log2_example_output] +*/ diff --git a/example/integer_mask_example.cpp b/example/integer_mask_example.cpp new file mode 100644 index 0000000..a67ee49 --- /dev/null +++ b/example/integer_mask_example.cpp @@ -0,0 +1,69 @@ +// boost integer_mask_example.cpp + +// Copyright Paul A. Bristow 2015 +// Use, modification and distribution are subject to 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) + +// Caution: this file contains Quickbook markup as well as code +// and comments, don't change any of the special comment markups! + +//[integer_mask_example_0 +#include // For boost::high_bit_mask_t etc +//] [/integer_masks_example_0] +#include +#include // for numeric_limits min and max. + +//[integer_mask_example_ +//] [/integer_masks_example_] + +int main() +{ +//[integer_mask_example_1 + typedef boost::high_bit_mask_t<29> mask1_type; + typedef boost::low_bits_mask_t<15> mask2_type; +//] [/integer_masks_example_1] + +//[integer_mask_example_2 + // high_bit_mask_t + std::cout << std::hex << mask1_type::bit_position << std::endl; // 1d + std::cout << std::hex << mask1_type::high_bit << std::endl; // 20000000 + std::cout << std::hex << mask1_type::high_bit_fast << std::endl; // 20000000 + + // low_bits_mask_t + std::cout << std::hex << mask2_type::bit_count << std::endl; // F + std::cout << std::hex << mask2_type::sig_bits << std::endl; // 7fff + std::cout << std::hex << mask2_type::sig_bits_fast << std::endl; // 7fff +//] [/integer_masks_example_2] + +//[integer_mask_example_3 + mask1_type::least my_var1; + mask2_type::fast my_var2; +//] [/integer_masks_example_3] + +//[integer_mask_example_4 + my_var1 |= mask1_type::high_bit; + std::cout << std::hex << my_var1 << std::endl; // eccccccc +//] [/integer_masks_example_4] + +//[integer_mask_example_5 + my_var2 &= mask2_type::sig_bits; + std::cout << std::hex << my_var2 << std::endl; // 4ccc +//] [/integer_masks_example_5] + +} // int main + +/* +//[integer_mask_example_output +1d +20000000 +20000000 +f +7fff +7fff +eccccccc +4ccc +//] [/integer_mask_example_output] + +*/ diff --git a/example/integer_static_minmax_example.cpp b/example/integer_static_minmax_example.cpp new file mode 100644 index 0000000..3d4b529 --- /dev/null +++ b/example/integer_static_minmax_example.cpp @@ -0,0 +1,73 @@ +// boost integer_static_minmax_example.cpp + +// Copyright Paul A. Bristow 2015 +// Use, modification and distribution are subject to 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) + +// Caution: this file contains Quickbook markup as well as code +// and comments, don't change any of the special comment markups! + +#include // For boost::static_signed_min +#include +#include // for numeric_limits min and max. + +//[integer_min_max_example_0 + +template < unsigned long AddendSize1, unsigned long AddendSize2 > +class adder +{ +public: + static unsigned long const addend1_size = AddendSize1; + static unsigned long const addend2_size = AddendSize2; + static unsigned long const sum_size = boost::static_unsigned_max::value + 1; + + typedef int addend1_type[addend1_size]; + typedef int addend2_type[addend2_size]; + typedef int sum_type[sum_size]; + + void operator ()(addend1_type const &a1, addend2_type const &a2, sum_type &s) const; +}; // class adder + +//] [/integer_min_max_example_0] + +int main() +{ +//[integer_min_max_example_1 + + std::cout << "boost::static_signed_min< 9, 14>::value = "<< boost::static_signed_min< 9, 14>::value << std::endl; + std::cout << "boost::static_signed_max< 9, 14>::value = "<< boost::static_signed_max< 9, 14>::value << std::endl; + +//] [/integer_min_max_example_1] + +//[integer_min_max_example_2 + int const a1[] = { 0, 4, 3 }; // 340 + int const a2[] = { 9, 8 }; // 89 + int s[4]; + + adder<3, 2> obj; + // adder obj; + + std::cout << "obj.addend1_size = " << obj.addend1_size << std::endl; // 3 + std::cout << "obj.addend2_size = " << obj.addend2_size << std::endl; // 2 + std::cout << "obj.sum_size = " << obj.sum_size << std::endl; // 4 +//] [/integer_min_max_example_2] + + // obj(a1, a2, s); // 's' should be 429 or { 9, 2, 4, 0 } + //void adder<3,2>::operator()(int const (&)[3],int const (&)[2],int (&)[4])const + + std::cout << s[0] << s[1] << s[2] << s[3]<< std::endl; // 's' should be 429 or { 9, 2, 4, 0 } + +} // int main + +/* +//[integer_min_max_example_output + +boost::static_signed_min< 9, 14>::value = 9 +boost::static_signed_max< 9, 14>::value = 14 +obj.addend1_size = 3 +obj.addend2_size = 2 +obj.sum_size = 4 +//] [/integer_min_max_example_output] +*/ diff --git a/example/integer_traits_example.cpp b/example/integer_traits_example.cpp new file mode 100644 index 0000000..a406b89 --- /dev/null +++ b/example/integer_traits_example.cpp @@ -0,0 +1,55 @@ +// boost integer_traits_example.cpp + +// Copyright Paul A. Bristow 2015 +// Use, modification and distribution are subject to 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) + +// Caution: this file contains Quickbook markup as well as code +// and comments, don't change any of the special comment markups! + +#include +#include +#include // for numeric_limits min and max. + +//[integer_traits_example_1 +template +void f() +{ // Entirely contrived templated function. + std::cout << N << std::endl; // Do something pointless. +} +//] [/integer_traits_example_1] + + +int main() +{ + std::cout << "Type int, min = " + << (std::numeric_limits::min)() + << ", const_min = " << boost::integer_traits::const_min + << std::endl; // Type int, min = -2147483648, const_min = -2147483648 + +//[integer_traits_example_2 + f<2>(); +//] [/integer_traits_example_2] + +//[integer_traits_example_3 + int i = 2; + // f(); // A local variable cannot be used as a non-type argument. +//] [/integer_traits_example_3] + +//[integer_traits_example_4 + const int ci = 2; + f(); // But a const variable can. +//] [/integer_traits_example_4] +//[integer_traits_example_5 + + // f::min()>(); // Function call must have a constant value in a constant expression. +//] [/integer_traits_example_5] +//[integer_traits_example_6 + + f::const_min>(); +//] [/integer_traits_example_6] + +} // int main + diff --git a/example/integer_type_selection_example.cpp b/example/integer_type_selection_example.cpp new file mode 100644 index 0000000..e0800bf --- /dev/null +++ b/example/integer_type_selection_example.cpp @@ -0,0 +1,251 @@ +// boost integer_type_selection.cpp + +// Copyright Paul A. Bristow 2015 +// Use, modification and distribution are subject to 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) + +// Caution: this file contains Quickbook markup as well as code +// and comments, don't change any of the special comment markups! + +#include +#include +#include // for numeric_limits min and max. +// Note use of extra brackets to avoid potential clash for any min and max macros: +// (std::numeric_limits::max)() (std::numeric_limits::min)() + +//! Show info about type +template +void show_type() +{ + std::cout << typeid(T).name() + << " is a signed int using at least " << Bits << " bits uses " + << std::numeric_limits::least>::digits + << " bits, needing at most " + << std::numeric_limits::least>::digits10 + << " decimal digits, " " and representing a maximum decimal value of " + << static_cast((std::numeric_limits::least>::max)()) + << std::endl; +} // template void show_type() + +template +void show_consts() +{ // + std::cout << "Type " << typeid(T).name(); + if (std::numeric_limits::is_specialized) + { + std::cout << " is specialized for std::numeric_limits,"; + if (std::numeric_limits::is_integer) + { + std::cout << " and is integer type." << std::endl; + // If a constant expression for `min` and `max` are required, see + // Boost integer_traits. + std::cout << "const_max = " << boost::integer_traits::const_max << std::endl; + std::cout << "const_min = " << boost::integer_traits::const_min << std::endl; + } + } +} // void show_consts() + +template +void show_type() +{ + std::cout << "Type " << typeid(T).name(); // name of resultant type. + if (std::numeric_limits::is_specialized) + { + if (std::numeric_limits::is_integer) + { + std::cout << " is an unsigned int with at least 13 bits using " + << std::numeric_limits::digits + (std::numeric_limits::is_signed ? 1 : 0) << " bits,\n" + // See http://en.cppreference.com/w/cpp/types/numeric_limits/digits for details on the meaning of digits10. + // The value of std::numeric_limits::digits is the number of digits in base-radix that can be represented + // by the type T without change. + // For integer types, this is the number of bits *not counting the sign bit*, so add one for the total. + // (For floating-point types, this is the number of digits in the mantissa). + "guaranteeing at most " << std::numeric_limits::digits10 << " decimal digits precision,\n" + "and using at most " << std::numeric_limits::digits10 + 1 + << " decimal digits,\n" + // See http://en.cppreference.com/w/cpp/types/numeric_limits/digits10 for details on the meaning of digits10. + // The value of std::numeric_limits::digits is the number of digits in base-radix that can be represented + // by the type T without change. + // For integer types, the maximum number of digits that may be required is one more than digits10. + "a maximum decimal value of " << static_cast((std::numeric_limits::max)()) + << " and a minimum decimal value of " << static_cast((std::numeric_limits::min)()) << "." + << std::endl; + } + else + { + std::cout << "is floating-point." << std::endl; + } + } + else + { // is NOT specialized. + std::cout << " is NOT specialized for std::numeric_limits!" << std::endl; + } +} // template void show_type() + + +template +void show_type_limits() +{ // + + std::cout <<"Type " << typeid(T).name(); + if (std::numeric_limits::is_specialized) + { + std::cout << " is specialized for std::numeric_limits." << std::endl; + if (std::numeric_limits::is_integer) + { + std::cout << "is integer." << std::endl; + + std::cout << (std::numeric_limits::is_bounded ? "is bounded." : "") << std::endl; + std::cout << (std::numeric_limits::is_exact ? "is exact." : "") << std::endl; + std::cout << (std::numeric_limits::is_modulo ? "is modulo." : "") << std::endl; + std::cout << "radix = " << std::numeric_limits::radix << std::endl; + std::cout << (std::numeric_limits::is_signed ? "is signed." : "is unsigned.") << std::endl; + + std::cout << "max = " << static_cast((std::numeric_limits::max)()) << std::endl; + std::cout << "min = " << static_cast((std::numeric_limits::min)()) << std::endl; + // Can't list const_max or const_min here because compiler will protest that + // const_max' : is not a member of 'boost::integer_traits' when T is double. + //std::cout << "const_max = " << boost::integer_traits::const_max << std::endl; + //std::cout << "const_min = " << boost::integer_traits::const_min << std::endl; + + std::cout << "digits = " << std::numeric_limits::digits << std::endl; + std::cout << "bits = " << std::numeric_limits::digits +1 << std::endl; + // digits is the number of bits not counting the sign bit for integer types. + + std::cout << "digits10 = " << std::numeric_limits::digits10 << std::endl; + // max_digits10 is not defined for integer types. + //std::cout << "max_digits10 = " << std::numeric_limits::max_digits10 << std::endl; + } + else + { // Not integral, so might be floating-point, or ? + std::cout << "is NOT integral type." << std::endl; + if ((std::numeric_limits::max_exponent != 0) && (std::numeric_limits::max_exponent10 != 0)) + { // floating-point type including fundamental float, double and multiprecision like cpp_dec_float_50 and cpp_bin_float_50. + std::cout << "is floating-point type." << std::endl; + std::cout << "digits = " << std::numeric_limits::digits << std::endl; + // digits is the number of bits in the significand (not counting the sign bit) for floating-point types. + std::cout << "digits10 = " << std::numeric_limits::digits10 << std::endl; + // http://en.cppreference.com/w/cpp/types/numeric_limits/digits10 + std::cout << "max_digits10 = " << std::numeric_limits::max_digits10 << std::endl; + std::cout << "is_modulo = " << std::numeric_limits::is_modulo << std::endl; + std::cout << "is_iec559 = " << std::numeric_limits::is_iec559 << std::endl; + std::cout << (std::numeric_limits::is_exact ? "is exact." : "") << std::endl; + std::cout << (std::numeric_limits::is_signed ? "is signed." : "is unsigned.") << std::endl; + std::cout << "has_quiet_NaN = " << std::numeric_limits::has_quiet_NaN << std::endl; + std::cout << "has_infinity = " << std::numeric_limits::has_infinity << std::endl; + std::cout << "has_denorm_loss = " << std::numeric_limits::has_denorm_loss << std::endl; + std::cout << "max_exponent = " << std::numeric_limits::max_exponent << std::endl; + std::cout << "min_exponent = " << std::numeric_limits::min_exponent << std::endl; + std::cout << "max_exponent10 = " << std::numeric_limits::max_exponent10 << std::endl; + std::cout << "min_exponent10 = " << std::numeric_limits::min_exponent10 << std::endl; + } + else + { // Unknown type + std::cout << "Unknown type." << std::endl; + } + } + } + else + { // Not specialized! + std::cout << " is NOT specialized for std::numeric_limits!" << std::endl; + } +} // show_type_limits + + +int main() +{ + try + { + +// Select, construct and assign an unsigned integer of at least 13 bits. +//[integer_type_selection_1 + boost::uint_t<13>::least my_var13 = 42; +//] [/integer_type_selection_1] + +//[integer_type_selection_2 + show_type::least>(); +//] [/integer_type_selection_2] + + // Select fastest signed integer of at least 7 bits. +//[integer_type_selection_3 + typedef boost::int_t<7>::fast int_7; +//] [/integer_type_selection_3] + +//[integer_type_selection_4 + show_type(); +//] [/integer_type_selection_4] + + + // Choose an integer size that can hold at least a value of 1000 + // Assignment of this value is guaranteed not to be truncated: +//[integer_value_type_selection_5 + + boost::int_max_value_t<1000>::least thousand = 1000; +//] [/integer_value_type_selection_5] + + std::cout << thousand << std::endl; + +//[integer_value_type_selection_6 + + std::cout << (std::numeric_limits::least>::max)() << std::endl; + +//] [/integer_value_type_selection_6] + +//[integer_value_type_selection_7 + + thousand = 100000; // Probably too big! + + // warning C4305 : warning C4305: '=' : truncation from 'int' to 'short' + // warning C4309: '=' : truncation of constant value + +//] [/integer_value_type_selection_7] + +//[integer_value_type_selection_8 + + boost::int_t<32>::exact my_exact32 = 1000000; + + std::cout << "boost::int_t<32>::exact has " + << std::numeric_limits::exact>::digits + << " bits and 1 sign bit." << std::endl; +// boost::int_t<32>::exact has 31 bits and 1 sign bit. + +//] [/integer_value_type_selection_8] + +// If we ask for an unachievable number of bits or value + + //boost::int_t<128>::exact exact128; + //error C2338 : No suitable signed integer type with the requested number of bits is available. + // see reference to class template instantiation 'boost::int_t<128>' being compiled + + show_consts::exact>(); + // const_max = 2147483647 const_min = -2147483648 + + show_type<16, boost::int_max_value_t<1000>::least>(); + + } + catch (std::exception ex) + { + std::cout << ex.what() << std::endl; + } + return 0; +} // int main + + +/* + +//[integer_type_selection_output_1 +Type short is an unsigned int with at least 13 bits using 16 bits, +guaranteeing at most 4 decimal digits precision, +and using at most 5 decimal digits, +//] [/integer_type_selection_output_1] + +//[integer_type_selection_output_2 +Type signed char is an unsigned int with at least 13 bits using 8 bits, +guaranteeing at most 2 decimal digits precision, +and using at most 3 decimal digits, +a maximum decimal value of 127 and a minimum decimal value of -128. +//] [/integer_type_selection_output_2] + +*/ \ No newline at end of file diff --git a/example/jamfile.v2 b/example/jamfile.v2 new file mode 100644 index 0000000..4d02a49 --- /dev/null +++ b/example/jamfile.v2 @@ -0,0 +1,33 @@ +# libs/integer/example Jamfile +# Copyright (c) Vladimir Batov 2009-2014 +# Copyright Paul A. Bristow 2015 + +# Distributed under the Boost Software License, Version 1.0. +# See copy at http://www.boost.org/LICENSE_1_0.txt. + +# bring in the rules for testing +import testing ; + +project convert_examples + : requirements + on + gcc:all + msvc:all + gcc:"-Wno-unused-local-typedefs -Wno-unused-variable -Wno-long-long" + msvc:"/wd4996 /wd4512 /wd4610 /wd4510 /wd4127 /wd4701 /wd4127 /wd4305 /wd4100 /wd4512 /wd4714" + msvc:on + msvc:_CRT_SECURE_NO_DEPRECATE + msvc:_SCL_SECURE_NO_DEPRECATE + msvc:_SCL_SECURE_NO_WARNINGS + msvc:_CRT_SECURE_NO_WARNINGS + ../include + ; + +run integer_mask_example.cpp ; +run integer_traits_example.cpp ; +run integer_type_selection_example.cpp ; + + + + + diff --git a/include/boost/integer/common_factor_ct.hpp b/include/boost/integer/common_factor_ct.hpp index 572e063..e9debb3 100644 --- a/include/boost/integer/common_factor_ct.hpp +++ b/include/boost/integer/common_factor_ct.hpp @@ -12,8 +12,9 @@ #ifndef BOOST_INTEGER_COMMON_FACTOR_CT_HPP #define BOOST_INTEGER_COMMON_FACTOR_CT_HPP -#include // self include +//#include // self include #include // for BOOST_STATIC_CONSTANT, etc. +#include // for boost::uintmax_t namespace boost { @@ -21,6 +22,8 @@ namespace integer { // Warning: this is from 1.58 in namespace boost::integer and no longer in namespace boost::math. + typedef boost::uintmax_t static_gcd_type; + // Implementation details --------------------------------------------------// //! \cond DETAIL namespace detail