Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port conversions to c++ #200

Open
wants to merge 35 commits into
base: main
Choose a base branch
from
Open

Conversation

juntuu
Copy link
Collaborator

@juntuu juntuu commented Mar 7, 2021

The main funtion doing the conversion work is convert<From, To>(). The external interface is unchanged (except B -> bool).

  • Simple cases use just simple copy, with range check when From may exceed Tos value range.
  • Another overload takes additional trasformation function, if the function returns std::optional<T>, a std::nullopt signals failure and is checked
  • More complex cases use template specialisations

Also added template parameter to specify return type of pointer_to_values() (e9e7f41).
This changes the semantics of set_value_at() to depend on the type of the value:

T value;
set_value_at(arr, idx, value)

// was previously equivalent to
int64_t *values = (int64_t*)AV(arr);
values[idx] = value;

// is now equivalent to
T *values = (T*)AV(arr);
values[idx] = value;

This allows use of set_value_at() with types wider than, or not convertible to, int64_t.
However, this requires more care with the value parameter, it must be the correct type (correct bit width), to get the correct stride.

@juntuu juntuu force-pushed the port-conversions branch 2 times, most recently from b7ef90d to df695e3 Compare March 7, 2021 01:30
@juntuu juntuu marked this pull request as ready for review March 7, 2021 14:27
@juntuu juntuu requested a review from codereport as a code owner March 7, 2021 14:27
@juntuu juntuu added the c to c++ Porting C code to C++ label Mar 7, 2021
@juntuu juntuu force-pushed the port-conversions branch 3 times, most recently from 70472ad to d9ae65c Compare March 8, 2021 08:42
@juntuu juntuu mentioned this pull request Mar 8, 2021
@codereport
Copy link
Owner

This is awesome! Will do a live code review on the next live stream!

Copy link
Owner

@codereport codereport left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is 🔥 Thanks for opening the PR. Comments below or for the first 200 lines.

[[nodiscard]] constexpr auto
in_range(V value) -> bool {
if constexpr (std::is_same_v<bool, V>) {
(void)value;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this for?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems indeed unnecessary, I think I had some compiler errors with bool at the time, but don't remember exactly what

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found the reason for the special case, however, I think I'll just disable the warning

../jsrc/conversions.cpp:29:45: error: comparison of constant ‘-9223372036854775808’ with boolean expression is always true [-Werror=bool-compare]
--

jsrc/conversions.cpp Outdated Show resolved Hide resolved

template <>
[[nodiscard]] auto
convert<D, bool>(J jt, array w, void *yv, D fuzz) -> bool {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's try to avoid the D macro

Suggested change
convert<D, bool>(J jt, array w, void *yv, D fuzz) -> bool {
convert<D, bool>(J jt, array w, void *yv, double fuzz) -> bool {

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe same goes for all the others

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did D -> double and I -> int64_t (and one last B -> bool)

most others are j specific structs

ps. typedefs not macros

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The different width integer types (1, 2, 3, 4 bytes; UC, US...) could possibly be replaced, but seeing the compiler, I'd postpone that to whenever those typedefs are refactored.

template <>
[[nodiscard]] auto
convert<Z, D>(J jt, array w, void *yv, D fuzz) -> bool {
if (fuzz != 0.0) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this ok?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Original test was if (fuzz), not sure if these have differences

Comment on lines 129 to 135
return convert<B, X>(jt,
w,
yv,
[=](auto v) {
int64_t u[] = {v};
return jtvec(jt, INT, 1L, u);
}) &&
!jt->jerr;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See if you can do something like this: (not {v} might not work.

Suggested change
return convert<B, X>(jt,
w,
yv,
[=](auto v) {
int64_t u[] = {v};
return jtvec(jt, INT, 1L, u);
}) &&
!jt->jerr;
auto name_me = [=](auto v) { return jtvec(jt, INT, 1L, {v}); };
return convert<B, X>(jt, w, yv, name_me) && !jt->jerr;

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{v} won't work in the parameter list, the function takes void*

jsrc/conversions.cpp Outdated Show resolved Hide resolved
Comment on lines +170 to +178
switch (mode) {
case XMFLR: p = e; break;
case XMCEIL: p = ceil(p); break;
case XMEXACT:
ASSERT(TEQ(p, e), EVDOMAIN);
p = e;
break;
case XMEXMT:
if (!TEQ(p, e)) { return jtvec(jt, INT, 0L, &iotavec[-IOTAVECBEGIN]); }
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
switch (mode) {
case XMFLR: p = e; break;
case XMCEIL: p = ceil(p); break;
case XMEXACT:
ASSERT(TEQ(p, e), EVDOMAIN);
p = e;
break;
case XMEXMT:
if (!TEQ(p, e)) { return jtvec(jt, INT, 0L, &iotavec[-IOTAVECBEGIN]); }
}
if (!TEQ(p, e)) return jtvec(jt, INT, 0L, &iotavec[-IOTAVECBEGIN]);
p = mode == XMEXACT ? e : ceil(p);

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This refactor would invalidate the meaning of the modes (if the comments are up to date)

jsource/jsrc/vx.h

Lines 20 to 23 in 5f03cf2

#define XMFLR 0 /* floor, round down */
#define XMCEIL 1 /* ceiling, round up */
#define XMEXACT 2 /* exact, error if impossible */
#define XMEXMT 3 /* exact, empty if impossible */

jsrc/conversions.cpp Outdated Show resolved Hide resolved
@juntuu juntuu force-pushed the port-conversions branch 4 times, most recently from e35c7cc to ddbcc44 Compare March 17, 2021 01:27
@juntuu
Copy link
Collaborator Author

juntuu commented Mar 17, 2021

CI compiler is giving somewhat ambiguous error:

../jsrc/conversions.cpp:565:71: error: call of overloaded ‘jtccvt(JST*&, <unnamed enum>, AD*&, AD**)’ is ambiguous
--

No idea how it thinks jtccvt() from all the functions would be overloaded...

Turned out the CI compiler had different idea of I compared to int64_t

The macro definition had parentheses, which made it work
@juntuu juntuu force-pushed the port-conversions branch 3 times, most recently from 984cba4 to 1224af8 Compare March 17, 2021 08:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c to c++ Porting C code to C++
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants