libjmmcg  release_579_6_g8cffd
A C++ library containing an eclectic mix of useful, advanced components.
int128_compatibility.hpp
Go to the documentation of this file.
1 #ifndef LIBJMMCG_CORE_INT128_COMPATIBILITY_HPP
2 #define LIBJMMCG_CORE_INT128_COMPATIBILITY_HPP
3 
4 /******************************************************************************
5  * * Copyright © 2021 by J.M.McGuiness, coder@hussar.me.uk
6  **
7  ** This library is free software; you can redistribute it and/or
8  ** modify it under the terms of the GNU Lesser General Public
9  ** License as published by the Free Software Foundation; either
10  ** version 2.1 of the License, or (at your option) any later version.
11  **
12  ** This library is distributed in the hope that it will be useful,
13  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  ** Lesser General Public License for more details.
16  **
17  ** You should have received a copy of the GNU Lesser General Public
18  ** License along with this library; if not, write to the Free Software
19  ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21 
22 #include <cassert>
23 #include <cstdint>
24 
25 /**
26  * \file For those architectures that do not support 128-bit integer types as builtins, e.g. ARM & many 32-bit platforms.
27  */
28 
29 namespace jmmcg { namespace LIBJMMCG_VER_NAMESPACE {
30 
31 #ifdef __SIZEOF_INT128__
32  using int128_t=__int128;
33  using uint128_t=__uint128_t;
34 
35  inline unsigned
36  count_trailing_zeroes_compat(const uint128_t value) noexcept(true) {
37  assert(value!=0);
38  return __builtin_ctzll(value);
39  }
40 
41  inline unsigned
42  count_leading_zeroes_compat(const uint128_t value) noexcept(true) {
43  assert(value!=0);
44  return __builtin_clzll(value);
45  }
46 
47 #else
48  struct int128_t {
51  } __attribute__((packed));
52  struct uint128_t {
55 
56  constexpr bool
57  operator==(std::uint64_t rhs) const noexcept(true) {
58  return high==0 && low<rhs;
59  }
60  constexpr bool
61  operator!=(std::uint64_t rhs) const noexcept(true) {
62  return !this->operator==(rhs);
63  }
64  constexpr bool
65  operator<(uint128_t const &rhs) const noexcept(true) {
66  return high<rhs.high
67  || (
68  high==rhs.high && low<rhs.low
69  );
70  }
71 
72  constexpr uint128_t &
73  operator~() noexcept(true) {
74  low=~low;
75  high=~high;
76  return *this;
77  }
78  constexpr uint128_t &
79  operator&=(uint128_t const &rhs) noexcept(true) {
80  low&=rhs.low;
81  high&=rhs.high;
82  return *this;
83  }
84  constexpr uint128_t
85  operator>>(std::size_t const shift) const noexcept(true) {
86  assert(shift<=128);
87  if (shift>=64) {
88  uint128_t tmp{high, 0};
89  assert(tmp<*this);
90  return tmp>>(shift-64);
91  } else {
92  const uint128_t tmp{
93  (high<<(64-shift)) | (low>>shift),
94  (high>>shift)
95  };
96  assert(tmp<*this);
97  return tmp;
98  }
99  }
100  } __attribute__((packed));
101 
102  inline unsigned
104  assert(value.high!=0 || value.low!=0);
106  }
107 
108  inline unsigned
110  assert(value.high!=0 || value.low!=0);
112  }
113 
114 #endif
115 
116 } }
117 
118 #endif