]> git.proxmox.com Git - ceph.git/blame - ceph/src/include/intarith.h
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / include / intarith.h
CommitLineData
11fdf7f2 1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
7c673cae
FG
2// vim: ts=8 sw=2 smarttab
3/*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
11fdf7f2 10 * License version 2.1, as published by the Free Software
7c673cae 11 * Foundation. See file COPYING.
11fdf7f2 12 *
7c673cae
FG
13 */
14
15#ifndef CEPH_INTARITH_H
16#define CEPH_INTARITH_H
17
1e59de90
TL
18#include <bit>
19#include <climits>
20#include <concepts>
11fdf7f2 21#include <type_traits>
7c673cae 22
11fdf7f2
TL
23template<typename T, typename U>
24constexpr inline std::make_unsigned_t<std::common_type_t<T, U>> div_round_up(T n, U d) {
25 return (n + d - 1) / d;
26}
7c673cae 27
7c673cae 28
11fdf7f2
TL
29template<typename T, typename U>
30constexpr inline std::make_unsigned_t<std::common_type_t<T, U>> round_up_to(T n, U d) {
31 return (n % d ? (n + d - n % d) : n);
32}
7c673cae 33
11fdf7f2
TL
34template<typename T, typename U>
35constexpr inline std::make_unsigned_t<std::common_type_t<T, U>> shift_round_up(T x, U y) {
36 return (x + (1 << y) - 1) >> y;
37}
7c673cae 38
7c673cae 39/*
11fdf7f2 40 * Wrappers for various sorts of alignment and rounding. The "align" must
7c673cae
FG
41 * be a power of 2. Often times it is a block, sector, or page.
42 */
43
44/*
45 * return x rounded down to an align boundary
11fdf7f2
TL
46 * eg, p2align(1200, 1024) == 1024 (1*align)
47 * eg, p2align(1024, 1024) == 1024 (1*align)
48 * eg, p2align(0x1234, 0x100) == 0x1200 (0x12*align)
49 * eg, p2align(0x5600, 0x100) == 0x5600 (0x56*align)
7c673cae 50 */
11fdf7f2
TL
51template<typename T>
52constexpr inline T p2align(T x, T align) {
53 return x & -align;
54}
7c673cae
FG
55
56/*
57 * return x % (mod) align
11fdf7f2
TL
58 * eg, p2phase(0x1234, 0x100) == 0x34 (x-0x12*align)
59 * eg, p2phase(0x5600, 0x100) == 0x00 (x-0x56*align)
7c673cae 60 */
11fdf7f2
TL
61template<typename T>
62constexpr inline T p2phase(T x, T align) {
63 return x & (align - 1);
64}
7c673cae
FG
65
66/*
67 * return how much space is left in this block (but if it's perfectly
68 * aligned, return 0).
11fdf7f2
TL
69 * eg, p2nphase(0x1234, 0x100) == 0xcc (0x13*align-x)
70 * eg, p2nphase(0x5600, 0x100) == 0x00 (0x56*align-x)
7c673cae 71 */
11fdf7f2
TL
72template<typename T>
73constexpr inline T p2nphase(T x, T align) {
74 return -x & (align - 1);
75}
7c673cae
FG
76
77/*
78 * return x rounded up to an align boundary
11fdf7f2
TL
79 * eg, p2roundup(0x1234, 0x100) == 0x1300 (0x13*align)
80 * eg, p2roundup(0x5600, 0x100) == 0x5600 (0x56*align)
7c673cae 81 */
11fdf7f2
TL
82template<typename T>
83constexpr inline T p2roundup(T x, T align) {
84 return -(-x & -align);
85}
7c673cae 86
7c673cae 87// count bits (set + any 0's that follow)
1e59de90
TL
88template<std::integral T>
89unsigned cbits(T v) {
90 return (sizeof(v) * CHAR_BIT) - std::countl_zero(std::make_unsigned_t<T>(v));
7c673cae
FG
91}
92
7c673cae 93#endif