Compare commits

...

9 Commits

Author SHA1 Message Date
49195acf60 Enabled testing with GNU extensions in GitHub Actions. 2022-01-16 18:29:54 +03:00
bc9b0e6177 Implemented integer_log2 in terms of countl_zero from Boost.Core.
This allows to use compiler intrinsics and specialized hardware
instructions to compute log2, which results in better performance.

Also, added tests for the generic implementation using Boost.Multiprecision
integers.

Closes https://github.com/boostorg/integer/issues/31.
2022-01-16 15:20:37 +03:00
c6564a2d2b Merge pull request #26 from bernardosulzbach/documentation-typo-fix
Fixed a typo in ::least
2022-01-15 22:19:23 +03:00
16ef530fcf Use up to date includes for lightweight_test.hpp. 2021-12-21 20:45:00 +03:00
c5df07cb21 Simplified integer_log2 implementation.
Removed unnecessary template specializations, removed workaround for
compilers not supporting partial template specializations. Use unsigned
integers for bit counting, which allows to replace the division with
a shift.
2021-12-21 20:39:22 +03:00
a832e8fe65 Added a test for integer_log2. 2021-12-21 20:36:24 +03:00
0cd1879903 Fixed a link to library docs and silenced b2 warning about unescaped character. 2021-11-19 18:25:39 +03:00
4c1e36b023 Updated check for apt-add-repository capabilities.
In Ubuntu 20.04 there appeared an updated version of the
software-properties-common package in focal-updates, which ships a newer
apt-add-repository version that doesn't support -P/-S/-U command line arguments.

Since we cannot rely on package version checks to determine apt-add-repository
capabilities, we have to parse its --help output instead.

Also, made source list processing more protected against spaces.
2021-11-16 00:44:02 +03:00
ba7ea7f846 Fixed a typo in ::least 2021-01-31 14:03:24 +01:00
11 changed files with 329 additions and 107 deletions

View File

@ -98,7 +98,7 @@ jobs:
install:
- g++-10
- toolset: gcc-11
cxxstd: "03,11,14,17,20"
cxxstd: "03-gnu,11-gnu,14-gnu,17-gnu,20-gnu"
os: ubuntu-20.04
install:
- g++-11
@ -106,7 +106,7 @@ jobs:
- "ppa:ubuntu-toolchain-r/test"
- name: UBSAN
toolset: gcc-11
cxxstd: "03,11,14,17,20"
cxxstd: "03-gnu,11-gnu,14-gnu,17-gnu,20-gnu"
ubsan: 1
build_variant: debug
os: ubuntu-20.04
@ -203,13 +203,13 @@ jobs:
- clang-11
- toolset: clang
compiler: clang++-12
cxxstd: "03,11,14,17,20"
cxxstd: "03-gnu,11-gnu,14-gnu,17-gnu,20-gnu"
os: ubuntu-20.04
install:
- clang-12
- toolset: clang
compiler: clang++-12
cxxstd: "03,11,14,17,20"
cxxstd: "03-gnu,11-gnu,14-gnu,17-gnu,20-gnu"
os: ubuntu-20.04
install:
- clang-12
@ -217,10 +217,34 @@ jobs:
- libc++abi-12-dev
cxxflags: -stdlib=libc++
linkflags: -stdlib=libc++
- toolset: clang
compiler: clang++-13
cxxstd: "03-gnu,11-gnu,14-gnu,17-gnu,20-gnu"
os: ubuntu-20.04
install:
- clang-13
sources:
- "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-13 main"
source_keys:
- "https://apt.llvm.org/llvm-snapshot.gpg.key"
- toolset: clang
compiler: clang++-13
cxxstd: "03-gnu,11-gnu,14-gnu,17-gnu,20-gnu"
os: ubuntu-20.04
install:
- clang-13
- libc++-13-dev
- libc++abi-13-dev
sources:
- "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-13 main"
source_keys:
- "https://apt.llvm.org/llvm-snapshot.gpg.key"
cxxflags: -stdlib=libc++
linkflags: -stdlib=libc++
- name: UBSAN
toolset: clang
compiler: clang++-12
cxxstd: "03,11,14,17,20"
cxxstd: "03-gnu,11-gnu,14-gnu,17-gnu,20-gnu"
cxxflags: -stdlib=libc++
linkflags: -stdlib=libc++
ubsan: 1
@ -253,7 +277,7 @@ jobs:
if [ -f "/etc/debian_version" ]
then
apt-get -o Acquire::Retries=$NET_RETRY_COUNT update
apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y sudo software-properties-common tzdata wget curl apt-transport-https ca-certificates make build-essential g++ python python3 git cmake
apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y sudo software-properties-common tzdata wget curl apt-transport-https ca-certificates make build-essential g++ python python3 perl git cmake
fi
fi
git config --global pack.threads 0
@ -263,28 +287,32 @@ jobs:
- name: Install packages
if: matrix.install
run: |
SOURCE_KEYS=(${{join(matrix.source_keys, ' ')}})
SOURCES=(${{join(matrix.sources, ' ')}})
declare -a SOURCE_KEYS SOURCES
if [ -n "${{join(matrix.source_keys, ' ')}}" ]
then
SOURCE_KEYS=("${{join(matrix.source_keys, '" "')}}")
fi
if [ -n "${{join(matrix.sources, ' ')}}" ]
then
SOURCES=("${{join(matrix.sources, '" "')}}")
fi
for key in "${SOURCE_KEYS[@]}"
do
for i in {1..$NET_RETRY_COUNT}
do
echo "Adding key: $key"
wget -O - "$key" | sudo apt-key add - && break || sleep 2
done
done
if [ ${#SOURCES[@]} -gt 0 ]
then
APT_ADD_REPO_COMMON_ARGS=("-y")
APT_ADD_REPO_HAS_SOURCE_ARGS=0
SOFTWARE_PROPERTIES_VERSION="$(dpkg-query --showformat='${Version}' --show software-properties-common)"
if dpkg --compare-versions "$SOFTWARE_PROPERTIES_VERSION" ge "0.96.24.20"
APT_ADD_REPO_SUPPORTED_ARGS="$(apt-add-repository --help | perl -ne 'if (/^\s*-n/) { print "n"; } elsif (/^\s*-P/) { print "P"; } elsif (/^\s*-S/) { print "S"; } elsif (/^\s*-U/) { print "U"; }')"
if [ -n "$APT_ADD_REPO_SUPPORTED_ARGS" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*n*}" ]
then
APT_ADD_REPO_COMMON_ARGS+=("-n")
fi
if dpkg --compare-versions "$SOFTWARE_PROPERTIES_VERSION" ge "0.98.10"
then
APT_ADD_REPO_HAS_SOURCE_ARGS=1
fi
APT_ADD_REPO_HAS_SOURCE_ARGS="$([ -n "$APT_ADD_REPO_SUPPORTED_ARGS" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*P*}" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*S*}" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*U*}" ] && echo 1 || echo 0)"
for source in "${SOURCES[@]}"
do
for i in {1..$NET_RETRY_COUNT}
@ -305,6 +333,7 @@ jobs:
esac
fi
APT_ADD_REPO_ARGS+=("$source")
echo "apt-add-repository ${APT_ADD_REPO_ARGS[@]}"
sudo -E apt-add-repository "${APT_ADD_REPO_ARGS[@]}" && break || sleep 2
done
done
@ -335,7 +364,7 @@ jobs:
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
BOOST_BRANCH=develop && [ "$REF" = "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
BUILD_JOBS=$((nproc || sysctl -n hw.ncpu) 2> /dev/null)
echo "BUILD_JOBS=$BUILD_JOBS" >> $GITHUB_ENV

View File

@ -25,8 +25,8 @@ boostbook standalone
# How far down we go with TOC's
<xsl:param>generate.section.toc.level=4
# Path for links to Boost:
<xsl:param>boost.root=../../../..
<xsl:param>"boost.root=../../../.."
# PDF Options:
# TOC Generation: this is needed for FOP-0.9 and later:
<xsl:param>fop1.extensions=0
@ -46,8 +46,8 @@ boostbook standalone
# default pnd graphics are awful in PDF form,
# better use SVG's instead:
<format>pdf:<xsl:param>admon.graphics.extension=".svg"
<format>pdf:<xsl:param>admon.graphics.path=$(boost-images)/
<format>pdf:<xsl:param>boost.url.prefix=https://www.boost.org/doc/libs/release/libs/regex/doc/html
<format>pdf:<xsl:param>"admon.graphics.path=$(boost-images)/"
<format>pdf:<xsl:param>"boost.url.prefix=https://www.boost.org/doc/libs/release/libs/integer/doc/html"
;
install pdfinstall : standalone/<format>pdf : <location>. <install-type>PDF ;

View File

@ -285,7 +285,7 @@ The following table describes each template's criteria.
[*only] if there exists a type with exactly N bits.]
]
[
[[^boost::int_max_value_t<V>::last]]
[[^boost::int_max_value_t<V>::least]]
[The smallest, built-in, signed integral type that can hold all the values in the inclusive range ['0 - V].
The parameter should be a positive number.]
]

View File

@ -4,7 +4,8 @@
// Gives the integer part of the logarithm, in base 2, of a
// given number. Behavior is undefined if the argument is <= 0.
//
// Copyright (c) 2003-2004, 2008 Gennaro Prota
// Copyright (c) 2003-2004, 2008 Gennaro Prota
// Copyright (c) 2022 Andrey Semashev
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@ -15,98 +16,102 @@
#ifndef BOOST_INTEGER_INTEGER_LOG2_HPP
#define BOOST_INTEGER_INTEGER_LOG2_HPP
#include <boost/limits.hpp>
#include <climits>
#include <limits>
#include <boost/config.hpp>
#include <boost/assert.hpp>
#if defined(BOOST_BORLANDC)
#include <climits>
#endif
#include <boost/cstdint.hpp>
#include <boost/core/bit.hpp>
#include <boost/core/enable_if.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/make_unsigned.hpp>
namespace boost {
namespace detail {
namespace detail {
template <typename T>
int integer_log2_impl(T x, int n) {
// helper to find the maximum power of two
// less than p
template< unsigned int p, unsigned int n, bool = ((2u * n) < p) >
struct max_pow2_less :
public max_pow2_less< p, 2u * n >
{
};
int result = 0;
template< unsigned int p, unsigned int n >
struct max_pow2_less< p, n, false >
{
BOOST_STATIC_CONSTANT(unsigned int, value = n);
};
while (x != 1) {
template< typename T >
inline typename boost::disable_if< boost::is_integral< T >, int >::type integer_log2_impl(T x)
{
unsigned int n = detail::max_pow2_less<
std::numeric_limits< T >::digits,
CHAR_BIT / 2u
>::value;
const T t = static_cast<T>(x >> n);
if (t) {
result += n;
x = t;
}
n /= 2;
}
return result;
}
// helper to find the maximum power of two
// less than p (more involved than necessary,
// to avoid PTS)
//
template <int p, int n>
struct max_pow2_less {
enum { c = 2*n < p };
BOOST_STATIC_CONSTANT(int, value =
c ? (max_pow2_less< c*p, 2*c*n>::value) : n);
};
template <>
struct max_pow2_less<0, 0> {
BOOST_STATIC_CONSTANT(int, value = 0);
};
// this template is here just for Borland :(
// we could simply rely on numeric_limits but sometimes
// Borland tries to use numeric_limits<const T>, because
// of its usual const-related problems in argument deduction
// - gps
template <typename T>
struct width {
#ifdef BOOST_BORLANDC
BOOST_STATIC_CONSTANT(int, value = sizeof(T) * CHAR_BIT);
int result = 0;
while (x != 1)
{
T t(x >> n);
if (t)
{
result += static_cast< int >(n);
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
x = static_cast< T&& >(t);
#else
BOOST_STATIC_CONSTANT(int, value = (std::numeric_limits<T>::digits));
x = t;
#endif
}
n >>= 1u;
}
};
} // detail
// ---------
// integer_log2
// ---------------
//
template <typename T>
int integer_log2(T x) {
BOOST_ASSERT(x > 0);
const int n = detail::max_pow2_less<
detail::width<T> :: value, 4
> :: value;
return detail::integer_log2_impl(x, n);
}
return result;
}
template< typename T >
inline typename boost::enable_if< boost::is_integral< T >, int >::type integer_log2_impl(T x)
{
// We could simply rely on numeric_limits but sometimes
// Borland tries to use numeric_limits<const T>, because
// of its usual const-related problems in argument deduction
// - gps
return static_cast< int >((sizeof(T) * CHAR_BIT - 1u) -
boost::core::countl_zero(static_cast< typename boost::make_unsigned< T >::type >(x)));
}
#if defined(BOOST_HAS_INT128)
// We need to provide explicit overloads for __int128 because (a) boost/core/bit.hpp currently does not support it and
// (b) std::numeric_limits are not specialized for __int128 in some standard libraries.
inline int integer_log2_impl(boost::uint128_type x)
{
const boost::uint64_t x_hi = static_cast< boost::uint64_t >(x >> 64u);
if (x_hi != 0u)
return 127 - boost::core::countl_zero(x_hi);
else
return 63 - boost::core::countl_zero(static_cast< boost::uint64_t >(x));
}
inline int integer_log2_impl(boost::int128_type x)
{
return detail::integer_log2_impl(static_cast< boost::uint128_type >(x));
}
#endif // defined(BOOST_HAS_INT128)
} // namespace detail
#endif // include guard
// ------------
// integer_log2
// ------------
template< typename T >
inline int integer_log2(T x)
{
BOOST_ASSERT(x > 0);
return detail::integer_log2_impl(x);
}
} // namespace boost
#endif // BOOST_INTEGER_INTEGER_LOG2_HPP

View File

@ -15,6 +15,7 @@ test-suite integer
[ run integer_traits_test.cpp ]
[ run integer_test.cpp : : : <toolset>gcc:<cxxflags>-Wno-long-long <toolset>darwin:<cxxflags>-Wno-long-long <toolset>sun:<cxxflags>"-Qoption ccfe -tmpldepth=128" ]
[ run integer_mask_test.cpp ]
[ run integer_log2_test.cpp ]
[ run static_log2_test.cpp ]
[ run static_min_max_test.cpp ]
[ run extended_euclidean_test.cpp ]

187
test/integer_log2_test.cpp Normal file
View File

@ -0,0 +1,187 @@
// Boost integer_log2.hpp test program --------------------------------------//
// (C) Copyright Andrey Semashev 2021.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// See https://www.boost.org for most recent version including documentation.
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/integer/integer_log2.hpp>
#include <boost/core/lightweight_test.hpp>
#include <iostream>
#include "multiprecision_config.hpp"
#if !defined(DISABLE_MP_TESTS)
#include <boost/multiprecision/cpp_int.hpp>
#endif
// Macros to compact code
#define PRIVATE_LB_TEST( v, e ) BOOST_TEST( ::boost::integer_log2((v)) == e )
#define PRIVATE_PRINT_LB( v ) ::std::cout << "boost::integer_log2(" << (v) \
<< ") = " << ::boost::integer_log2((v)) << '.' << ::std::endl
// Control to check for a compile-time error
#ifndef CONTROL_LB_0_TEST
#define PRIVATE_LB_0_TEST
#else
#define PRIVATE_LB_0_TEST PRIVATE_PRINT_LB( 0 )
#endif
// Main testing function
int main()
{
std::cout << "Doing tests on integer_log2." << std::endl;
PRIVATE_LB_0_TEST;
PRIVATE_LB_TEST( (unsigned char)1, 0 );
PRIVATE_LB_TEST( (unsigned char)2, 1 );
PRIVATE_LB_TEST( 1, 0 );
PRIVATE_LB_TEST( 2, 1 );
PRIVATE_LB_TEST( 3, 1 );
PRIVATE_LB_TEST( 4, 2 );
PRIVATE_LB_TEST( 5, 2 );
PRIVATE_LB_TEST( 6, 2 );
PRIVATE_LB_TEST( 7, 2 );
PRIVATE_LB_TEST( 8, 3 );
PRIVATE_LB_TEST( 9, 3 );
PRIVATE_LB_TEST( 10, 3 );
PRIVATE_LB_TEST( 11, 3 );
PRIVATE_LB_TEST( 12, 3 );
PRIVATE_LB_TEST( 13, 3 );
PRIVATE_LB_TEST( 14, 3 );
PRIVATE_LB_TEST( 15, 3 );
PRIVATE_LB_TEST( 16, 4 );
PRIVATE_LB_TEST( 17, 4 );
PRIVATE_LB_TEST( 18, 4 );
PRIVATE_LB_TEST( 19, 4 );
PRIVATE_LB_TEST( 20, 4 );
PRIVATE_LB_TEST( 21, 4 );
PRIVATE_LB_TEST( 22, 4 );
PRIVATE_LB_TEST( 23, 4 );
PRIVATE_LB_TEST( 24, 4 );
PRIVATE_LB_TEST( 25, 4 );
PRIVATE_LB_TEST( 26, 4 );
PRIVATE_LB_TEST( 27, 4 );
PRIVATE_LB_TEST( 28, 4 );
PRIVATE_LB_TEST( 29, 4 );
PRIVATE_LB_TEST( 30, 4 );
PRIVATE_LB_TEST( 31, 4 );
PRIVATE_LB_TEST( 32, 5 );
PRIVATE_LB_TEST( 33, 5 );
PRIVATE_LB_TEST( 34, 5 );
PRIVATE_LB_TEST( 35, 5 );
PRIVATE_LB_TEST( 36, 5 );
PRIVATE_LB_TEST( 37, 5 );
PRIVATE_LB_TEST( 38, 5 );
PRIVATE_LB_TEST( 39, 5 );
PRIVATE_LB_TEST( 40, 5 );
PRIVATE_LB_TEST( 63, 5 );
PRIVATE_LB_TEST( 64, 6 );
PRIVATE_LB_TEST( 65, 6 );
PRIVATE_LB_TEST( 127, 6 );
PRIVATE_LB_TEST( 128, 7 );
PRIVATE_LB_TEST( 129, 7 );
PRIVATE_LB_TEST( 255, 7 );
PRIVATE_LB_TEST( 256, 8 );
PRIVATE_LB_TEST( 257, 8 );
PRIVATE_LB_TEST( 511, 8 );
PRIVATE_LB_TEST( 512, 9 );
PRIVATE_LB_TEST( 513, 9 );
PRIVATE_LB_TEST( 1023, 9 );
PRIVATE_LB_TEST( 1024, 10 );
PRIVATE_LB_TEST( 1025, 10 );
PRIVATE_LB_TEST( 2047, 10 );
PRIVATE_LB_TEST( 2048, 11 );
PRIVATE_LB_TEST( 2049, 11 );
PRIVATE_LB_TEST( 4095, 11 );
PRIVATE_LB_TEST( 4096, 12 );
PRIVATE_LB_TEST( 4097, 12 );
PRIVATE_LB_TEST( 8191, 12 );
PRIVATE_LB_TEST( 8192, 13 );
PRIVATE_LB_TEST( 8193, 13 );
PRIVATE_LB_TEST( 16383, 13 );
PRIVATE_LB_TEST( 16384, 14 );
PRIVATE_LB_TEST( 16385, 14 );
PRIVATE_LB_TEST( 32767, 14 );
PRIVATE_LB_TEST( 32768, 15 );
PRIVATE_LB_TEST( 32769, 15 );
PRIVATE_LB_TEST( 65535, 15 );
PRIVATE_LB_TEST( 65536, 16 );
PRIVATE_LB_TEST( 65537, 16 );
#if defined(UINT32_C)
PRIVATE_LB_TEST( UINT32_C(4294967295), 31 );
#endif
#if defined(UINT64_C) && !defined(BOOST_NO_INT64_T)
PRIVATE_LB_TEST( UINT64_C(4294967296), 32 );
PRIVATE_LB_TEST( UINT64_C(4294967297), 32 );
PRIVATE_LB_TEST( UINT64_C(18446744073709551615), 63 );
#endif
#if defined(BOOST_HAS_INT128)
PRIVATE_LB_TEST( boost::uint128_type(1u) << 64u, 64 );
PRIVATE_LB_TEST( (boost::uint128_type(1u) << 64u) + 1u, 64 );
PRIVATE_LB_TEST( ~boost::uint128_type(0u), 127 );
#endif
#if !defined(DISABLE_MP_TESTS)
PRIVATE_LB_TEST( boost::multiprecision::cpp_int(1), 0 );
PRIVATE_LB_TEST( boost::multiprecision::cpp_int(2), 1 );
PRIVATE_LB_TEST( boost::multiprecision::cpp_int(3), 1 );
PRIVATE_LB_TEST( boost::multiprecision::cpp_int(65535), 15 );
PRIVATE_LB_TEST( boost::multiprecision::cpp_int(65536), 16 );
PRIVATE_LB_TEST( boost::multiprecision::int1024_t(1), 0 );
PRIVATE_LB_TEST( boost::multiprecision::int1024_t(2), 1 );
PRIVATE_LB_TEST( boost::multiprecision::int1024_t(3), 1 );
PRIVATE_LB_TEST( boost::multiprecision::int1024_t(65535), 15 );
PRIVATE_LB_TEST( boost::multiprecision::int1024_t(65536), 16 );
PRIVATE_LB_TEST( boost::multiprecision::uint1024_t(1), 0 );
PRIVATE_LB_TEST( boost::multiprecision::uint1024_t(2), 1 );
PRIVATE_LB_TEST( boost::multiprecision::uint1024_t(3), 1 );
PRIVATE_LB_TEST( boost::multiprecision::uint1024_t(65535), 15 );
PRIVATE_LB_TEST( boost::multiprecision::uint1024_t(65536), 16 );
#endif
return boost::report_errors();
}

View File

@ -10,7 +10,7 @@
// Revision History
// 23 Sep 2001 Initial version (Daryle Walker)
#include <boost/detail/lightweight_test.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/cstdlib.hpp> // for boost::exit_success
#include <boost/integer/integer_mask.hpp> // for boost::high_bit_mask_t, etc.

View File

@ -15,7 +15,7 @@
// 10 Mar 01 Boost Test Library now used for tests (Beman Dawes)
// 31 Aug 99 Initial version
#include <boost/detail/lightweight_test.hpp> // for main, BOOST_TEST
#include <boost/core/lightweight_test.hpp> // for main, BOOST_TEST
#include <boost/integer.hpp> // for boost::int_t, boost::uint_t
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/bool.hpp> // for mpl::true_ and false_

View File

@ -17,7 +17,7 @@
// use int64_t instead of long long for better portability
#include <boost/cstdint.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/core/lightweight_test.hpp>
/*
* General portability note:

View File

@ -10,7 +10,7 @@
// Revision History
// 01 Oct 2001 Initial version (Daryle Walker)
#include <boost/detail/lightweight_test.hpp> // for main
#include <boost/core/lightweight_test.hpp> // for main
#include <boost/cstdlib.hpp> // for boost::exit_success
#include <boost/integer/static_log2.hpp> // for boost::static_log2

View File

@ -10,7 +10,7 @@
// Revision History
// 23 Sep 2001 Initial version (Daryle Walker)
#include <boost/detail/lightweight_test.hpp> // for main, BOOST_TEST
#include <boost/core/lightweight_test.hpp> // for main, BOOST_TEST
#include <boost/cstdlib.hpp> // for boost::exit_success
#include <boost/integer/static_min_max.hpp> // for boost::static_signed_min, etc.