Edit: /usr/include/boost/hana/bool.hpp (9747B)
/*!
@file
Defines the `Logical` and `Comparable` models of `boost::hana::integral_constant`.
@copyright Louis Dionne 2013-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_HANA_BOOL_HPP
#define BOOST_HANA_BOOL_HPP
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
BOOST_HANA_NAMESPACE_BEGIN
//////////////////////////////////////////////////////////////////////////
// integral_constant
//////////////////////////////////////////////////////////////////////////
//! @cond
namespace ic_detail {
template >
struct go;
template
struct go> {
using swallow = T[];
template
static constexpr void with_index(F&& f)
{ (void)swallow{T{}, ((void)f(integral_constant{}), i)...}; }
template
static constexpr void without_index(F&& f)
{ (void)swallow{T{}, ((void)f(), i)...}; }
};
template
template
constexpr void with_index_t::operator()(F&& f) const
{ go::with_index(static_cast(f)); }
template
template
constexpr void times_t::operator()(F&& f) const
{ go::without_index(static_cast(f)); }
// avoid link-time error
template
constexpr with_index_t times_t::with_index;
}
// avoid link-time error
template
constexpr ic_detail::times_t integral_constant::times;
template
struct tag_of> {
using type = integral_constant_tag;
};
//! @endcond
//////////////////////////////////////////////////////////////////////////
// Operators
//////////////////////////////////////////////////////////////////////////
namespace detail {
template
struct comparable_operators> {
static constexpr bool value = true;
};
template
struct orderable_operators> {
static constexpr bool value = true;
};
template
struct arithmetic_operators> {
static constexpr bool value = true;
};
template
struct logical_operators> {
static constexpr bool value = true;
};
}
#define BOOST_HANA_INTEGRAL_CONSTANT_BINARY_OP(op) \
template \
constexpr integral_constant \
operator op(integral_constant, integral_constant) \
{ return {}; } \
/**/
#define BOOST_HANA_INTEGRAL_CONSTANT_UNARY_OP(op) \
template \
constexpr integral_constant \
operator op(integral_constant) \
{ return {}; } \
/**/
// Arithmetic
BOOST_HANA_INTEGRAL_CONSTANT_UNARY_OP(+)
// Bitwise
BOOST_HANA_INTEGRAL_CONSTANT_UNARY_OP(~)
BOOST_HANA_INTEGRAL_CONSTANT_BINARY_OP(&)
BOOST_HANA_INTEGRAL_CONSTANT_BINARY_OP(|)
BOOST_HANA_INTEGRAL_CONSTANT_BINARY_OP(^)
BOOST_HANA_INTEGRAL_CONSTANT_BINARY_OP(<<)
BOOST_HANA_INTEGRAL_CONSTANT_BINARY_OP(>>)
#undef BOOST_HANA_INTEGRAL_CONSTANT_UNARY_OP
#undef BOOST_HANA_INTEGRAL_CONSTANT_BINARY_OP
//////////////////////////////////////////////////////////////////////////
// User-defined literal
//////////////////////////////////////////////////////////////////////////
namespace ic_detail {
constexpr int to_int(char c) {
int result = 0;
if (c >= 'A' && c <= 'F') {
result = static_cast(c) - static_cast('A') + 10;
}
else if (c >= 'a' && c <= 'f') {
result = static_cast(c) - static_cast('a') + 10;
}
else {
result = static_cast(c) - static_cast('0');
}
return result;
}
template
constexpr long long parse(const char (&arr)[N]) {
long long base = 10;
std::size_t offset = 0;
if (N > 2) {
bool starts_with_zero = arr[0] == '0';
bool is_hex = starts_with_zero && arr[1] == 'x';
bool is_binary = starts_with_zero && arr[1] == 'b';
if (is_hex) {
//0xDEADBEEF (hexadecimal)
base = 16;
offset = 2;
}
else if (is_binary) {
//0b101011101 (binary)
base = 2;
offset = 2;
}
else if (starts_with_zero) {
//012345 (octal)
base = 8;
offset = 1;
}
}
long long number = 0;
long long multiplier = 1;
for (std::size_t i = 0; i < N - offset; ++i) {
char c = arr[N - 1 - i];
if (c != '\'') { // skip digit separators
number += to_int(c) * multiplier;
multiplier *= base;
}
}
return number;
}
}
namespace literals {
template
constexpr auto operator"" _c() {
return hana::llong({c...})>{};
}
}
//////////////////////////////////////////////////////////////////////////
// Model of Constant/IntegralConstant
//////////////////////////////////////////////////////////////////////////
template
struct IntegralConstant> {
static constexpr bool value = true;
};
template
struct to_impl, C, when::value>>
: embedding::value>
{
template
static constexpr auto apply(N const&)
{ return integral_constant{}; }
};
//////////////////////////////////////////////////////////////////////////
// Optimizations
//////////////////////////////////////////////////////////////////////////
template
struct eval_if_impl> {
template
static constexpr decltype(auto)
apply(Cond const&, Then&& t, Else&& e) {
constexpr bool cond = static_cast(Cond::value);
return eval_if_impl::apply(hana::bool_{},
static_cast(t),
static_cast(e));
}
template
static constexpr decltype(auto)
apply(hana::true_ const&, Then&& t, Else&&)
{ return hana::eval(static_cast(t)); }
template
static constexpr decltype(auto)
apply(hana::false_ const&, Then&&, Else&& e)
{ return hana::eval(static_cast(e)); }
};
template
struct if_impl> {
template
static constexpr decltype(auto)
apply(Cond const&, Then&& t, Else&& e) {
constexpr bool cond = static_cast(Cond::value);
return if_impl::apply(hana::bool_{},
static_cast(t),
static_cast(e));
}
//! @todo We could return `Then` instead of `auto` to sometimes save
//! a copy, but that would break some code that would return a
//! reference to a `type` object. I think the code that would be
//! broken should be changed, but more thought needs to be given.
template
static constexpr auto
apply(hana::true_ const&, Then&& t, Else&&)
{ return static_cast(t); }
template
static constexpr auto
apply(hana::false_ const&, Then&&, Else&& e)
{ return static_cast(e); }
};
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_BOOL_HPP