mclow.lists created this revision.
mclow.lists added reviewers: EricWF, ldionne.
Herald added a subscriber: christof.
In C++20, we're going to have a header named for bit manipulations.
See https://wg21.link/P0553 and https://wg21.link/P0556 for more info.
This doesn't do any of that.
It just creates the header, and pulls some existing internal routines into it.
Later diffs will rename the existing routines, and implement the features from
P0553 and P0556.
This is just moving stuff around. NFC intended.
https://reviews.llvm.org/D50815
Files:
include/algorithm
include/bit
include/module.modulemap
test/libcxx/double_include.sh.cpp
Index: test/libcxx/double_include.sh.cpp
===
--- test/libcxx/double_include.sh.cpp
+++ test/libcxx/double_include.sh.cpp
@@ -27,6 +27,7 @@
#ifndef _LIBCPP_HAS_NO_THREADS
#include
#endif
+#include
#include
#include
#include
Index: include/module.modulemap
===
--- include/module.modulemap
+++ include/module.modulemap
@@ -228,6 +228,10 @@
header "atomic"
export *
}
+ module bit {
+header "bit"
+export *
+ }
module bitset {
header "bitset"
export string
Index: include/bit
===
--- include/bit
+++ include/bit
@@ -0,0 +1,169 @@
+// -*- C++ -*-
+//===-- bit --===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===-===//
+
+#ifndef _LIBCPP_BIT
+#define _LIBCPP_BIT
+
+/*
+bit synopsis
+
+namespace std {
+
+} // namespace std
+
+*/
+
+#include <__config>
+
+#if defined(__IBMCPP__)
+#include "support/ibm/support.h"
+#endif
+#if defined(_LIBCPP_COMPILER_MSVC)
+#include
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// Precondition: __x != 0
+inline _LIBCPP_INLINE_VISIBILITY
+unsigned __ctz(unsigned __x) {
+#ifndef _LIBCPP_COMPILER_MSVC
+return static_cast(__builtin_ctz(__x));
+#else
+ static_assert(sizeof(unsigned) == sizeof(unsigned long), "");
+ static_assert(sizeof(unsigned long) == 4, "");
+ unsigned long where;
+ // Search from LSB to MSB for first set bit.
+ // Returns zero if no set bit is found.
+ if (_BitScanForward(, __x))
+return where;
+ return 32;
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+unsigned long __ctz(unsigned long __x) {
+#ifndef _LIBCPP_COMPILER_MSVC
+return static_cast(__builtin_ctzl(__x));
+#else
+static_assert(sizeof(unsigned long) == sizeof(unsigned), "");
+return __ctz(static_cast(__x));
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+unsigned long long __ctz(unsigned long long __x) {
+#ifndef _LIBCPP_COMPILER_MSVC
+return static_cast(__builtin_ctzll(__x));
+#else
+unsigned long where;
+// Search from LSB to MSB for first set bit.
+// Returns zero if no set bit is found.
+#if defined(_LIBCPP_HAS_BITSCAN64)
+(defined(_M_AMD64) || defined(__x86_64__))
+ if (_BitScanForward64(, __x))
+return static_cast(where);
+#else
+ // Win32 doesn't have _BitScanForward64 so emulate it with two 32 bit calls.
+ // Scan the Low Word.
+ if (_BitScanForward(, static_cast(__x)))
+return where;
+ // Scan the High Word.
+ if (_BitScanForward(, static_cast(__x >> 32)))
+return where + 32; // Create a bit offset from the LSB.
+#endif
+ return 64;
+#endif // _LIBCPP_COMPILER_MSVC
+}
+
+// Precondition: __x != 0
+inline _LIBCPP_INLINE_VISIBILITY
+unsigned __clz(unsigned __x) {
+#ifndef _LIBCPP_COMPILER_MSVC
+return static_cast(__builtin_clz(__x));
+#else
+ static_assert(sizeof(unsigned) == sizeof(unsigned long), "");
+ static_assert(sizeof(unsigned long) == 4, "");
+ unsigned long where;
+ // Search from LSB to MSB for first set bit.
+ // Returns zero if no set bit is found.
+ if (_BitScanReverse(, __x))
+return 31 - where;
+ return 32; // Undefined Behavior.
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+unsigned long __clz(unsigned long __x) {
+#ifndef _LIBCPP_COMPILER_MSVC
+return static_cast(__builtin_clzl (__x));
+#else
+static_assert(sizeof(unsigned) == sizeof(unsigned long), "");
+return __clz(static_cast(__x));
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+unsigned long long __clz(unsigned long long __x) {
+#ifndef _LIBCPP_COMPILER_MSVC
+return static_cast(__builtin_clzll(__x));
+#else
+ unsigned long where;
+// BitScanReverse scans from MSB to LSB for first set bit.
+// Returns 0 if no set bit is found.
+#if defined(_LIBCPP_HAS_BITSCAN64)
+ if (_BitScanReverse64(, __x))
+return static_cast(63 - where);
+#else
+ // Scan the high 32 bits.
+ if (_BitScanReverse(,