Skip to content

Commit

Permalink
Add valid method to rb_map
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielKrawisz committed Aug 23, 2022
1 parent 2fa0f58 commit 1f1f6a1
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 6 deletions.
11 changes: 8 additions & 3 deletions include/data/encoding/halves.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,17 +173,22 @@ namespace data::encoding {
};

template <typename half>
typename twice<half>::type combine(half greater, half lesser) {
typename twice<half>::type inline combine(half greater, half lesser) {
return ((typename twice<half>::type)(greater) << count_digits<half>::value * 8) + lesser;
};

template <typename half>
typename twice<half>::type multiply(half a, half b, half r) {
typename twice<half>::type inline multiply(half a, half b, half r) {
return (typename twice<half>::type)(a) * (typename twice<half>::type)(b) + (typename twice<half>::type)(r);
};

template <typename half>
typename twice<half>::type add(half a, half b, half r) {
typename twice<half>::type inline subtract(half a, half b, half r) {
return (typename twice<half>::type)(a) - b + r;
};

template <typename half>
typename twice<half>::type inline add(half a, half b, half r) {
return (typename twice<half>::type)(a) + b + r;
};

Expand Down
42 changes: 40 additions & 2 deletions include/data/encoding/words.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,13 +163,51 @@ namespace data::arithmetic {
template <typename digit, typename sen, typename ita, typename itb>
requires std::input_iterator<itb> && std::output_iterator<ita, digit> && std::sentinel_for<sen, ita>
digit minus(sen z, ita a, itb b, itb i) {
throw method::unimplemented{"arithmetic::minus"};
using two_digits = typename encoding::twice<digit>::type;

digit remainder = 0;

while (i != z) {
two_digits result = encoding::subtract<digit>(*a, *b, remainder);
remainder = encoding::greater_half(result);
*i = encoding::lesser_half(result);
i++;
a++;
b++;
}

return remainder;
}

template <typename digit, typename sen, typename ita, typename itb>
requires std::input_iterator<itb> && std::output_iterator<ita, digit> && std::sentinel_for<sen, ita>
digit times(sen z, ita a, itb b, itb i) {
throw method::unimplemented{"arithmetic::minus"};
using two_digits = typename encoding::twice<digit>::type;

digit remainder = 0;
auto ab = a;
while (i != z) {
auto ax = ab;
auto bx = b;

two_digits result = remainder;

while (true) {
result += two_digits(*ax) * two_digits(*bx);

if (ax == a) break;
ax++;
bx--;
}

remainder = encoding::greater_half(result);
*i = encoding::lesser_half(result);
i++;
a++;
b++;
}

return remainder;
}

// bit shift operations are defined in terms of big-endian numbers.
Expand Down
11 changes: 10 additions & 1 deletion include/data/tools/rb_map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,16 @@ namespace data::tool {
rb_map remove(const K& k) const;
rb_map remove(const entry& e) const;

bool valid() const;
bool valid() const {
try {
milewski::okasaki::forEach(Map, [](const K &k, const V &v) -> void {
if (!data::valid(k) || !data::valid(v)) throw 0;
});
} catch (int) {
return false;
}
return true;
}

bool empty() const;
size_t size() const;
Expand Down

0 comments on commit 1f1f6a1

Please sign in to comment.