summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2009-06-30 15:53:41 +0000
committerTavian Barnes <tavianator@gmail.com>2009-06-30 15:53:41 +0000
commit5dcc62e9f198094e3fd49be1847871853c1449bc (patch)
treeb8efb924424c0160e77782ce40e8ddb6c85c9e2f
parenta50808b77e7b7f9c5239d6416bb8cb9741794670 (diff)
downloaddimension-5dcc62e9f198094e3fd49be1847871853c1449bc.tar.xz
New inline function framework.
-rw-r--r--libdimension/Makefile.am1
-rw-r--r--libdimension/array.c9
-rw-r--r--libdimension/dimension.h21
-rw-r--r--libdimension/dimension/array.h10
-rw-r--r--libdimension/dimension/geometry.h105
-rw-r--r--libdimension/geometry.c113
-rw-r--r--libdimension/inlines.c36
7 files changed, 154 insertions, 141 deletions
diff --git a/libdimension/Makefile.am b/libdimension/Makefile.am
index d73f1e7..125ad77 100644
--- a/libdimension/Makefile.am
+++ b/libdimension/Makefile.am
@@ -42,6 +42,7 @@ libdimension_la_SOURCES = $(nobase_include_HEADERS) \
cube.c \
error.c \
geometry.c \
+ inlines.c \
png.c \
progress.c \
object.c \
diff --git a/libdimension/array.c b/libdimension/array.c
index a22b450..fcd77f5 100644
--- a/libdimension/array.c
+++ b/libdimension/array.c
@@ -99,14 +99,7 @@ dmnsn_array_at(dmnsn_array *array, size_t i)
return (char *)array->ptr + array->obj_size*i;
}
-/* Get the size of the array */
-size_t
-dmnsn_array_size(const dmnsn_array *array)
-{
- return array->length;
-}
-
-/* Set the size of the array, atomically */
+/* Set the size of the array */
void
dmnsn_array_resize(dmnsn_array *array, size_t length)
{
diff --git a/libdimension/dimension.h b/libdimension/dimension.h
index 3e1bcf9..4157f8b 100644
--- a/libdimension/dimension.h
+++ b/libdimension/dimension.h
@@ -25,6 +25,27 @@
#ifndef DIMENSION_H
#define DIMENSION_H
+/* Handle inlines nicely without cheating and making them static. The
+ DMNSN_INLINE macro is set appropriately for the version of C you're using,
+ and non-inline versions are emitted in exactly one translation unit when
+ necessary. */
+#ifndef DMNSN_INLINE
+ #ifdef __cplusplus
+ /* C++ inline semantics */
+ #define DMNSN_INLINE inline
+ #elif (__STDC_VERSION__ >= 199901L)
+ /* C99 inline semantics */
+ #define DMNSN_INLINE inline
+ #elif defined(__GNUC__)
+ /* GCC inline semantics */
+ #define DMNSN_INLINE extern inline
+ #else
+ /* Unknown C - mark functions static and hope the compiler is smart enough
+ to inline them */
+ #define DMNSN_INLINE static
+ #endif
+#endif
+
#ifdef __cplusplus
/* We've been included from a C++ file; mark everything here as extern "C" */
extern "C" {
diff --git a/libdimension/dimension/array.h b/libdimension/dimension/array.h
index 5d5e50e..036d6c8 100644
--- a/libdimension/dimension/array.h
+++ b/libdimension/dimension/array.h
@@ -45,7 +45,13 @@ void dmnsn_array_get(const dmnsn_array *array, size_t i, void *obj);
void dmnsn_array_set(dmnsn_array *array, size_t i, const void *obj);
void *dmnsn_array_at(dmnsn_array *array, size_t i);
-size_t dmnsn_array_size(const dmnsn_array *array);
-void dmnsn_array_resize(dmnsn_array *array, size_t length);
+/* Inline so for-loops calling this are fast */
+DMNSN_INLINE size_t
+dmnsn_array_size(const dmnsn_array *array)
+{
+ return array->length;
+}
+
+void dmnsn_array_resize(dmnsn_array *array, size_t length);
#endif /* DIMENSION_ARRAY_H */
diff --git a/libdimension/dimension/geometry.h b/libdimension/dimension/geometry.h
index 9ddfbd9..2f08012 100644
--- a/libdimension/dimension/geometry.h
+++ b/libdimension/dimension/geometry.h
@@ -25,6 +25,8 @@
#ifndef DIMENSION_GEOMETRY_H
#define DIMENSION_GEOMETRY_H
+#include <math.h>
+
/* Vector and matrix types. */
typedef struct { double x, y, z; } dmnsn_vector;
@@ -39,12 +41,25 @@ typedef struct {
/* Shorthand for vector/matrix construction */
-dmnsn_vector dmnsn_vector_construct(double x, double y, double z);
-
-dmnsn_matrix dmnsn_matrix_construct(double a0, double a1, double a2, double a3,
- double b0, double b1, double b2, double b3,
- double c0, double c1, double c2, double c3,
- double d0, double d1, double d2, double d3);
+DMNSN_INLINE dmnsn_vector
+dmnsn_vector_construct(double x, double y, double z)
+{
+ dmnsn_vector v = { x, y, z };
+ return v;
+}
+
+DMNSN_INLINE dmnsn_matrix
+dmnsn_matrix_construct(double a0, double a1, double a2, double a3,
+ double b0, double b1, double b2, double b3,
+ double c0, double c1, double c2, double c3,
+ double d0, double d1, double d2, double d3)
+{
+ dmnsn_matrix m = { { { a0, a1, a2, a3 },
+ { b0, b1, b2, b3 },
+ { c0, c1, c2, c3 },
+ { d0, d1, d2, d3 } } };
+ return m;
+}
dmnsn_matrix dmnsn_identity_matrix();
dmnsn_matrix dmnsn_scale_matrix(dmnsn_vector s);
@@ -52,20 +67,69 @@ dmnsn_matrix dmnsn_translation_matrix(dmnsn_vector d);
/* Left-handed rotation; theta/|theta| = axis, |theta| = angle */
dmnsn_matrix dmnsn_rotation_matrix(dmnsn_vector theta);
-dmnsn_line dmnsn_line_construct(dmnsn_vector x0, dmnsn_vector n);
+DMNSN_INLINE dmnsn_line
+dmnsn_line_construct(dmnsn_vector x0, dmnsn_vector n)
+{
+ dmnsn_line l = { x0, n };
+ return l;
+}
/* Vector and matrix arithmetic */
-dmnsn_vector dmnsn_vector_add(dmnsn_vector lhs, dmnsn_vector rhs);
-dmnsn_vector dmnsn_vector_sub(dmnsn_vector lhs, dmnsn_vector rhs);
-dmnsn_vector dmnsn_vector_mul(double lhs, dmnsn_vector rhs);
-dmnsn_vector dmnsn_vector_div(dmnsn_vector lhs, double rhs);
-
-double dmnsn_vector_dot(dmnsn_vector lhs, dmnsn_vector rhs);
-dmnsn_vector dmnsn_vector_cross(dmnsn_vector lhs, dmnsn_vector rhs);
-
-double dmnsn_vector_norm(dmnsn_vector n);
-dmnsn_vector dmnsn_vector_normalize(dmnsn_vector n);
+DMNSN_INLINE dmnsn_vector
+dmnsn_vector_add(dmnsn_vector lhs, dmnsn_vector rhs)
+{
+ dmnsn_vector v = { lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z };
+ return v;
+}
+
+DMNSN_INLINE dmnsn_vector
+dmnsn_vector_sub(dmnsn_vector lhs, dmnsn_vector rhs)
+{
+ dmnsn_vector v = { lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z };
+ return v;
+}
+
+DMNSN_INLINE dmnsn_vector
+dmnsn_vector_mul(double lhs, dmnsn_vector rhs)
+{
+ dmnsn_vector v = { lhs*rhs.x, lhs*rhs.y, lhs*rhs.z };
+ return v;
+}
+
+DMNSN_INLINE dmnsn_vector
+dmnsn_vector_div(dmnsn_vector lhs, double rhs)
+{
+ dmnsn_vector v = { lhs.x/rhs, lhs.y/rhs, lhs.z/rhs };
+ return v;
+}
+
+DMNSN_INLINE double
+dmnsn_vector_dot(dmnsn_vector lhs, dmnsn_vector rhs)
+{
+ return lhs.x*rhs.x + lhs.y*rhs.y + lhs.z*rhs.z;
+}
+
+DMNSN_INLINE dmnsn_vector
+dmnsn_vector_cross(dmnsn_vector lhs, dmnsn_vector rhs)
+{
+ dmnsn_vector v = { lhs.y*rhs.z - lhs.z*rhs.y,
+ lhs.z*rhs.x - lhs.x*rhs.z,
+ lhs.x*rhs.y - lhs.y*rhs.x };
+ return v;
+}
+
+DMNSN_INLINE double
+dmnsn_vector_norm(dmnsn_vector n)
+{
+ return sqrt(dmnsn_vector_dot(n, n));
+}
+
+DMNSN_INLINE dmnsn_vector
+dmnsn_vector_normalize(dmnsn_vector n)
+{
+ return dmnsn_vector_div(n, dmnsn_vector_norm(n));
+}
dmnsn_matrix dmnsn_matrix_inverse(dmnsn_matrix A);
dmnsn_matrix dmnsn_matrix_mul(dmnsn_matrix lhs, dmnsn_matrix rhs);
@@ -73,7 +137,12 @@ dmnsn_vector dmnsn_matrix_vector_mul(dmnsn_matrix lhs, dmnsn_vector rhs);
dmnsn_line dmnsn_matrix_line_mul(dmnsn_matrix lhs, dmnsn_line rhs);
/* A point on a line, defined by x0 + t*n */
-dmnsn_vector dmnsn_line_point(dmnsn_line l, double t);
+DMNSN_INLINE dmnsn_vector
+dmnsn_line_point(dmnsn_line l, double t)
+{
+ return dmnsn_vector_add(l.x0, dmnsn_vector_mul(t, l.n));
+}
+
/* Solve for the t value such that x0 + t*n = x */
double dmnsn_line_index(dmnsn_line l, dmnsn_vector x);
diff --git a/libdimension/geometry.c b/libdimension/geometry.c
index 8008224..01345cf 100644
--- a/libdimension/geometry.c
+++ b/libdimension/geometry.c
@@ -21,28 +21,6 @@
#include "dimension.h"
#include <math.h>
-/* Construct a vector from x, y, and z. Just for convienence. */
-dmnsn_vector
-dmnsn_vector_construct(double x, double y, double z)
-{
- dmnsn_vector v = { .x = x, .y = y, .z = z };
- return v;
-}
-
-/* Construct a matrix. */
-dmnsn_matrix
-dmnsn_matrix_construct(double a0, double a1, double a2, double a3,
- double b0, double b1, double b2, double b3,
- double c0, double c1, double c2, double c3,
- double d0, double d1, double d2, double d3)
-{
- dmnsn_matrix m = { { { a0, a1, a2, a3 },
- { b0, b1, b2, b3 },
- { c0, c1, c2, c3 },
- { d0, d1, d2, d3 } } };
- return m;
-}
-
/* Identity matrix */
dmnsn_matrix
dmnsn_identity_matrix()
@@ -104,89 +82,6 @@ dmnsn_rotation_matrix(dmnsn_vector theta)
);
}
-/* Construct a line */
-dmnsn_line
-dmnsn_line_construct(dmnsn_vector x0, dmnsn_vector n)
-{
- dmnsn_line l = { .x0 = x0, .n = n };
- return l;
-}
-
-/* Add two vectors */
-dmnsn_vector
-dmnsn_vector_add(dmnsn_vector lhs, dmnsn_vector rhs)
-{
- /* 3 additions */
- dmnsn_vector v = { .x = lhs.x + rhs.x,
- .y = lhs.y + rhs.y,
- .z = lhs.z + rhs.z };
- return v;
-}
-
-/* Subtract two vectors */
-dmnsn_vector
-dmnsn_vector_sub(dmnsn_vector lhs, dmnsn_vector rhs)
-{
- /* 3 additions */
- dmnsn_vector v = { .x = lhs.x - rhs.x,
- .y = lhs.y - rhs.y,
- .z = lhs.z - rhs.z };
- return v;
-}
-
-/* Multiply a vector by a scalar */
-dmnsn_vector
-dmnsn_vector_mul(double lhs, dmnsn_vector rhs)
-{
- /* 3 multiplications */
- dmnsn_vector v = { .x = lhs*rhs.x, .y = lhs*rhs.y, .z = lhs*rhs.z };
- return v;
-}
-
-/* Divide a vector by a scalar */
-dmnsn_vector
-dmnsn_vector_div(dmnsn_vector lhs, double rhs)
-{
- /* 3 divisions */
- dmnsn_vector v = { .x = lhs.x/rhs, .y = lhs.y/rhs, .z = lhs.z/rhs };
- return v;
-}
-
-/* Dot product */
-double
-dmnsn_vector_dot(dmnsn_vector lhs, dmnsn_vector rhs)
-{
- /* 3 multiplications, 2 additions */
- return lhs.x*rhs.x + lhs.y*rhs.y + lhs.z*rhs.z;
-}
-
-/* Cross product */
-dmnsn_vector
-dmnsn_vector_cross(dmnsn_vector lhs, dmnsn_vector rhs)
-{
- /* 6 multiplications, 3 additions */
- dmnsn_vector v = { .x = lhs.y*rhs.z - lhs.z*rhs.y,
- .y = lhs.z*rhs.x - lhs.x*rhs.z,
- .z = lhs.x*rhs.y - lhs.y*rhs.x };
- return v;
-}
-
-/* Length of vector */
-double
-dmnsn_vector_norm(dmnsn_vector n)
-{
- /* 1 sqrt, 3 multiplications, 2 additions */
- return sqrt(n.x*n.x + n.y*n.y + n.z*n.z);
-}
-
-/* Normalized vector */
-dmnsn_vector
-dmnsn_vector_normalize(dmnsn_vector n)
-{
- /* 1 sqrt, 3 divisions, 3 multiplications, 2 additions */
- return dmnsn_vector_div(n, dmnsn_vector_norm(n));
-}
-
/* Matrix inversion helper functions */
typedef struct { double n[2][2]; } dmnsn_matrix2;
@@ -455,14 +350,6 @@ dmnsn_matrix_line_mul(dmnsn_matrix lhs, dmnsn_line rhs)
return l;
}
-/* A point on a line, l. Returns l.x0 + t*l.n */
-dmnsn_vector
-dmnsn_line_point(dmnsn_line l, double t)
-{
- /* 3 multiplications, 3 additions */
- return dmnsn_vector_add(l.x0, dmnsn_vector_mul(t, l.n));
-}
-
/* Solve for the t value such that x0 + t*n = x */
double
dmnsn_line_index(dmnsn_line l, dmnsn_vector x)
diff --git a/libdimension/inlines.c b/libdimension/inlines.c
new file mode 100644
index 0000000..a03d08f
--- /dev/null
+++ b/libdimension/inlines.c
@@ -0,0 +1,36 @@
+/*************************************************************************
+ * Copyright (C) 2008 Tavian Barnes <tavianator@gmail.com> *
+ * *
+ * This file is part of The Dimension Library. *
+ * *
+ * The Dimension Library is free software; you can redistribute it and/ *
+ * or modify it under the terms of the GNU Lesser General Public License *
+ * as published by the Free Software Foundation; either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * The Dimension Library is distributed in the hope that it will be *
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty *
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this program. If not, see *
+ * <http://www.gnu.org/licenses/>. *
+ *************************************************************************/
+
+#ifdef __cplusplus
+ /* C++ inline semantics */
+ #define DMNSN_INLINE inline
+#elif (__STDC_VERSION__ >= 199901L)
+ /* C99 inline semantics */
+ #define DMNSN_INLINE
+#elif defined(__GNUC__)
+ /* GCC inline semantics */
+ #define DMNSN_INLINE inline
+#else
+ /* Unknown C - mark functions static and hope the compiler is smart enough
+ to inline them */
+ #define DMNSN_INLINE static
+#endif
+
+#include "dimension.h"