89 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// unsigned long long to_ullong() const; // constexpr since C++2310 11#include <bitset>12#include <algorithm>13#include <type_traits>14#include <limits>15#include <climits>16#include <cassert>17#include <stdexcept>18 19#include "test_macros.h"20 21template <std::size_t N>22TEST_CONSTEXPR_CXX23 void test_to_ullong() {23 const std::size_t M = sizeof(unsigned long long) * CHAR_BIT < N ? sizeof(unsigned long long) * CHAR_BIT : N;24 const bool is_M_zero = std::integral_constant < bool, M == 0 > ::value; // avoid compiler warnings25 const std::size_t X =26 is_M_zero ? sizeof(unsigned long long) * CHAR_BIT - 1 : sizeof(unsigned long long) * CHAR_BIT - M;27 const unsigned long long max = is_M_zero ? 0 : (unsigned long long)(-1) >> X;28 unsigned long long tests[] = {29 0,30 std::min<unsigned long long>(1, max),31 std::min<unsigned long long>(2, max),32 std::min<unsigned long long>(3, max),33 std::min(max, max - 3),34 std::min(max, max - 2),35 std::min(max, max - 1),36 max};37 for (unsigned long long j : tests) {38 std::bitset<N> v(j);39 assert(j == v.to_ullong());40 }41 { // test values bigger than can fit into the bitset42 const unsigned long long val = 0x55AAAAFFFFAAAA55ULL;43 const bool canFit = N < sizeof(unsigned long long) * CHAR_BIT;44 const unsigned long long mask =45 canFit ? (1ULL << (canFit ? N : 0)) - 1 : (unsigned long long)(-1); // avoid compiler warnings46 std::bitset<N> v(val);47 assert(v.to_ullong() == (val & mask)); // we shouldn't return bit patterns from outside the limits of the bitset.48 }49}50 51TEST_CONSTEXPR_CXX23 bool test() {52 test_to_ullong<0>();53 test_to_ullong<1>();54 test_to_ullong<31>();55 test_to_ullong<32>();56 test_to_ullong<33>();57 test_to_ullong<63>();58 test_to_ullong<64>();59 test_to_ullong<65>();60 test_to_ullong<1000>();61 62#ifndef TEST_HAS_NO_EXCEPTIONS63 if (!TEST_IS_CONSTANT_EVALUATED) {64 // bitset has true bits beyond the size of unsigned long long65 std::bitset<std::numeric_limits<unsigned long long>::digits + 1> q(0);66 q.flip();67 try {68 (void)q.to_ullong(); // throws69 assert(false);70 } catch (const std::overflow_error&) {71 // expected72 } catch (...) {73 assert(false);74 }75 }76#endif // TEST_HAS_NO_EXCEPTIONS77 78 return true;79}80 81int main(int, char**) {82 test();83#if TEST_STD_VER > 2084 static_assert(test());85#endif86 87 return 0;88}89