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

Get rid of dependency on complex.h #271

Closed
whitequark opened this issue Feb 20, 2015 · 5 comments
Closed

Get rid of dependency on complex.h #271

whitequark opened this issue Feb 20, 2015 · 5 comments

Comments

@whitequark
Copy link
Contributor

complex.h is not available on Android.

@whitequark
Copy link
Contributor Author

Here's a patch I use:

diff --git a/src/configure/make_primitive_details_stubs.c b/src/configure/make_primitive_details_stubs.c
index d64755f..e3243b2 100644
--- a/src/configure/make_primitive_details_stubs.c
+++ b/src/configure/make_primitive_details_stubs.c
@@ -11,7 +11,6 @@
 #include <inttypes.h>
 #include <errno.h>
 #include <stdint.h>
-#include <complex.h>
 #include <stdbool.h>

 #include <caml/mlvalues.h>
@@ -61,8 +60,8 @@ static struct details {
   ENTRY(Nativeint, intnat, "%" REAL_ARCH_INTNAT_PRINTF_FORMAT "d"),
   ENTRY(Float, float, "%.12g"),
   ENTRY(Double, double, "%.12g"),
-  ENTRY(Complex32, float complex, NULL),
-  ENTRY(Complex64, double complex, NULL),
+  ENTRY(Complex32, float _Complex, NULL),
+  ENTRY(Complex64, double _Complex, NULL),
 };

 void generate_function(char *name, char *type,
diff --git a/src/ctypes/complex_stubs.c b/src/ctypes/complex_stubs.c
index 699d88e..dd0a23d 100644
--- a/src/ctypes/complex_stubs.c
+++ b/src/ctypes/complex_stubs.c
@@ -5,8 +5,6 @@
  * See the file LICENSE for details.
  */

-#include <complex.h>
-
 #include <caml/memory.h>
 #include <caml/alloc.h>

@@ -21,25 +19,25 @@ static value allocate_complex_value(double r, double i)
 }

 /* ctypes_copy_float_complex : float complex -> Complex.t */
-value ctypes_copy_float_complex(float complex c)
+value ctypes_copy_float_complex(float _Complex c)
 {
-  return allocate_complex_value(crealf(c), cimagf(c));
+  return allocate_complex_value(__real__ c, __imag__ c);
 }

 /* ctypes_copy_double_complex : double complex -> Complex.t */
-value ctypes_copy_double_complex(double complex c)
+value ctypes_copy_double_complex(double _Complex c)
 {
-  return allocate_complex_value(creal(c), cimag(c));
+  return allocate_complex_value(__real__ c, __imag__ c);
 }

 /* ctypes_float_complex_val : Complex.t -> float complex */
-float complex ctypes_float_complex_val(value v)
+float _Complex ctypes_float_complex_val(value v)
 {
-  return Double_field(v, 0) + Double_field(v, 1) * I;
+  return Double_field(v, 0) + Double_field(v, 1) * (__extension__ 1.0iF);
 }

 /* ctypes_double_complex_val : Complex.t -> double complex */
-double complex ctypes_double_complex_val(value v)
+double _Complex ctypes_double_complex_val(value v)
 {
-  return Double_field(v, 0) + Double_field(v, 1) * I;
+  return Double_field(v, 0) + Double_field(v, 1) * (__extension__ 1.0iF);
 }
diff --git a/src/ctypes/ctypes_complex_stubs.h b/src/ctypes/ctypes_complex_stubs.h
index 96d0e5e..766713f 100644
--- a/src/ctypes/ctypes_complex_stubs.h
+++ b/src/ctypes/ctypes_complex_stubs.h
@@ -8,19 +8,18 @@
 #ifndef CTYPES_COMPLEX_STUBS_H
 #define CTYPES_COMPLEX_STUBS_H

-#include <complex.h>
 #include <caml/mlvalues.h>

 /* ctypes_copy_float_complex : float complex -> Complex.t */
-value ctypes_copy_float_complex(float complex);
+value ctypes_copy_float_complex(float _Complex);

 /* ctypes_copy_double_complex : double complex -> Complex.t */
-value ctypes_copy_double_complex(double complex);
+value ctypes_copy_double_complex(double _Complex);

 /* ctypes_float_complex_val : Complex.t -> float complex */
-float complex ctypes_float_complex_val(value);
+float _Complex ctypes_float_complex_val(value);

 /* ctypes_double_complex_val : Complex.t -> double complex */
-double complex ctypes_double_complex_val(value);
+double _Complex ctypes_double_complex_val(value);

 #endif /* CTYPES_COMPLEX_STUBS_H */
diff --git a/src/ctypes/type_info_stubs.c b/src/ctypes/type_info_stubs.c
index 188ada4..1b8271f 100644
--- a/src/ctypes/type_info_stubs.c
+++ b/src/ctypes/type_info_stubs.c
@@ -12,7 +12,6 @@
 #include <inttypes.h>
 #include <stdio.h>
 #include <assert.h>
-#include <complex.h>
 #include <string.h>
 #include <stdbool.h>

@@ -65,8 +64,8 @@ value ctypes_read(value prim_, value buffer_)
    case Nativeint: b = caml_copy_nativeint(*(intnat *)buf); break;
    case Float: b = caml_copy_double(*(float *)buf); break;
    case Double: b = caml_copy_double(*(double *)buf); break;
-   case Complex32: b = ctypes_copy_float_complex(*(float complex *)buf); break;
-   case Complex64: b = ctypes_copy_double_complex(*(double complex *)buf); break;
+   case Complex32: b = ctypes_copy_float_complex(*(float _Complex *)buf); break;
+   case Complex64: b = ctypes_copy_double_complex(*(double _Complex *)buf); break;
    default:
     assert(0);
   }
@@ -106,8 +105,8 @@ value ctypes_write(value prim_, value v, value buffer_)
    case Nativeint: *(intnat *)buf = Nativeint_val(v); break;
    case Float: *(float *)buf = Double_val(v); break;
    case Double: *(double *)buf = Double_val(v); break;
-   case Complex32: *(float complex *)buf = ctypes_float_complex_val(v); break;
-   case Complex64: *(double complex *)buf = ctypes_double_complex_val(v); break;
+   case Complex32: *(float _Complex *)buf = ctypes_float_complex_val(v); break;
+   case Complex64: *(double _Complex *)buf = ctypes_double_complex_val(v); break;
    default:
     assert(0);
   }
@@ -152,13 +151,13 @@ value ctypes_string_of_prim(value prim_, value v)
   case Float: len = snprintf(buf, sizeof buf, "%.12g", Double_val(v)); break;
   case Double: len = snprintf(buf, sizeof buf, "%.12g", Double_val(v)); break;
   case Complex32: {
-    float complex c = ctypes_float_complex_val(v);
-    len = snprintf(buf, sizeof buf, "%.12g+%.12gi", crealf(c), cimagf(c));
+    float _Complex c = ctypes_float_complex_val(v);
+    len = snprintf(buf, sizeof buf, "%.12g+%.12gi", __real__ c, __imag__ c);
     break;
   }
   case Complex64: {
-    double complex c = ctypes_double_complex_val(v);
-    len = snprintf(buf, sizeof buf, "%.12g+%.12gi", creal(c), cimag(c));
+    double _Complex c = ctypes_double_complex_val(v);
+    len = snprintf(buf, sizeof buf, "%.12g+%.12gi", __real__ c, __imag__ c);
     break;
   }
   default:

@yallop yallop added this to the ctypes 0.5 milestone Mar 25, 2015
@yallop yallop modified the milestone: ctypes 0.5 Mar 18, 2016
@whitequark
Copy link
Contributor Author

@yallop ping

@yallop
Copy link
Owner

yallop commented Mar 9, 2017

I'd gladly merge a PR for this, but I'd prefer to have the non-standard extensions (__real__, etc.) pulled out into a compatibility header rather than inlined in the code. It'd even be possible to use standard C, since complex numbers have the same representation as length 2 arrays.

Changing complex to _Complex everywhere is fine, of course.

@whitequark
Copy link
Contributor Author

It'd even be possible to use standard C, since complex numbers have the same representation as length 2 arrays.

Is this actually an ABI guarantee?

@yallop
Copy link
Owner

yallop commented Mar 9, 2017

C99 (or at least the draft I have to hand) says:

Each complex type has the same representation and alignment requirements as an array type containing exactly two elements of the corresponding real type; the first element is equal to the real part, and the second element to the imaginary part, of the complex number.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants