Blob Blame Raw
#ifndef COMMON_H
#define COMMON_H


#include <cmath>
#include <cstdlib>
#include <algorithm>

#include <glibmm/refptr.h>


typedef float ColorReal;
typedef double Real;
typedef int Int;
typedef unsigned int UInt;
typedef long long int LongInt;
typedef unsigned long long int ULongInt;

using Glib::RefPtr;


const Real real_precision = 1e-10;


class Shared {
private:
	int ref_count;
public:
	Shared(): ref_count(1) { }
	Shared(const Shared&): ref_count(1) { }
	virtual ~Shared() { };
	
	inline Shared& operator=(const Shared&) { return *this; }
	inline void reference() {
		++ref_count;
	}
	inline void unreference() {
		if (--ref_count <= 0)
			delete this;
	}
};


class Color {
public:
	typedef ColorReal Channel;
	union {
		struct { Channel channels[4]; };
		struct { Channel r, g, b, a; };
	};
	
	inline explicit Color(Channel r = 0.0, Channel g = 0.0, Channel b = 0.0, Channel a = 0.0):
		r(r), g(g), b(b), a(a) { }
};


inline bool real_less(const Real &a, const Real &b)
	{ return a < b - real_precision; }
inline bool real_greater(const Real &a, const Real &b)
	{ return real_less(b, a); }
inline bool real_less_or_equal(const Real &a, const Real &b)
	{ return !real_less(b, a); }
inline bool real_greater_or_equal(const Real &a, const Real &b)
	{ return !real_less(a, b); }
inline bool real_equal(const Real &a, const Real &b)
	{ return !real_less(a, b) && !real_less(b, a); }
inline bool real_not_equal(const Real &a, const Real &b)
	{ return real_less(a, b) || real_less(b, a); }

	
inline int clz(const Int &x)
	{ return x ? __builtin_clz(x) : 32; }
inline int clz(const UInt &x)
	{ return x ? __builtin_clz(x) : 32; }
inline int clz(const LongInt &x)
	{ return x ? __builtin_clzll(x) : 64; }
inline int clz(const ULongInt &x)
	{ return x ? __builtin_clzll(x) : 64; }


inline Real clamp(Real x, Real min, Real max)
	{ return std::max(min, std::min(max, x)); }
inline int iclamp(int x, int min, int max)
	{ return std::max(min, std::min(max, x)); }
	
inline Real flip_clamp(Real x) {
	x -= floor(0.5*x)*2.0;
	return 1.0 - fabs(1.0 - x);
};

#endif