Movatterモバイル変換


[0]ホーム

URL:


Google Git
Sign in
chromium /chromium /src /refs/heads/main /. /base /bits.h
blob: 5f93183d034b7d3b448e5616bfa4fb08a23dddcd [file] [log] [blame] [edit]
// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This file defines some bit utilities.
#ifndef BASE_BITS_H_
#define BASE_BITS_H_
#include<stddef.h>
#include<stdint.h>
#include<bit>
#include<concepts>
#include<type_traits>
#include"base/check.h"
namespacebase::bits{
// Bit functions in <bit> are restricted to a specific set of types of unsigned
// integer; restrict functions in this file that are related to those in that
// header to match for consistency.
template<typename T>
conceptUnsignedInteger=
std::unsigned_integral<T>&&!std::same_as<T,bool>&&
!std::same_as<T,char>&&!std::same_as<T,char8_t>&&
!std::same_as<T,char16_t>&&!std::same_as<T,char32_t>&&
!std::same_as<T,wchar_t>;
// We want to migrate all users of these functions to use the unsigned type
// versions of the functions, but until they are all moved over, create a
// concept that captures all the types that must be supported for compatibility
// but that we want to remove.
//
// TODO(crbug.com/40256225): Switch uses to supported functions and
// remove.
template<typename T>
conceptSignedIntegerDeprecatedDoNotUse=
std::integral<T>&&!UnsignedInteger<T>;
// Round down |size| to a multiple of alignment, which must be a power of two.
template<typename T>
requiresUnsignedInteger<T>
inlineconstexpr TAlignDown(T size, T alignment){
DCHECK(std::has_single_bit(alignment));
return size&~(alignment-1);
}
// Round down |size| to a multiple of alignment, which must be a power of two.
// DEPRECATED; use the UnsignedInteger version.
//
// TODO(crbug.com/40256225): Switch uses and remove.
template<typename T>
inlineconstexprautoAlignDownDeprecatedDoNotUse(T size, T alignment){
using U= std::make_unsigned_t<T>;
DCHECK(std::has_single_bit(static_cast<U>(alignment)));
returnstatic_cast<U>(size)&~static_cast<U>(alignment-1);
}
// Move |ptr| back to the previous multiple of alignment, which must be a power
// of two. Defined for types where sizeof(T) is one byte.
template<typename T>
requires(sizeof(T)==1)
inline T*AlignDown(T* ptr,uintptr_t alignment){
returnreinterpret_cast<T*>(
AlignDown(reinterpret_cast<uintptr_t>(ptr), alignment));
}
// Round up |size| to a multiple of alignment, which must be a power of two.
template<typename T>
requiresUnsignedInteger<T>
inlineconstexpr TAlignUp(T size, T alignment){
DCHECK(std::has_single_bit(alignment));
return(size+ alignment-1)&~(alignment-1);
}
// Round up |size| to a multiple of alignment, which must be a power of two.
// DEPRECATED; use the UnsignedInteger version.
//
// TODO(crbug.com/40256225): Switch uses and remove.
template<typename T>
requiresSignedIntegerDeprecatedDoNotUse<T>
inlineconstexpr TAlignUpDeprecatedDoNotUse(T size, T alignment){
using U= std::make_unsigned_t<T>;
DCHECK(std::has_single_bit(static_cast<U>(alignment)));
returnstatic_cast<U>(size+ alignment-1)&~static_cast<U>(alignment-1);
}
// Advance |ptr| to the next multiple of alignment, which must be a power of
// two. Defined for types where sizeof(T) is one byte.
template<typename T>
requires(sizeof(T)==1)
inline T*AlignUp(T* ptr,uintptr_t alignment){
returnreinterpret_cast<T*>(
AlignUp(reinterpret_cast<uintptr_t>(ptr), alignment));
}
// Returns the integer i such as 2^i <= n < 2^(i+1).
//
// A common use for this function is to measure the number of bits required to
// contain a value; for that case use std::bit_width().
//
// A common use for this function is to take its result and use it to left-shift
// a bit; instead of doing so, use std::bit_floor().
constexprintLog2Floor(uint32_t n){
return31- std::countl_zero(n);
}
// Returns the integer i such as 2^(i-1) < n <= 2^i.
//
// A common use for this function is to measure the number of bits required to
// contain a value; for that case use std::bit_width().
//
// A common use for this function is to take its result and use it to left-shift
// a bit; instead of doing so, use std::bit_ceil().
constexprintLog2Ceiling(uint32_t n){
// When n == 0, we want the function to return -1.
// When n == 0, (n - 1) will underflow to 0xFFFFFFFF, which is
// why the statement below starts with (n ? 32 : -1).
return(n?32:-1)- std::countl_zero(n-1);
}
// Returns a value of type T with a single bit set in the left-most position.
// Can be used instead of manually shifting a 1 to the left. Unlike the other
// functions in this file, usable for any integral type.
template<typename T>
requires std::integral<T>
constexpr TLeftmostBit(){
T one(1u);
return one<<(8*sizeof(T)-1);
}
}// namespace base::bits
#endif// BASE_BITS_H_

[8]ページ先頭

©2009-2025 Movatter.jp