
#ifndef __fvec_c1_h__
#define __fvec_c1_h__

#ifndef _MATH_H
#include <math.h>
#endif

#define FVEC_WIDTH 1
#define FVEC_WIDTH_SHIFT 0
typedef float fvec;

inline fvec fv_neg( fvec a )   { return -a; }
inline fvec fv_abs( fvec a )   { return fabs(a); }

inline fvec fv_add( fvec a, fvec b )   { return a + b; }
inline fvec fv_sub( fvec a, fvec b )   { return a - b; }
inline fvec fv_mul( fvec a, fvec b )   { return a * b; }

inline fvec fv_muladd( fvec a, fvec b, fvec c )   { return a + (b * c); }
inline fvec fv_mulsub( fvec a, fvec b, fvec c )   { return a - (b * c); }

inline fvec fv_recip_fast( fvec a )   { return 1.0f / a; }
inline fvec fv_recip_precise( fvec a )   { return 1.0f / a; }
inline fvec fv_rsqrt_fast( fvec a )   { return 1.0f / sqrtf( a ); }
inline fvec fv_rsqrt_precise( fvec a )   { return 1.0f / sqrtf( a ); }

inline fvec fv_clamp_pos( fvec a )   { return 0.5f * (a + fabsf(a)); }
inline fvec fv_clamp_neg( fvec a )   { return 0.5f * (a - fabsf(a)); }

inline fvec fv_clamp_max( fvec a, fvec max )   { float b = max - a; return max - 0.5f * (b + fabsf(b)); }
inline fvec fv_clamp_min( fvec a, fvec min )   { float b = a - min; return min + 0.5f * (b + fabsf(b)); }

inline fvec fv_clamp_pos_max( fvec a, fvec max )   { float b = max - a; float c = max - 0.5f * (b + fabsf(b)); return 0.5f * (c + fabsf(c)); }
inline fvec fv_clamp_min_neg( fvec a, fvec min )   { float b = a - min; float c = min + 0.5f * (b + fabsf(b)); return 0.5f * (c - fabsf(c)); }

inline fvec fv_clamp_min_max( fvec a, fvec min, fvec max )   { float b = max - a; float c = max - 0.5f * (b + fabsf(b)); float d = c - min; return min + 0.5f * (d + fabsf(d)); }

inline void fv_merge4_frommem( fvec &a, fvec &b, fvec &c, fvec &d, const float *in )   { a = in[0]; b = in[1]; c = in[2]; d = in[3]; }
inline void fv_merge4_tomem( float *out, fvec a, fvec b, fvec c, fvec d )   { out[0] = a; out[1] = b; out[2] = c; out[3] = d; }

inline void fv_merge3pad_frommem( fvec &a, fvec &b, fvec &c, const float *in )   { a = in[0]; b = in[1]; c = in[2]; }
inline void fv_merge3pad_tomem( float *out, fvec a, fvec b, fvec c )   { out[0] = a; out[1] = b; out[2] = c; }

inline void fv_merge2_frommem( fvec &a, fvec &b, const float *in )   { a = in[0]; b = in[1]; }
inline void fv_merge2_tomem( float *out, fvec a, fvec b )   { out[0] = a; out[1] = b; }

#define fv_zero (0.0f)
#define fv_half (0.5f)
#define fv_one (1.0f)
#define fv_two (2.0f)
#define fv_constf(f) (f)
#define fv_loadf(f) (f)

#endif

