Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions include/safe/algorithm/irange.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ template <typename BeginT, typename EndT> struct irange {
constexpr iterator(irange const *parent, T value, bool end)
: parent_{parent}, value_{value}, end_{end} {}

constexpr ret_t operator*() const { return unsafe_cast<ret_t>(value_); }
constexpr auto operator*() const -> ret_t {
return unsafe_cast<ret_t>(value_);
}

constexpr auto operator++() {
auto const new_unsafe_value = value_++;
Expand All @@ -37,14 +39,11 @@ template <typename BeginT, typename EndT> struct irange {
return *this;
}

constexpr bool operator==(iterator rhs) {
constexpr auto operator==(iterator rhs) -> bool {
if (end_) {
return rhs.end_;

} else {
return parent_ == rhs.parent_ && value_ == rhs.value_ &&
!rhs.end_;
}
return parent_ == rhs.parent_ && value_ == rhs.value_ && !rhs.end_;
}
};

Expand All @@ -62,4 +61,4 @@ template <typename BeginT, typename EndT> struct irange {
this, end_.unsafe_value() - 1, true};
}
};
} // namespace safe
} // namespace safe
84 changes: 48 additions & 36 deletions include/safe/array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,96 +28,106 @@ template <typename T, std::size_t Size> struct array {

// TODO: constructors
template <typename... Us>
constexpr array(Us... values) : storage({values...}) {}
constexpr explicit array(Us... values) : storage({values...}) {}

[[nodiscard]] constexpr reference
operator[](var<size_type, ival<0, Size - 1>> pos) {
[[nodiscard]] constexpr auto
operator[](var<size_type, ival<0, Size - 1>> pos) -> reference {
return storage[pos.unsafe_value()];
}

[[nodiscard]] constexpr const_reference
operator[](var<size_type, ival<0, Size - 1>> pos) const {
[[nodiscard]] constexpr auto
operator[](var<size_type, ival<0, Size - 1>> pos) const -> const_reference {
return storage[pos.unsafe_value()];
}

[[nodiscard]] constexpr reference
at(var<size_type, ival<0, Size - 1>> pos) {
[[nodiscard]] constexpr auto at(var<size_type, ival<0, Size - 1>> pos)
-> reference {
return storage[pos.unsafe_value()];
}

[[nodiscard]] constexpr const_reference
at(var<size_type, ival<0, Size - 1>> pos) const {
[[nodiscard]] constexpr auto at(var<size_type, ival<0, Size - 1>> pos) const
-> const_reference {
return storage[pos.unsafe_value()];
}

[[nodiscard]] constexpr reference front() { return storage.front(); }
[[nodiscard]] constexpr auto front() -> reference {
return storage.front();
}

[[nodiscard]] constexpr const_reference front() const {
[[nodiscard]] constexpr auto front() const -> const_reference {
return storage.front();
}

[[nodiscard]] constexpr reference back() { return storage.back(); }
[[nodiscard]] constexpr auto back() -> reference { return storage.back(); }

[[nodiscard]] constexpr const_reference back() const {
[[nodiscard]] constexpr auto back() const -> const_reference {
return storage.back();
}

// NOTE: intentionally omitting data()

[[nodiscard]] constexpr iterator begin() { return storage.begin(); }
[[nodiscard]] constexpr auto begin() -> iterator { return storage.begin(); }

[[nodiscard]] constexpr const_iterator begin() const {
[[nodiscard]] constexpr auto begin() const -> const_iterator {
return storage.begin();
}

[[nodiscard]] constexpr const_iterator cbegin() const {
[[nodiscard]] constexpr auto cbegin() const -> const_iterator {
return storage.cbegin();
}

[[nodiscard]] constexpr iterator end() { return storage.end(); }
[[nodiscard]] constexpr auto end() -> iterator { return storage.end(); }

[[nodiscard]] constexpr const_iterator end() const { return storage.end(); }
[[nodiscard]] constexpr auto end() const -> const_iterator {
return storage.end();
}

[[nodiscard]] constexpr const_iterator cend() const {
[[nodiscard]] constexpr auto cend() const -> const_iterator {
return storage.cend();
}

[[nodiscard]] constexpr reverse_iterator rbegin() {
[[nodiscard]] constexpr auto rbegin() -> reverse_iterator {
return storage.rbegin();
}

[[nodiscard]] constexpr const_reverse_iterator rbegin() const {
[[nodiscard]] constexpr auto rbegin() const -> const_reverse_iterator {
return storage.rbegin();
}

[[nodiscard]] constexpr const_reverse_iterator crbegin() const {
[[nodiscard]] constexpr auto crbegin() const -> const_reverse_iterator {
return storage.crbegin();
}

[[nodiscard]] constexpr reverse_iterator rend() { return storage.rend(); }
[[nodiscard]] constexpr auto rend() -> reverse_iterator {
return storage.rend();
}

[[nodiscard]] constexpr const_reverse_iterator rend() const {
[[nodiscard]] constexpr auto rend() const -> const_reverse_iterator {
return storage.rend();
}

[[nodiscard]] constexpr const_reverse_iterator crend() const {
[[nodiscard]] constexpr auto crend() const -> const_reverse_iterator {
return storage.crend();
}

[[nodiscard]] constexpr bool empty() const { return storage.empty(); }
[[nodiscard]] constexpr auto empty() const -> bool {
return storage.empty();
}

[[nodiscard]] constexpr size_type size() const { return storage.size(); }
[[nodiscard]] constexpr auto size() const -> size_type {
return storage.size();
}

[[nodiscard]] constexpr size_type max_size() const {
[[nodiscard]] constexpr auto max_size() const -> size_type {
return storage.max_size();
}

constexpr void fill(T const &value) { storage.fill(value); }

constexpr void swap(array &other) { storage.swap(other.storage); }

[[nodiscard]] friend constexpr bool operator==(array const &lhs,
array const &rhs) {
[[nodiscard]] friend constexpr auto operator==(array const &lhs,
array const &rhs) -> bool {
return lhs.storage == rhs.storage;
}

Expand All @@ -132,22 +142,24 @@ template <class T, class... U> array(T, U...) -> array<T, 1 + sizeof...(U)>;

namespace std {
template <std::size_t I, class T, std::size_t N>
[[nodiscard]] constexpr T &get(safe::array<T, N> &a) noexcept {
[[nodiscard]] constexpr auto get(safe::array<T, N> &a) noexcept -> T & {
return a[safe::constant<std::size_t, I>];
}

template <std::size_t I, class T, std::size_t N>
[[nodiscard]] constexpr T &&get(safe::array<T, N> &&a) noexcept {
return a[safe::constant<std::size_t, I>];
[[nodiscard]] constexpr auto get(safe::array<T, N> &&a) noexcept -> T && {
return std::move(a)[safe::constant<std::size_t, I>];
}

template <std::size_t I, class T, std::size_t N>
[[nodiscard]] constexpr T const &get(safe::array<T, N> const &a) noexcept {
[[nodiscard]] constexpr auto get(safe::array<T, N> const &a) noexcept
-> T const & {
return a[safe::constant<std::size_t, I>];
}

template <std::size_t I, class T, std::size_t N>
[[nodiscard]] constexpr T const &&get(safe::array<T, N> const &&a) noexcept {
[[nodiscard]] constexpr auto get(safe::array<T, N> const &&a) noexcept
-> T const && {
return a[safe::constant<std::size_t, I>];
}

Expand All @@ -164,4 +176,4 @@ template <std::size_t I, class T, std::size_t N>
struct tuple_element<I, safe::array<T, N>> {
using type = T;
};
} // namespace std
} // namespace std
19 changes: 8 additions & 11 deletions include/safe/big_integer/detail/compare.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ template <std::size_t LhsNumBits, std::size_t RhsNumBits>

if (lhs.get(i) < rhs.get(i)) {
return std::strong_ordering::less;

} else if (lhs.get(i) > rhs.get(i)) {
}
if (lhs.get(i) > rhs.get(i)) {
return std::strong_ordering::greater;
}
} while (i > 0);
Expand All @@ -33,15 +33,12 @@ template <std::size_t LhsNumBits, std::size_t RhsNumBits>
if (lhs.negative()) {
if (rhs.negative()) {
return unsigned_compare(lhs, rhs);
} else {
return std::strong_ordering::less;
}
} else {
if (rhs.negative()) {
return std::strong_ordering::greater;
} else {
return unsigned_compare(lhs, rhs);
}
return std::strong_ordering::less;
}
if (rhs.negative()) {
return std::strong_ordering::greater;
}
return unsigned_compare(lhs, rhs);
}
} // namespace safe::_big_integer::detail
} // namespace safe::_big_integer::detail
4 changes: 2 additions & 2 deletions include/safe/big_integer/detail/multiplies.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ constexpr static auto unsigned_multiplies = [](auto &result, auto const &lhs,

result_t partial_product{
{static_cast<elem_t>(raw_partial_product & 0xffff'ffffu),
static_cast<elem_t>(raw_partial_product >> 32)}};
static_cast<elem_t>(raw_partial_product >> 32u)}};

bit_shift_left(partial_product, partial_product, (i + j) * 32);

Expand Down Expand Up @@ -59,4 +59,4 @@ constexpr static auto multiplies = [](auto &result, auto const &lhs,
}
}
};
} // namespace safe::_big_integer::detail
} // namespace safe::_big_integer::detail
4 changes: 2 additions & 2 deletions include/safe/big_integer/detail/plus.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ constexpr static auto plus =
double_elem_t const result =
lhs + rhs + static_cast<double_elem_t>(carry);

carry = result >> 32;
carry = result >> 32u;
return result & 0xffff'ffffu;
});

Expand All @@ -29,4 +29,4 @@ constexpr static auto minus = [](auto &result, auto const &lhs,
negate(negative_rhs, rhs);
plus(result, lhs, negative_rhs);
};
} // namespace safe::_big_integer::detail
} // namespace safe::_big_integer::detail
8 changes: 3 additions & 5 deletions include/safe/big_integer/detail/shift.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,8 @@ constexpr static auto bit_shift_left =
reverse_zip_transform([=](elem_t const upper, elem_t const lower) {
if (bit_shift_amt == 0) {
return upper;
} else {
return (upper << bit_shift_amt) | (lower >> (32 - bit_shift_amt));
}
return (upper << bit_shift_amt) | (lower >> (32 - bit_shift_amt));
})(result, lhs_shifted_upper, lhs_shifted_lower);
};

Expand Down Expand Up @@ -63,9 +62,8 @@ constexpr static auto bit_shift_right =
zip_transform([=](elem_t const upper, elem_t const lower) {
if (bit_shift_amt == 0) {
return lower;
} else {
return (upper << (32 - bit_shift_amt)) | (lower >> bit_shift_amt);
}
return (upper << (32 - bit_shift_amt)) | (lower >> bit_shift_amt);
})(result, lhs_shifted_upper, lhs_shifted_lower);
};
} // namespace safe::_big_integer::detail
} // namespace safe::_big_integer::detail
32 changes: 15 additions & 17 deletions include/safe/big_integer/detail/storage.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,8 @@ template <std::size_t NumBits> struct storage {
std::array<elem_t, num_elems> elems{};

constexpr storage() = default;

constexpr storage(std::array<elem_t, num_elems> const &new_elems) {
elems = new_elems;
}
constexpr storage(std::array<elem_t, num_elems> const &new_elems)
: elems{new_elems} {}

template <std::size_t RhsNumBits>
constexpr storage(storage<RhsNumBits> const &rhs) {
Expand Down Expand Up @@ -51,22 +49,21 @@ template <std::size_t NumBits> struct storage {
return true;
}

[[nodiscard]] constexpr bool negative() const {
[[nodiscard]] constexpr auto negative() const -> bool {
return (elems.back() >> 31) & 1;
}

[[nodiscard]] constexpr auto get(int32_t i) const -> elem_t {
if (i < 0) {
return 0u;
} else if (i < num_elems) {
}
if (i < num_elems) {
return elems[i];
} else {
if (negative()) {
return 0xffff'ffffu;
} else {
return 0u;
}
}
if (negative()) {
return 0xffff'ffffu;
}
return 0u;
}

constexpr auto set(int32_t i, elem_t elem) -> void {
Expand Down Expand Up @@ -101,18 +98,19 @@ template <typename T>
}

template <std::size_t NumBits>
[[nodiscard]] constexpr auto const &
to_storage(interface::big_integer<NumBits> const &v) {
[[nodiscard]] constexpr auto
to_storage(interface::big_integer<NumBits> const &v) -> auto const & {
return v.unsafe_storage;
}

template <std::size_t NumBits>
[[nodiscard]] constexpr auto &to_storage(storage<NumBits> &v) {
[[nodiscard]] constexpr auto to_storage(storage<NumBits> &v) -> auto & {
return v;
}

template <std::size_t NumBits>
[[nodiscard]] constexpr auto const &to_storage(storage<NumBits> const &v) {
[[nodiscard]] constexpr auto to_storage(storage<NumBits> const &v)
-> auto const & {
return v;
}

Expand Down Expand Up @@ -167,4 +165,4 @@ constexpr static auto sum_width = [](std::size_t left_bits,
std::size_t right_bits) -> std::size_t {
return left_bits + right_bits;
};
} // namespace safe::_big_integer::detail
} // namespace safe::_big_integer::detail
6 changes: 3 additions & 3 deletions include/safe/big_integer/interface/big_integer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@

namespace safe::_big_integer::interface {
template <std::size_t NumBits> struct big_integer {
detail::storage<NumBits> unsafe_storage;
detail::storage<NumBits> unsafe_storage{};

constexpr big_integer(auto value)
: unsafe_storage{detail::to_storage(value)} {}
constexpr big_integer() : unsafe_storage{} {}
constexpr big_integer() = default;

constexpr auto operator&=(auto const &rhs) -> big_integer & {
return do_assign_op(detail::bit_and, rhs);
Expand Down Expand Up @@ -386,4 +386,4 @@ struct std::numeric_limits<
constexpr static auto signaling_NaN() noexcept -> T { return T{0}; }

constexpr static auto denorm_min() noexcept -> T { return T{0}; }
};
};
Loading