<commit_before>#pragma once
#include <cmath>
#include <cstddef>
#include <m7/m/vec_generic_base.H>

namespace m7 {
namespace m {

template <typename T, size_t N>
struct VecBaseData {
	/// Underlying scalar type.
	using ValueT = T;

	/// Number of elements in the vector.
	static constexpr auto kNumElements = N;
	/// Underlying array of scalars.
	T raw[N] = {};
};

template <typename T>
struct VecBaseData<T, 1> {
	/// Underlying scalar type.
	using ValueT = T;
	/// Number of elements in the vector.
	static constexpr auto kNumElements = 1;
	union {
		/// Underlying array of scalars.
		T raw[1] = {};
		T x;  ///< The 1st element.
	};
};

template <typename T>
struct VecBaseData<T, 2> {
	/// Underlying scalar type.
	using ValueT = T;
	/// Number of elements in the vector.
	static constexpr auto kNumElements = 2;
	union {
		/// Underlying array of scalars.
		T raw[2] = {};
		struct {
			T x;  ///<The 1st element.
			T y;  ///<The 2nd element.
		};
	};
};

template <typename T>
struct VecBaseData<T, 3> {
	/// Underlying scalar type.
	using ValueT = T;
	/// Number of elements in the vector.
	static constexpr auto kNumElements = 3;
	union {
		/// Underlying array of scalars.
		T raw[3] = {};
		struct {
			T x;  ///<The 1st element.
			T y;  ///<The 2nd element.
			T z;  ///<The 3rd element.
		};
	};
};

template <typename T>
struct VecBaseData<T, 4> {
	/// Underlying scalar type.
	using ValueT = T;
	/// Number of elements in the vector.
	static constexpr auto kNumElements = 4;

	union {
		/// Underlying array of scalars.
		T raw[4] = {};
		struct {
			T x;  ///<The 1st element.
			T y;  ///<The 2nd element.
			T z;  ///<The 3rd element.
			T w;  ///<The 4th element.
		};
	};
};

/// Implementation base class for Vec<T,N>.
template <typename T, size_t N>
using VecBase = VecGenericBase<VecBaseData<T, N>>;

/// Linear algebra vector type.
template <typename T, size_t N>
struct Vec : public VecBase<T, N> {};

template <typename T>
using Vec1 = Vec<T, 1>;
template <typename T>
using Vec2 = Vec<T, 2>;
template <typename T>
using Vec3 = Vec<T, 3>;
template <typename T>
using Vec4 = Vec<T, 4>;

using Vec1f = Vec<float, 1>;
using Vec2f = Vec<float, 2>;
using Vec3f = Vec<float, 3>;
using Vec4f = Vec<float, 4>;
using Vec1d = Vec<double, 1>;
using Vec2d = Vec<double, 2>;
using Vec3d = Vec<double, 3>;
using Vec4d = Vec<double, 4>;

using Vec1i = Vec<int, 1>;
using Vec2i = Vec<int, 2>;
using Vec3i = Vec<int, 3>;
using Vec4i = Vec<int, 4>;
using Vec1ui = Vec<unsigned int, 1>;
using Vec2ui = Vec<unsigned int, 2>;
using Vec3ui = Vec<unsigned int, 3>;
using Vec4ui = Vec<unsigned int, 4>;

using Vec1i8 = Vec<int8_t, 1>;
using Vec2i8 = Vec<int8_t, 2>;
using Vec3i8 = Vec<int8_t, 3>;
using Vec4i8 = Vec<int8_t, 4>;
using Vec1ui8 = Vec<uint8_t, 1>;
using Vec2ui8 = Vec<uint8_t, 2>;
using Vec3ui8 = Vec<uint8_t, 3>;
using Vec4ui8 = Vec<uint8_t, 4>;

using Vec1i16 = Vec<int16_t, 1>;
using Vec2i16 = Vec<int16_t, 2>;
using Vec3i16 = Vec<int16_t, 3>;
using Vec4i16 = Vec<int16_t, 4>;
using Vec1ui16 = Vec<uint16_t, 1>;
using Vec2ui16 = Vec<uint16_t, 2>;
using Vec3ui16 = Vec<uint16_t, 3>;
using Vec4ui16 = Vec<uint16_t, 4>;

using Vec1i32 = Vec<int32_t, 1>;
using Vec2i32 = Vec<int32_t, 2>;
using Vec3i32 = Vec<int32_t, 3>;
using Vec4i32 = Vec<int32_t, 4>;
using Vec1ui32 = Vec<uint32_t, 1>;
using Vec2ui32 = Vec<uint32_t, 2>;
using Vec3ui32 = Vec<uint32_t, 3>;
using Vec4ui32 = Vec<uint32_t, 4>;

using Vec1i64 = Vec<int64_t, 1>;
using Vec2i64 = Vec<int64_t, 2>;
using Vec3i64 = Vec<int64_t, 3>;
using Vec4i64 = Vec<int64_t, 4>;
using Vec1ui64 = Vec<uint64_t, 1>;
using Vec2ui64 = Vec<uint64_t, 2>;
using Vec3ui64 = Vec<uint64_t, 3>;
using Vec4ui64 = Vec<uint64_t, 4>;

/// Multiply scalar by vector
/// \relates Vec
template <typename T, size_t N>
inline Vec<T, N> operator*(typename Vec<T, N>::ValueT s, Vec<T, N> v) {
	Vec<T, N> res;
	for (size_t i = 0; i < N; ++i) {
		res[i] = s * v[i];
	}
	return res;
}

/// Multiply scalar by vector
/// \relates Vec
template <typename T, size_t N>
inline Vec<T, N> operator*(Vec<T, N> v, typename Vec<T, N>::ValueT s) {
	Vec<T, N> res;
	for (size_t i = 0; i < N; ++i) {
		res[i] = v[i] * s;
	}
	return res;
}

/// Return the dot product of 2 vectors.
/// \relates Vec
template <typename T, size_t N>
inline T dot(Vec<T, N> a, Vec<T, N> b) {
	T s = 0;
	for (size_t i = 0; i < N; ++i) {
		s += a[i] * b[i];
	}
	return s;
}

/// Return the Cross Product of 2 3d vectors.
/// \relates Vec
template <typename T>
Vec3<T> cross(Vec3<T>& l, Vec3<T>& r) {
	Vec<T, 3> res;
	res[0] = l[1] * r[2] - l[2] * r[1];
	res[1] = l[2] * r[0] - l[0] * r[2];
	res[2] = l[0] * r[1] - l[1] * r[0];
	return res;
}

/// Return vector triple product.
/// \relates Vec
template <typename T>
T tripleProduct(const Vec3<T>& a, const Vec3<T>& b, const Vec3<T>& c) {
	T res;
	res = a[0] * (b[1] * c[2] - b[2] * c[1]);
	res += a[1] * (b[2] * c[0] - b[0] * c[2]);
	res += a[2] * (b[0] * c[1] - b[1] * c[0]);
	return res;
}

/// Return the length squared of vector.
/// \remark More efficient than len().
/// \relates Vec
template <typename T, size_t N>
inline T len2(Vec<T, N> x) {
	return dot(x, x);
}

/// Return the length of vector.
/// \relates Vec
template <typename T, size_t N>
inline T len(Vec<T, N> x) {
	return std::sqrt(len2(x));
}

/// Return normalized vector.
/// \relates Vec
template <typename T, size_t N>
inline T norm(Vec<T, N> x) {
	auto l = length(x);
	Vec<T, N> n;
	for (size_t i = 0; i < N; ++i) {
		n[i] = x[i] / l;
	}
	return n;
}

/// Return distance squared.
/// \remark More efficient than dist().
/// \relates Vec
template <typename T, size_t N>
inline T dist2(Vec<T, N> a, Vec<T, N> b) {
	T d = 0;
	for (size_t i = 0; i < N; ++i) {
		auto x = a[i] - b[i];
		d += x * x;
	}
	return d;
}

/// Return distance.
/// \relates Vec
template <typename T, size_t N>
inline T dist(Vec<T, N> a, Vec<T, N> b) {
	return std::sqrt(dist2(a, b));
}

/// Return angle between 2 vectors in radians.
/// \relates Vec
template <typename T, size_t N>
T angle(Vec<T, N> l, Vec<T, N> r) {
	return std::acos(dot(l, r) / (len(l) * len(r)));
}

/// Return angle between 2 unit vectors
/// \pre len(l) == 1 && len(r) == 1
/// \remark More efficient than angle().
/// \relates Vec
template <typename T, size_t N>
T angleUnit(Vec<T, N> l, Vec<T, N> r) {
	return std::acos(dot(l, r));
}

/// Return scalar projection of v onto angle (radians).
/// \param[in] angle The angle in radians.
/// \relates Vec
template <typename T, size_t N>
T scalarProject(Vec<T, N> v, typename Vec<T, N>::ValueT angle) {
	return length(v) * cos(angle);
}

/// Return scalar projection of v onto onto.
/// \relates Vec
template <typename T, size_t N>
T scalarProject(Vec<T, N> v, Vec<T, N> onto) {
	return dot(v, onto) / len(onto);
}

/// Return scalar projection of v onto onto.
/// \pre length(v) == 1 && length(onto) == 1.
/// \remark More efficient than scalarProject().
/// \relates Vec
template <typename T, size_t N>
T scalarProjectUnit(Vec<T, N> v, Vec<T, N> onto) {
	return dor(v, onto);
}

/// Return vector projection of v onto onto.
/// \relates Vec
template <typename T, size_t N>
Vec<T, N> vectorProject(Vec<T, N> v, Vec<T, N> onto) {
	return (dot(v, onto) / len2(onto)) * onto;
}

/// Return vector projection of v onto onto.
/// \pre len(v) == 1 && len(onto) == 1.
/// \remark More efficient than vectorProject().
/// \relates Vec
template <typename T, size_t N>
Vec<T, N> vectorProjectUnit(Vec<T, N> v, Vec<T, N> onto) {
	return dot(v, onto) * onto;
}

/// Return vector projection of v onto onto.
/// \relates Vec
template <typename T, size_t N>
Vec<T, N> vectorReject(Vec<T, N> v, Vec<T, N> onto) {
	return v - vectorProject(v, onto);
}

/// Return vector projection of v onto onto.
/// \pre len(v) == 1 && len(onto) == 1.
/// \remark More efficient than vectorReject().
/// \relates Vec
template <typename T, size_t N>
Vec<T, N> vectorRejectUnit(Vec<T, N> v, Vec<T, N> onto) {
	return v - vectorProjectUnit(v, onto);
}

/// Return
}  // namespace m
}  // namespace m7
<commit_msg>Improvements to vec.<commit_after>#pragma once
#include <cmath>
#include <cstddef>
#include <iterator>
#include <m7/assert.H>
#include <m7/m/cwise.H>

namespace m7 {
namespace m {

template <typename T, size_t N>
struct Vec;

template <typename T>
using Vec1 = Vec<T, 1>;
template <typename T>
using Vec2 = Vec<T, 2>;
template <typename T>
using Vec3 = Vec<T, 3>;
template <typename T>
using Vec4 = Vec<T, 4>;

using Vec1f = Vec<float, 1>;
using Vec2f = Vec<float, 2>;
using Vec3f = Vec<float, 3>;
using Vec4f = Vec<float, 4>;
using Vec1d = Vec<double, 1>;
using Vec2d = Vec<double, 2>;
using Vec3d = Vec<double, 3>;
using Vec4d = Vec<double, 4>;

using Vec1i = Vec<int, 1>;
using Vec2i = Vec<int, 2>;
using Vec3i = Vec<int, 3>;
using Vec4i = Vec<int, 4>;
using Vec1ui = Vec<unsigned int, 1>;
using Vec2ui = Vec<unsigned int, 2>;
using Vec3ui = Vec<unsigned int, 3>;
using Vec4ui = Vec<unsigned int, 4>;

using Vec1i8 = Vec<int8_t, 1>;
using Vec2i8 = Vec<int8_t, 2>;
using Vec3i8 = Vec<int8_t, 3>;
using Vec4i8 = Vec<int8_t, 4>;
using Vec1ui8 = Vec<uint8_t, 1>;
using Vec2ui8 = Vec<uint8_t, 2>;
using Vec3ui8 = Vec<uint8_t, 3>;
using Vec4ui8 = Vec<uint8_t, 4>;

using Vec1i16 = Vec<int16_t, 1>;
using Vec2i16 = Vec<int16_t, 2>;
using Vec3i16 = Vec<int16_t, 3>;
using Vec4i16 = Vec<int16_t, 4>;
using Vec1ui16 = Vec<uint16_t, 1>;
using Vec2ui16 = Vec<uint16_t, 2>;
using Vec3ui16 = Vec<uint16_t, 3>;
using Vec4ui16 = Vec<uint16_t, 4>;

using Vec1i32 = Vec<int32_t, 1>;
using Vec2i32 = Vec<int32_t, 2>;
using Vec3i32 = Vec<int32_t, 3>;
using Vec4i32 = Vec<int32_t, 4>;
using Vec1ui32 = Vec<uint32_t, 1>;
using Vec2ui32 = Vec<uint32_t, 2>;
using Vec3ui32 = Vec<uint32_t, 3>;
using Vec4ui32 = Vec<uint32_t, 4>;

using Vec1i64 = Vec<int64_t, 1>;
using Vec2i64 = Vec<int64_t, 2>;
using Vec3i64 = Vec<int64_t, 3>;
using Vec4i64 = Vec<int64_t, 4>;
using Vec1ui64 = Vec<uint64_t, 1>;
using Vec2ui64 = Vec<uint64_t, 2>;
using Vec3ui64 = Vec<uint64_t, 3>;
using Vec4ui64 = Vec<uint64_t, 4>;

template <typename T, size_t N>
struct VecBaseData {
	VecBaseData() : raw_elems{} {}
	union {
		/// Underlying storage as a flat array.
		std::array<T, N> raw_elems;
		Vec4<T> xyzw;  ///< 1st, 2nd, 3rd, and 4th elements.
		struct {
			Vec3<T> xyz;  ///< 1st, 2nd, and 3rd elements.
			T w;	  ///< 4th element.
		};
		struct {
			Vec2<T> xy;  ///< 1st and 2nd elements.
			union {
				T z;	 ///< 3rd element.
				Vec2<T> zw;  ///< 3rd and 4th elements.
			};
		};
		struct {
			T x;  ///< 1st element.
			union {
				T y;	  ///< 2nd element.
				Vec2<T> yz;   ///< 2nd and 3rd elements.
				Vec3<T> yzw;  ///< 2nd, 3rd, and 4th elements.
			};
		};
	};
};

template <typename T>
struct VecBaseData<T, 4> {
	VecBaseData() : raw_elems{} {}
	union {
		/// Underlying storage as a flat array.
		std::array<T, 4> raw_elems = {};
		struct {
			Vec3<T> xyz;  ///< 1st, 2nd, and 3rd elements.
			T w;	  ///< 4th element.
		};
		struct {
			Vec2<T> xy;  ///< 1st and 2nd elements.
			union {
				T z;	 ///< 3rd element.
				Vec2<T> zw;  ///< 3rd and 4th elements.
			};
		};
		struct {
			T x;  ///< 1st element.
			union {
				T y;	  ///< 2nd element.
				Vec2<T> yz;   ///< 2nd and 3rd elements.
				Vec3<T> yzw;  ///< 2nd, 3rd, and 4th elements.
			};
		};
	};
};

template <typename T>
struct VecBaseData<T, 3> {
	VecBaseData() : raw_elems{} {}
	union {
		/// Underlying storage as a flat array.
		std::array<T, 3> raw_elems = {};
		struct {
			Vec2<T> xy;  ///< 1st and 2nd elements.
			T z;	 ///< 3rd element.
		};
		struct {
			T x;  ///< 1st element.
			union {
				T y;	 ///< 2nd element.
				Vec2<T> yz;  ///< 2nd and 3rd elements.
			};
		};
	};
};

template <typename T>
struct VecBaseData<T, 2> {
	VecBaseData() : raw_elems{} {}
	union {
		/// Underlying storage as a flat array.
		std::array<T, 2> raw_elems = {};
		struct {
			T x;  ///< 1st element.
			T y;  ///< 2nd element.
		};
	};
};

template <typename T>
struct VecBaseData<T, 1> {
	VecBaseData() : raw_elems{} {}
	union {
		/// Underlying storage as a flat array.
		std::array<T, 1> raw_elems = {};
		T x;  ///< 1st element.
	};
};

/// Linear algebra vector type.
template <typename T, size_t N>
struct Vec : public VecBaseData<T, N> {
	/// The underlying scalar type T.
	using ScalarT = T;

	/// The type representing a vector of T.
	using VecT = Vec<T, N>;

	/// The number of underlying scalar elements.
	static constexpr auto kNumElements = N;

	/// Iterator type.
	using IteratorT = ScalarT*;
	/// Const Iterator type.
	using ConstIteratorT = const ScalarT*;
	/// Reverse Iterator type.
	using ReverseIteratorT = std::reverse_iterator<IteratorT>;
	/// Const Reverse Iterator type.
	using ConstReverseIteratorT = std::reverse_iterator<ConstIteratorT>;

	/// Default Zero initialize..
	constexpr Vec() = default;

	/// Initialize all elements with scalar s.
	constexpr explicit Vec(ScalarT s) { fill(s); }

	/// Initialize each element individually using the given array.
	constexpr explicit Vec(const std::array<T, kNumElements>& scalars) {
		this->raw_elems = scalars;
	}

	/// Return a pointer to the first column.
	ScalarT* data() { return this->raw_elems.data(); }
	/// Return a pointer to the first column.
	const ScalarT* data() const { return this->raw_elems.data(); }

	/// Return a reference to the i'th column.
	/// \pre i < size()
	ScalarT& operator[](size_t i) {
		M7_ASSERT(i < size());
		return this->raw_elems[i];
	}

	/// Return a reference to the i'th column.
	/// \pre i < size()
	const ScalarT& operator[](size_t i) const {
		M7_ASSERT(i < size());
		return this->raw_elems[i];
	}

	/// The number of elements.
	constexpr static size_t sizeElements() { return kNumElements; }
	/// The number of elements.
	constexpr static size_t size() { return sizeElements(); }

	/// Iterator to the beginning.
	IteratorT begin() { return data(); }
	/// Iterator to the end.
	IteratorT end() { return data() + size(); }

	/// Iterator to the beginning.
	ConstIteratorT begin() const { return data(); }
	/// Iterator to the end.
	ConstIteratorT end() const { return data() + size(); }

	/// Iterator to the beginning.
	ConstIteratorT cbegin() const { return begin(); }
	/// Iterator to the end.
	ConstIteratorT cend() const { return end(); }

	/// Reverse Iterator to the end.
	ReverseIteratorT rbegin() { return ReverseIteratorT(end()); }
	/// Reverse Iterator to the beginning.
	ReverseIteratorT rend() { return ReverseIteratorT(begin()); }

	/// Reverse Iterator to the end.
	ConstReverseIteratorT rbegin() const {
		return ConstReverseIteratorT(end());
	}
	/// Reverse Iterator to the beginning.
	ConstReverseIteratorT rend() const {
		return ConstReverseIteratorT(begin());
	}

	/// Reverse Iterator to the end.
	ConstReverseIteratorT crbegin() const { return rbegin(); }
	/// Reverse Iterator to the beginning.
	ConstReverseIteratorT crend() const { return rend(); }

	/// Returns an array reference which references the scalar
	/// elements of this.
	std::array<ScalarT, kNumElements>& elems() { return this->raw_elems; }
	/// Returns an array reference which references the scalar
	/// elements of this.
	const std::array<ScalarT, kNumElements>& elems() const {
		return this->raw_elems;
	}

	/// Return a reference to the i'th element.
	/// \pre i < sizeElements()
	ScalarT& elem(size_t i) {
		M7_ASSERT(i < sizeElements());
		return this->elems()[i];
	}

	/// Return a reference to the i'th element.
	/// \pre i < sizeElements()
	const ScalarT& elem(size_t i) const {
		M7_ASSERT(i < sizeElements());
		return this->elems()[i];
	}

	/// Set all elements to s.
	constexpr void fill(ScalarT s) {
		for (auto& e : this->raw_elems) e = s;
	}
};

/// Add 2 vectors
/// \relates Vec
template <typename T, size_t N>
inline Vec<T, N> operator+(const Vec<T, N>& x, const Vec<T, N>& y) {
	return cw_add(x, y);
}

/// Subtract 2 vectors
/// \relates Vec
template <typename T, size_t N>
inline Vec<T, N> operator-(const Vec<T, N>& x, const Vec<T, N>& y) {
	return cw_sub(x, y);
}

/// Multiply scalar by vector
/// \relates Vec
template <typename T, size_t N>
inline Vec<T, N> operator*(typename Vec<T, N>::ScalarT s, Vec<T, N> v) {
	return cw_mul(s, v);
}

/// Multiply scalar by vector
/// \relates Vec
template <typename T, size_t N>
inline Vec<T, N> operator*(Vec<T, N> v, typename Vec<T, N>::ScalarT s) {
	cw_mul(v, s);
}

/// Return the dot product of 2 vectors.
/// \relates Vec
template <typename T, size_t N>
inline T dot(Vec<T, N> a, Vec<T, N> b) {
	T s = 0;
	for (size_t i = 0; i < N; ++i) {
		s += a[i] * b[i];
	}
	return s;
}

/// Return the Cross Product of 2 3d vectors.
/// \relates Vec
template <typename T>
Vec3<T> cross(Vec3<T>& l, Vec3<T>& r) {
	Vec<T, 3> res;
	res[0] = l[1] * r[2] - l[2] * r[1];
	res[1] = l[2] * r[0] - l[0] * r[2];
	res[2] = l[0] * r[1] - l[1] * r[0];
	return res;
}

/// Return vector triple product.
/// \relates Vec
template <typename T>
T tripleProduct(const Vec3<T>& a, const Vec3<T>& b, const Vec3<T>& c) {
	T res;
	res = a[0] * (b[1] * c[2] - b[2] * c[1]);
	res += a[1] * (b[2] * c[0] - b[0] * c[2]);
	res += a[2] * (b[0] * c[1] - b[1] * c[0]);
	return res;
}

/// Return the length squared of vector.
/// \remark More efficient than len().
/// \relates Vec
template <typename T, size_t N>
inline T len2(Vec<T, N> x) {
	return dot(x, x);
}

/// Return the length of vector.
/// \relates Vec
template <typename T, size_t N>
inline T len(Vec<T, N> x) {
	return std::sqrt(len2(x));
}

/// Return normalized vector.
/// \relates Vec
template <typename T, size_t N>
inline T norm(Vec<T, N> x) {
	auto l = length(x);
	Vec<T, N> n;
	for (size_t i = 0; i < N; ++i) {
		n[i] = x[i] / l;
	}
	return n;
}

/// Return distance squared.
/// \remark More efficient than dist().
/// \relates Vec
template <typename T, size_t N>
inline T dist2(Vec<T, N> a, Vec<T, N> b) {
	T d = 0;
	for (size_t i = 0; i < N; ++i) {
		auto x = a[i] - b[i];
		d += x * x;
	}
	return d;
}

/// Return distance.
/// \relates Vec
template <typename T, size_t N>
inline T dist(Vec<T, N> a, Vec<T, N> b) {
	return std::sqrt(dist2(a, b));
}

/// Return angle between 2 vectors in radians.
/// \relates Vec
template <typename T, size_t N>
T angle(Vec<T, N> l, Vec<T, N> r) {
	return std::acos(dot(l, r) / (len(l) * len(r)));
}

/// Return angle between 2 unit vectors
/// \pre len(l) == 1 && len(r) == 1
/// \remark More efficient than angle().
/// \relates Vec
template <typename T, size_t N>
T angleUnit(Vec<T, N> l, Vec<T, N> r) {
	return std::acos(dot(l, r));
}

/// Return scalar projection of v onto angle (radians).
/// \param[in] angle The angle in radians.
/// \relates Vec
template <typename T, size_t N>
T scalarProject(Vec<T, N> v, typename Vec<T, N>::ScalarT angle) {
	return length(v) * cos(angle);
}

/// Return scalar projection of v onto onto.
/// \relates Vec
template <typename T, size_t N>
T scalarProject(Vec<T, N> v, Vec<T, N> onto) {
	return dot(v, onto) / len(onto);
}

/// Return scalar projection of v onto onto.
/// \pre length(v) == 1 && length(onto) == 1.
/// \remark More efficient than scalarProject().
/// \relates Vec
template <typename T, size_t N>
T scalarProjectUnit(Vec<T, N> v, Vec<T, N> onto) {
	return dor(v, onto);
}

/// Return vector projection of v onto onto.
/// \relates Vec
template <typename T, size_t N>
Vec<T, N> vectorProject(Vec<T, N> v, Vec<T, N> onto) {
	return (dot(v, onto) / len2(onto)) * onto;
}

/// Return vector projection of v onto onto.
/// \pre len(v) == 1 && len(onto) == 1.
/// \remark More efficient than vectorProject().
/// \relates Vec
template <typename T, size_t N>
Vec<T, N> vectorProjectUnit(Vec<T, N> v, Vec<T, N> onto) {
	return dot(v, onto) * onto;
}

/// Return vector projection of v onto onto.
/// \relates Vec
template <typename T, size_t N>
Vec<T, N> vectorReject(Vec<T, N> v, Vec<T, N> onto) {
	return v - vectorProject(v, onto);
}

/// Return vector projection of v onto onto.
/// \pre len(v) == 1 && len(onto) == 1.
/// \remark More efficient than vectorReject().
/// \relates Vec
template <typename T, size_t N>
Vec<T, N> vectorRejectUnit(Vec<T, N> v, Vec<T, N> onto) {
	return v - vectorProjectUnit(v, onto);
}

/// Return
}  // namespace m
}  // namespace m7
<|endoftext|>


<commit_before>#pragma once
/**
	@file
	@brief definition of Op
	@author MITSUNARI Shigeo(@herumi)
	@license modified new BSD license
	http://opensource.org/licenses/BSD-3-Clause
*/
#include <mcl/gmp_util.hpp>
#include <memory.h>

#ifndef MCL_MAX_BIT_SIZE
	#define MCL_MAX_BIT_SIZE 521
#endif
#ifdef __EMSCRIPTEN__
	#define MCL_DONT_USE_XBYAK
	#define MCL_DONT_USE_OPENSSL
#endif
#if !defined(MCL_DONT_USE_XBYAK) && (defined(_WIN64) || defined(__x86_64__)) && (MCL_SIZEOF_UNIT == 8)
	#define MCL_USE_XBYAK
#endif

#define MCL_MAX_HASH_BIT_SIZE 512

#if CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11
#include <random>
#endif

namespace mcl {

/*
	specifies available string format mode for X::setIoMode()
	// for Fp, Fp2, Fp6, Fp12
	default(0) : IoDec
	printable string(zero terminated, variable size)
	IoBin(2) | IoDec(10) | IoHex(16) | IoBinPrefix | IoHexPrefix

	byte string(not zero terminated, fixed size)
	IoArray | IoArrayRaw
	IoArray = IoSerialize

	// for Ec
	affine(0) | IoEcCompY | IoComp
	default : affine

	affine and IoEcCompY are available with ioMode for Fp
	IoSerialize ignores ioMode for Fp

	IoAuto
		dec or hex according to ios_base::fmtflags
	IoBin
		binary number([01]+)
	IoDec
		decimal number
	IoHex
		hexadecimal number([0-9a-fA-F]+)
	IoBinPrefix
		0b + <binary number>
	IoHexPrefix
		0x + <hexadecimal number>
	IoArray
		array of Unit(fixed size = Fp::getByteSize())
	IoArrayRaw
		array of Unit(fixed size = Fp::getByteSize()) without Montgomery convresion

	// for Ec::setIoMode()
	IoEcAffine(default)
	"0" ; infinity
	"1 <x> <y>" ; affine coordinate

	IoEcProj
	"4" <x> <y> <z> ; projective or jacobi coordinate

	IoEcCompY
		1-bit y prepresentation of elliptic curve
		"2 <x>" ; compressed for even y
		"3 <x>" ; compressed for odd y

	IoSerialize(fixed size = Fp::getByteSize())
		use MSB of array of x for 1-bit y for prime p where (p % 8 != 0)
		[0] ; infinity
		<x> ; for even y
		<x>|1 ; for odd y ; |1 means set MSB of x
*/
enum IoMode {
	IoAuto = 0, // dec or hex according to ios_base::fmtflags
	IoBin = 2, // binary number without prefix
	IoDec = 10, // decimal number without prefix
	IoHex = 16, // hexadecimal number without prefix
	IoArray = 32, // array of Unit(fixed size)
	IoArrayRaw = 64, // raw array of Unit without Montgomery conversion
	IoPrefix = 128, // append '0b'(bin) or '0x'(hex)
	IoBinPrefix = IoBin | IoPrefix,
	IoHexPrefix = IoHex | IoPrefix,
	IoEcAffine = 0, // affine coordinate
	IoEcCompY = 256, // 1-bit y representation of elliptic curve
	IoSerialize = 512, // use MBS for 1-bit y
	IoFixedSizeByteSeq = IoSerialize, // obsolete
	IoEcProj = 1024 // projective or jacobi coordinate
};

namespace fp {

const size_t UnitBitSize = sizeof(Unit) * 8;

const size_t maxUnitSize = (MCL_MAX_BIT_SIZE + UnitBitSize - 1) / UnitBitSize;
#define MCL_MAX_UNIT_SIZE ((MCL_MAX_BIT_SIZE + MCL_UNIT_BIT_SIZE - 1) / MCL_UNIT_BIT_SIZE)

struct FpGenerator;
struct Op;

typedef void (*void1u)(Unit*);
typedef void (*void2u)(Unit*, const Unit*);
typedef void (*void2uI)(Unit*, const Unit*, Unit);
typedef void (*void2uIu)(Unit*, const Unit*, Unit, const Unit*);
typedef void (*void2uOp)(Unit*, const Unit*, const Op&);
typedef void (*void3u)(Unit*, const Unit*, const Unit*);
typedef void (*void4u)(Unit*, const Unit*, const Unit*, const Unit*);
typedef int (*int2u)(Unit*, const Unit*);

typedef Unit (*u1uII)(Unit*, Unit, Unit);
typedef Unit (*u3u)(Unit*, const Unit*, const Unit*);

struct Block {
	const Unit *p; // pointer to original FpT.v_
	size_t n;
	Unit v_[maxUnitSize];
};

enum Mode {
	FP_AUTO,
	FP_GMP,
	FP_GMP_MONT,
	FP_LLVM,
	FP_LLVM_MONT,
	FP_XBYAK
};

enum PrimeMode {
	PM_GENERIC = 0,
	PM_NICT_P192,
	PM_NICT_P521
};

struct Op {
	/*
		don't change the layout of rp and p
		asm code assumes &rp + 1 == p
	*/
	Unit rp;
	Unit p[maxUnitSize];
	mpz_class mp;
	uint32_t pmod4;
	mcl::SquareRoot sq;
	FpGenerator *fg;
	Unit half[maxUnitSize]; // (p + 1) / 2
	Unit oneRep[maxUnitSize]; // 1(=inv R if Montgomery)
	/*
		for Montgomery
		one = 1
		R = (1 << (N * sizeof(Unit) * 8)) % p
		R2 = (R * R) % p
		R3 = RR^3
	*/
	Unit one[maxUnitSize];
	Unit R2[maxUnitSize];
	Unit R3[maxUnitSize];
	std::vector<Unit> invTbl;
	size_t N;
	size_t bitSize;
	bool (*fp_isZero)(const Unit*);
	void1u fp_clear;
	void2u fp_copy;
	void2u fp_shr1;
	void3u fp_neg;
	void4u fp_add;
	void4u fp_sub;
	void4u fp_mul;
	void3u fp_sqr;
	void2uOp fp_invOp;
	void2uIu fp_mulUnit; // fpN1_mod + fp_mulUnitPre

	void3u fpDbl_mulPre;
	void2u fpDbl_sqrPre;
	int2u fp_preInv;
	void2uI fp_mulUnitPre; // z[N + 1] = x[N] * y
	void3u fpN1_mod; // y[N] = x[N + 1] % p[N]

	void4u fpDbl_add;
	void4u fpDbl_sub;
	void3u fpDbl_mod;

	u3u fp_addPre; // without modulo p
	u3u fp_subPre; // without modulo p
	u3u fpDbl_addPre;
	u3u fpDbl_subPre;
	/*
		for Fp2 = F[u] / (u^2 + 1)
		x = a + bu
	*/
	int xi_a; // xi = xi_a + u
	void3u fp2_add;
	void3u fp2_sub;
	void3u fp2_mul;
	void4u fp2_mulNF;
	void2u fp2_neg;
	void2u fp2_inv;
	void2u fp2_sqr;
	void2u fp2_mul_xi;
	uint32_t (*hash)(void *out, uint32_t maxOutSize, const void *msg, uint32_t msgSize);

	PrimeMode primeMode;
	bool isFullBit; // true if bitSize % uniSize == 0
	bool isMont; // true if use Montgomery
	bool isFastMod; // true if modulo is fast

	Op()
	{
		clear();
		fg = 0;
	}
	~Op()
	{
		destroyFpGenerator(fg);
	}
	void clear()
	{
		rp = 0;
		memset(p, 0, sizeof(p));
		mp = 0;
		pmod4 = 0;
		sq.clear();
		// fg is not set
		memset(half, 0, sizeof(half));
		memset(oneRep, 0, sizeof(oneRep));
		memset(one, 0, sizeof(one));
		memset(R2, 0, sizeof(R2));
		memset(R3, 0, sizeof(R3));
		invTbl.clear();
		N = 0;
		bitSize = 0;
		fp_isZero = 0;
		fp_clear = 0;
		fp_copy = 0;
		fp_shr1 = 0;
		fp_neg = 0;
		fp_add = 0;
		fp_sub = 0;
		fp_mul = 0;
		fp_sqr = 0;
		fp_invOp = 0;
		fp_mulUnit = 0;

		fpDbl_mulPre = 0;
		fpDbl_sqrPre = 0;
		fp_preInv = 0;
		fp_mulUnitPre = 0;
		fpN1_mod = 0;

		fpDbl_add = 0;
		fpDbl_sub = 0;
		fpDbl_mod = 0;

		fp_addPre = 0;
		fp_subPre = 0;
		fpDbl_addPre = 0;
		fpDbl_subPre = 0;

		xi_a = 0;
		fp2_add = 0;
		fp2_sub = 0;
		fp2_mul = 0;
		fp2_mulNF = 0;
		fp2_neg = 0;
		fp2_inv = 0;
		fp2_sqr = 0;
		fp2_mul_xi = 0;

		primeMode = PM_GENERIC;
		isFullBit = false;
		isMont = false;
		isFastMod = false;
		hash = 0;
	}
	void fromMont(Unit* y, const Unit *x) const
	{
		/*
			M(x, y) = xyR^-1
			y = M(x, 1) = xR^-1
		*/
		fp_mul(y, x, one, p);
	}
	void toMont(Unit* y, const Unit *x) const
	{
		/*
			y = M(x, R2) = xR^2 R^-1 = xR
		*/
		fp_mul(y, x, R2, p);
	}
	void init(const std::string& mstr, size_t maxBitSize, Mode mode, size_t mclMaxBitSize = MCL_MAX_BIT_SIZE);
	void initFp2(int xi_a);
	static FpGenerator* createFpGenerator();
	static void destroyFpGenerator(FpGenerator *fg);
private:
	Op(const Op&);
	void operator=(const Op&);
};

/*
	conevrt string to array according to ioMode,
*/
void strToArray(bool *pIsMinus, Unit *x, size_t xN, const std::string& str, int ioMode);

void arrayToStr(std::string& str, const Unit *x, size_t n, int ioMode);

inline const char* getIoSeparator(int ioMode)
{
	return (ioMode & (IoArray | IoArrayRaw | IoSerialize)) ? "" : "\n";
}

int detectIoMode(int ioMode, const std::ios_base& ios);

inline void dump(const char *s, size_t n)
{
	for (size_t i = 0; i < n; i++) {
		printf("%02x ", (uint8_t)s[i]);
	}
	printf("\n");
}

inline void dump(const std::string& s)
{
	dump(s.c_str(), s.size());
}

} } // mcl::fp
<commit_msg>recover IoSeprator<commit_after>#pragma once
/**
	@file
	@brief definition of Op
	@author MITSUNARI Shigeo(@herumi)
	@license modified new BSD license
	http://opensource.org/licenses/BSD-3-Clause
*/
#include <mcl/gmp_util.hpp>
#include <memory.h>

#ifndef MCL_MAX_BIT_SIZE
	#define MCL_MAX_BIT_SIZE 521
#endif
#ifdef __EMSCRIPTEN__
	#define MCL_DONT_USE_XBYAK
	#define MCL_DONT_USE_OPENSSL
#endif
#if !defined(MCL_DONT_USE_XBYAK) && (defined(_WIN64) || defined(__x86_64__)) && (MCL_SIZEOF_UNIT == 8)
	#define MCL_USE_XBYAK
#endif

#define MCL_MAX_HASH_BIT_SIZE 512

#if CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11
#include <random>
#endif

namespace mcl {

/*
	specifies available string format mode for X::setIoMode()
	// for Fp, Fp2, Fp6, Fp12
	default(0) : IoDec
	printable string(zero terminated, variable size)
	IoBin(2) | IoDec(10) | IoHex(16) | IoBinPrefix | IoHexPrefix

	byte string(not zero terminated, fixed size)
	IoArray | IoArrayRaw
	IoArray = IoSerialize

	// for Ec
	affine(0) | IoEcCompY | IoComp
	default : affine

	affine and IoEcCompY are available with ioMode for Fp
	IoSerialize ignores ioMode for Fp

	IoAuto
		dec or hex according to ios_base::fmtflags
	IoBin
		binary number([01]+)
	IoDec
		decimal number
	IoHex
		hexadecimal number([0-9a-fA-F]+)
	IoBinPrefix
		0b + <binary number>
	IoHexPrefix
		0x + <hexadecimal number>
	IoArray
		array of Unit(fixed size = Fp::getByteSize())
	IoArrayRaw
		array of Unit(fixed size = Fp::getByteSize()) without Montgomery convresion

	// for Ec::setIoMode()
	IoEcAffine(default)
	"0" ; infinity
	"1 <x> <y>" ; affine coordinate

	IoEcProj
	"4" <x> <y> <z> ; projective or jacobi coordinate

	IoEcCompY
		1-bit y prepresentation of elliptic curve
		"2 <x>" ; compressed for even y
		"3 <x>" ; compressed for odd y

	IoSerialize(fixed size = Fp::getByteSize())
		use MSB of array of x for 1-bit y for prime p where (p % 8 != 0)
		[0] ; infinity
		<x> ; for even y
		<x>|1 ; for odd y ; |1 means set MSB of x
*/
enum IoMode {
	IoAuto = 0, // dec or hex according to ios_base::fmtflags
	IoBin = 2, // binary number without prefix
	IoDec = 10, // decimal number without prefix
	IoHex = 16, // hexadecimal number without prefix
	IoArray = 32, // array of Unit(fixed size)
	IoArrayRaw = 64, // raw array of Unit without Montgomery conversion
	IoPrefix = 128, // append '0b'(bin) or '0x'(hex)
	IoBinPrefix = IoBin | IoPrefix,
	IoHexPrefix = IoHex | IoPrefix,
	IoEcAffine = 0, // affine coordinate
	IoEcCompY = 256, // 1-bit y representation of elliptic curve
	IoSerialize = 512, // use MBS for 1-bit y
	IoFixedSizeByteSeq = IoSerialize, // obsolete
	IoEcProj = 1024 // projective or jacobi coordinate
};

namespace fp {

const size_t UnitBitSize = sizeof(Unit) * 8;

const size_t maxUnitSize = (MCL_MAX_BIT_SIZE + UnitBitSize - 1) / UnitBitSize;
#define MCL_MAX_UNIT_SIZE ((MCL_MAX_BIT_SIZE + MCL_UNIT_BIT_SIZE - 1) / MCL_UNIT_BIT_SIZE)

struct FpGenerator;
struct Op;

typedef void (*void1u)(Unit*);
typedef void (*void2u)(Unit*, const Unit*);
typedef void (*void2uI)(Unit*, const Unit*, Unit);
typedef void (*void2uIu)(Unit*, const Unit*, Unit, const Unit*);
typedef void (*void2uOp)(Unit*, const Unit*, const Op&);
typedef void (*void3u)(Unit*, const Unit*, const Unit*);
typedef void (*void4u)(Unit*, const Unit*, const Unit*, const Unit*);
typedef int (*int2u)(Unit*, const Unit*);

typedef Unit (*u1uII)(Unit*, Unit, Unit);
typedef Unit (*u3u)(Unit*, const Unit*, const Unit*);

struct Block {
	const Unit *p; // pointer to original FpT.v_
	size_t n;
	Unit v_[maxUnitSize];
};

enum Mode {
	FP_AUTO,
	FP_GMP,
	FP_GMP_MONT,
	FP_LLVM,
	FP_LLVM_MONT,
	FP_XBYAK
};

enum PrimeMode {
	PM_GENERIC = 0,
	PM_NICT_P192,
	PM_NICT_P521
};

struct Op {
	/*
		don't change the layout of rp and p
		asm code assumes &rp + 1 == p
	*/
	Unit rp;
	Unit p[maxUnitSize];
	mpz_class mp;
	uint32_t pmod4;
	mcl::SquareRoot sq;
	FpGenerator *fg;
	Unit half[maxUnitSize]; // (p + 1) / 2
	Unit oneRep[maxUnitSize]; // 1(=inv R if Montgomery)
	/*
		for Montgomery
		one = 1
		R = (1 << (N * sizeof(Unit) * 8)) % p
		R2 = (R * R) % p
		R3 = RR^3
	*/
	Unit one[maxUnitSize];
	Unit R2[maxUnitSize];
	Unit R3[maxUnitSize];
	std::vector<Unit> invTbl;
	size_t N;
	size_t bitSize;
	bool (*fp_isZero)(const Unit*);
	void1u fp_clear;
	void2u fp_copy;
	void2u fp_shr1;
	void3u fp_neg;
	void4u fp_add;
	void4u fp_sub;
	void4u fp_mul;
	void3u fp_sqr;
	void2uOp fp_invOp;
	void2uIu fp_mulUnit; // fpN1_mod + fp_mulUnitPre

	void3u fpDbl_mulPre;
	void2u fpDbl_sqrPre;
	int2u fp_preInv;
	void2uI fp_mulUnitPre; // z[N + 1] = x[N] * y
	void3u fpN1_mod; // y[N] = x[N + 1] % p[N]

	void4u fpDbl_add;
	void4u fpDbl_sub;
	void3u fpDbl_mod;

	u3u fp_addPre; // without modulo p
	u3u fp_subPre; // without modulo p
	u3u fpDbl_addPre;
	u3u fpDbl_subPre;
	/*
		for Fp2 = F[u] / (u^2 + 1)
		x = a + bu
	*/
	int xi_a; // xi = xi_a + u
	void3u fp2_add;
	void3u fp2_sub;
	void3u fp2_mul;
	void4u fp2_mulNF;
	void2u fp2_neg;
	void2u fp2_inv;
	void2u fp2_sqr;
	void2u fp2_mul_xi;
	uint32_t (*hash)(void *out, uint32_t maxOutSize, const void *msg, uint32_t msgSize);

	PrimeMode primeMode;
	bool isFullBit; // true if bitSize % uniSize == 0
	bool isMont; // true if use Montgomery
	bool isFastMod; // true if modulo is fast

	Op()
	{
		clear();
		fg = 0;
	}
	~Op()
	{
		destroyFpGenerator(fg);
	}
	void clear()
	{
		rp = 0;
		memset(p, 0, sizeof(p));
		mp = 0;
		pmod4 = 0;
		sq.clear();
		// fg is not set
		memset(half, 0, sizeof(half));
		memset(oneRep, 0, sizeof(oneRep));
		memset(one, 0, sizeof(one));
		memset(R2, 0, sizeof(R2));
		memset(R3, 0, sizeof(R3));
		invTbl.clear();
		N = 0;
		bitSize = 0;
		fp_isZero = 0;
		fp_clear = 0;
		fp_copy = 0;
		fp_shr1 = 0;
		fp_neg = 0;
		fp_add = 0;
		fp_sub = 0;
		fp_mul = 0;
		fp_sqr = 0;
		fp_invOp = 0;
		fp_mulUnit = 0;

		fpDbl_mulPre = 0;
		fpDbl_sqrPre = 0;
		fp_preInv = 0;
		fp_mulUnitPre = 0;
		fpN1_mod = 0;

		fpDbl_add = 0;
		fpDbl_sub = 0;
		fpDbl_mod = 0;

		fp_addPre = 0;
		fp_subPre = 0;
		fpDbl_addPre = 0;
		fpDbl_subPre = 0;

		xi_a = 0;
		fp2_add = 0;
		fp2_sub = 0;
		fp2_mul = 0;
		fp2_mulNF = 0;
		fp2_neg = 0;
		fp2_inv = 0;
		fp2_sqr = 0;
		fp2_mul_xi = 0;

		primeMode = PM_GENERIC;
		isFullBit = false;
		isMont = false;
		isFastMod = false;
		hash = 0;
	}
	void fromMont(Unit* y, const Unit *x) const
	{
		/*
			M(x, y) = xyR^-1
			y = M(x, 1) = xR^-1
		*/
		fp_mul(y, x, one, p);
	}
	void toMont(Unit* y, const Unit *x) const
	{
		/*
			y = M(x, R2) = xR^2 R^-1 = xR
		*/
		fp_mul(y, x, R2, p);
	}
	void init(const std::string& mstr, size_t maxBitSize, Mode mode, size_t mclMaxBitSize = MCL_MAX_BIT_SIZE);
	void initFp2(int xi_a);
	static FpGenerator* createFpGenerator();
	static void destroyFpGenerator(FpGenerator *fg);
private:
	Op(const Op&);
	void operator=(const Op&);
};

/*
	conevrt string to array according to ioMode,
*/
void strToArray(bool *pIsMinus, Unit *x, size_t xN, const std::string& str, int ioMode);

void arrayToStr(std::string& str, const Unit *x, size_t n, int ioMode);

inline const char* getIoSeparator(int ioMode)
{
	return (ioMode & (IoArray | IoArrayRaw | IoSerialize)) ? "" : " ";
}

int detectIoMode(int ioMode, const std::ios_base& ios);

inline void dump(const char *s, size_t n)
{
	for (size_t i = 0; i < n; i++) {
		printf("%02x ", (uint8_t)s[i]);
	}
	printf("\n");
}

inline void dump(const std::string& s)
{
	dump(s.c_str(), s.size());
}

} } // mcl::fp
<|endoftext|>


<commit_before>// Theme.cc for FbTk - Fluxbox ToolKit
// Copyright (c) 2002 - 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// $Id: Theme.cc,v 1.12 2003/08/19 21:25:26 fluxgen Exp $

#include "Theme.hh"

#include "XrmDatabaseHelper.hh"
#include "Font.hh"
#include "Color.hh"
#include "Texture.hh"
#include "App.hh"

#include <cstdio>

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif // HAVE_CONFIG_H

#ifdef HAVE_XPM
#include <X11/xpm.h>
#endif // HAVE_XPM

#include <iostream>

using namespace std;
namespace FbTk {

// create default handlers for Color, Font, Texture, int and string
template <>
void FbTk::ThemeItem<std::string>::load() { }

template <>
void FbTk::ThemeItem<std::string>::setDefaultValue() {
    *(*this) = "";
}

template <>
void FbTk::ThemeItem<std::string>::setFromString(const char *str) {
    *(*this) = (str ? str : "");
}

template <>
void FbTk::ThemeItem<int>::load() { }

template <>
void FbTk::ThemeItem<int>::setDefaultValue() {
    *(*this) = 0;
}

template <>
void FbTk::ThemeItem<int>::setFromString(const char *str) {
    if (str == 0)
        return;
    sscanf(str, "%d", &m_value);
}

template <>
void ThemeItem<FbTk::Font>::setDefaultValue() {
    if (!m_value.load("fixed")) {
        cerr<<"FbTk::ThemeItem<FbTk::Font>: Warning! Failed to load default value 'fixed'"<<endl;
    }
}

template <>
void ThemeItem<FbTk::Font>::setFromString(const char *str) {
    if (m_value.load(str) == false) {
        cerr<<"FbTk::Theme: Error loading font "<<
            ((m_value.isAntialias() || m_value.utf8()) ? "(" : "")<<

            (m_value.isAntialias() ? "antialias" : "")<<
            (m_value.utf8() ? " utf8" : "")<<

            ((m_value.isAntialias() || m_value.utf8()) ? ") " : "")<<
            "for \""<<name()<<"\" or \""<<altName()<<"\": "<<str<<endl;

        cerr<<"FbTk::Theme: Setting default value"<<endl;
        setDefaultValue();
    }

}

// do nothing
template <>
void ThemeItem<FbTk::Font>::load() {
}

template <>
void ThemeItem<FbTk::Texture>::setDefaultValue() {
    m_value.setType(FbTk::Texture::FLAT | FbTk::Texture::SOLID);
}

template <>
void ThemeItem<FbTk::Texture>::setFromString(const char *str) {
    m_value.setFromString(str);
    if (m_value.type() == 0) // failed to set value
        setDefaultValue();
}

template <>
void ThemeItem<FbTk::Texture>::load() {
    string color_name(ThemeManager::instance().
                      resourceValue(name()+".color", altName()+".Color"));
    string colorto_name(ThemeManager::instance().
                        resourceValue(name()+".colorTo", altName()+".ColorTo"));
    string pixmap_name(ThemeManager::instance().
                       resourceValue(name()+".pixmap", altName()+".Pixmap"));

    // set default value if we failed to load color
    if (!m_value.color().setFromString(color_name.c_str(), m_tm.screenNum()))
        m_value.color().setFromString("darkgray", m_tm.screenNum());

    if (!m_value.colorTo().setFromString(colorto_name.c_str(), m_tm.screenNum()))
        m_value.colorTo().setFromString("white", m_tm.screenNum());

#ifdef HAVE_XPM
    XpmAttributes xpm_attr;
    xpm_attr.valuemask = 0;
    Display *dpy = FbTk::App::instance()->display();
    Pixmap pm = 0, mask = 0;
    int retvalue = XpmReadFileToPixmap(dpy,
                                       RootWindow(dpy, m_tm.screenNum()),
                                       const_cast<char *>(pixmap_name.c_str()),
                                       &pm,
                                       &mask, &xpm_attr);
    if (retvalue == 0) { // success
        m_value.pixmap() = pm;
        if (mask != 0)
            XFreePixmap(dpy, mask);
    } else { // failure
#ifdef DEBUG
        cerr<<"Couldn't load pixmap: "<<pixmap_name<<endl;
#endif // DEBUG
        // create empty pixmap
        m_value.pixmap() = FbTk::FbPixmap();
    }
#endif // HAVE_XPM

}

template <>
void ThemeItem<FbTk::Color>::setDefaultValue() {
    m_value.setFromString("white", m_tm.screenNum());
}

template <>
void ThemeItem<FbTk::Color>::setFromString(const char *str) {
    if (!m_value.setFromString(str, m_tm.screenNum())) {
        cerr<<"FbTk::Theme: Error loading color value for \""<<name()<<"\" or \""<<altName()<<"\"."<<endl;
        setDefaultValue();
    }
}

// does nothing
template <>
void ThemeItem<FbTk::Color>::load() { }

Theme::Theme(int screen_num):m_screen_num(screen_num) {

    if (!ThemeManager::instance().registerTheme(*this)) {
        // should it be fatal or not?
        cerr<<"FbTk::Theme Warning: Failed to register Theme"<<endl;
    }
}

Theme::~Theme() {
    if (!ThemeManager::instance().unregisterTheme(*this)) {
#ifdef DEBUG
        cerr<<"Warning: Theme not registered!"<<endl;
#endif // DEBUG
    }
}

ThemeManager &ThemeManager::instance() {
    static ThemeManager tm;
    return tm;
}

ThemeManager::ThemeManager():
    m_max_screens(ScreenCount(FbTk::App::instance()->display())) {

}

bool ThemeManager::registerTheme(Theme &tm) {
    // valid screen num?
    if (m_max_screens < tm.screenNum() || tm.screenNum() < 0)
        return false;
    // TODO: use find and return false if it's already there
    // instead of unique
    m_themelist.push_back(&tm);
    m_themelist.unique();
    return true;
}

bool ThemeManager::unregisterTheme(Theme &tm) {
    m_themelist.remove(&tm);
    return true;
}

bool ThemeManager::load(const std::string &filename) {

    if (!m_database.load(filename.c_str()))
        return false;

    //get list and go throu all the resources and load them
    ThemeList::iterator theme_it = m_themelist.begin();
    const ThemeList::iterator theme_it_end = m_themelist.end();
    for (; theme_it != theme_it_end; ++theme_it) {
        loadTheme(**theme_it);
    }
    // notify all themes that we reconfigured
    theme_it = m_themelist.begin();
    for (; theme_it != theme_it_end; ++theme_it) {
        // send reconfiguration signal to theme and listeners
        (*theme_it)->reconfigTheme();
        (*theme_it)->reconfigSig().notify();
    }
    return true;
}

void ThemeManager::loadTheme(Theme &tm) {
    std::list<ThemeItem_base *>::iterator i = tm.itemList().begin();
    std::list<ThemeItem_base *>::iterator i_end = tm.itemList().end();
    for (; i != i_end; ++i) {
        ThemeItem_base *resource = *i;
        if (!loadItem(*resource)) {
            // try fallback resource in theme
            if (!tm.fallback(*resource)) {
                cerr<<"Failed to read theme item: "<<resource->name()<<endl;
                cerr<<"Setting default value"<<endl;
                resource->setDefaultValue();
            }
        }
    }
    // send reconfiguration signal to theme and listeners
}

bool ThemeManager::loadItem(ThemeItem_base &resource) {
    return loadItem(resource, resource.name(), resource.altName());
}

/// handles resource item loading with specific name/altname
bool ThemeManager::loadItem(ThemeItem_base &resource, const std::string &name, const std::string &alt_name) {
    XrmValue value;
    char *value_type;

    if (XrmGetResource(*m_database, name.c_str(),
                       alt_name.c_str(), &value_type, &value)) {
        resource.setFromString(value.addr);
        resource.load(); // load additional stuff by the ThemeItem
    } else
        return false;

    return true;
}

std::string ThemeManager::resourceValue(const std::string &name, const std::string &altname) {
    XrmValue value;
    char *value_type;

    if (*m_database != 0 && XrmGetResource(*m_database, name.c_str(),
                                           altname.c_str(), &value_type, &value) && value.addr != 0) {
        return string(value.addr);
    }
    return "";
}

}; // end namespace FbTk
<commit_msg>fixed theme items for pixmapwithmask<commit_after>// Theme.cc for FbTk - Fluxbox ToolKit
// Copyright (c) 2002 - 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// $Id: Theme.cc,v 1.13 2003/08/22 22:17:30 fluxgen Exp $

#include "Theme.hh"

#include "XrmDatabaseHelper.hh"
#include "Font.hh"
#include "Color.hh"
#include "Texture.hh"
#include "App.hh"
#include "Image.hh"
#include "PixmapWithMask.hh"

#include <cstdio>
#include <memory>
#include <iostream>
using namespace std;

namespace FbTk {

// create default handlers for Color, Font, Texture, int and string
template <>
void FbTk::ThemeItem<std::string>::load() { }

template <>
void FbTk::ThemeItem<std::string>::setDefaultValue() {
    *(*this) = "";
}

template <>
void FbTk::ThemeItem<std::string>::setFromString(const char *str) {
    *(*this) = (str ? str : "");
}

template <>
void FbTk::ThemeItem<int>::load() { }

template <>
void FbTk::ThemeItem<int>::setDefaultValue() {
    *(*this) = 0;
}

template <>
void FbTk::ThemeItem<int>::setFromString(const char *str) {
    if (str == 0)
        return;
    sscanf(str, "%d", &m_value);
}

template <>
void ThemeItem<FbTk::Font>::setDefaultValue() {
    if (!m_value.load("fixed")) {
        cerr<<"FbTk::ThemeItem<FbTk::Font>: Warning! Failed to load default value 'fixed'"<<endl;
    }
}

template <>
void ThemeItem<FbTk::Font>::setFromString(const char *str) {
    if (m_value.load(str) == false) {
        cerr<<"FbTk::Theme: Error loading font "<<
            ((m_value.isAntialias() || m_value.utf8()) ? "(" : "")<<

            (m_value.isAntialias() ? "antialias" : "")<<
            (m_value.utf8() ? " utf8" : "")<<

            ((m_value.isAntialias() || m_value.utf8()) ? ") " : "")<<
            "for \""<<name()<<"\" or \""<<altName()<<"\": "<<str<<endl;

        cerr<<"FbTk::Theme: Setting default value"<<endl;
        setDefaultValue();
    }

}

// do nothing
template <>
void ThemeItem<FbTk::Font>::load() {
}

template <>
void ThemeItem<FbTk::Texture>::setDefaultValue() {
    m_value.setType(FbTk::Texture::FLAT | FbTk::Texture::SOLID);
}

template <>
void ThemeItem<FbTk::Texture>::setFromString(const char *str) {
    m_value.setFromString(str);
    if (m_value.type() == 0) // failed to set value
        setDefaultValue();
}

template <>
void ThemeItem<FbTk::Texture>::load() {
    string color_name(ThemeManager::instance().
                      resourceValue(name()+".color", altName()+".Color"));
    string colorto_name(ThemeManager::instance().
                        resourceValue(name()+".colorTo", altName()+".ColorTo"));
    string pixmap_name(ThemeManager::instance().
                       resourceValue(name()+".pixmap", altName()+".Pixmap"));

    // set default value if we failed to load color
    if (!m_value.color().setFromString(color_name.c_str(), m_tm.screenNum()))
        m_value.color().setFromString("darkgray", m_tm.screenNum());

    if (!m_value.colorTo().setFromString(colorto_name.c_str(), m_tm.screenNum()))
        m_value.colorTo().setFromString("white", m_tm.screenNum());

    std::auto_ptr<PixmapWithMask> pm(Image::load(pixmap_name, m_tm.screenNum()));
    if (pm.get() == 0) {
        cerr<<"Resource("<<name()+".pixmap"<<"): Failed to load image: "<<pixmap_name<<endl;
    } else
        m_value.pixmap() = pm->pixmap().release();
}

// not used
template <>
void FbTk::ThemeItem<PixmapWithMask>::
load() { }

template <>
void FbTk::ThemeItem<PixmapWithMask>::
setDefaultValue() {
    // create empty pixmap
    (*this)->pixmap() = FbTk::FbPixmap(); // pixmap
    (*this)->mask() = FbTk::FbPixmap(); // mask
}

template <>
void FbTk::ThemeItem<PixmapWithMask>::
setFromString(const char *str) {
    if (str == 0)
        setDefaultValue();
    else {
        std::auto_ptr<FbTk::PixmapWithMask> pm(Image::load(str, m_tm.screenNum()));
        if (pm.get() == 0)
            setDefaultValue();
        else {
            (*this)->pixmap() = pm->pixmap().release();
            (*this)->mask() = pm->mask().release();
        }
    }
}

template <>
void ThemeItem<FbTk::Color>::setDefaultValue() {
    m_value.setFromString("white", m_tm.screenNum());
}

template <>
void ThemeItem<FbTk::Color>::setFromString(const char *str) {
    if (!m_value.setFromString(str, m_tm.screenNum())) {
        cerr<<"FbTk::Theme: Error loading color value for \""<<name()<<"\" or \""<<altName()<<"\"."<<endl;
        setDefaultValue();
    }
}

// does nothing
template <>
void ThemeItem<FbTk::Color>::load() { }

Theme::Theme(int screen_num):m_screen_num(screen_num) {

    if (!ThemeManager::instance().registerTheme(*this)) {
        // should it be fatal or not?
        cerr<<"FbTk::Theme Warning: Failed to register Theme"<<endl;
    }
}

Theme::~Theme() {
    if (!ThemeManager::instance().unregisterTheme(*this)) {
#ifdef DEBUG
        cerr<<"Warning: Theme not registered!"<<endl;
#endif // DEBUG
    }
}

ThemeManager &ThemeManager::instance() {
    static ThemeManager tm;
    return tm;
}

ThemeManager::ThemeManager():
    m_max_screens(ScreenCount(FbTk::App::instance()->display())) {

}

bool ThemeManager::registerTheme(Theme &tm) {
    // valid screen num?
    if (m_max_screens < tm.screenNum() || tm.screenNum() < 0)
        return false;
    // TODO: use find and return false if it's already there
    // instead of unique
    m_themelist.push_back(&tm);
    m_themelist.unique();
    return true;
}

bool ThemeManager::unregisterTheme(Theme &tm) {
    m_themelist.remove(&tm);
    return true;
}

bool ThemeManager::load(const std::string &filename) {

    if (!m_database.load(filename.c_str()))
        return false;

    //get list and go throu all the resources and load them
    ThemeList::iterator theme_it = m_themelist.begin();
    const ThemeList::iterator theme_it_end = m_themelist.end();
    for (; theme_it != theme_it_end; ++theme_it) {
        loadTheme(**theme_it);
    }
    // notify all themes that we reconfigured
    theme_it = m_themelist.begin();
    for (; theme_it != theme_it_end; ++theme_it) {
        // send reconfiguration signal to theme and listeners
        (*theme_it)->reconfigTheme();
        (*theme_it)->reconfigSig().notify();
    }
    return true;
}

void ThemeManager::loadTheme(Theme &tm) {
    std::list<ThemeItem_base *>::iterator i = tm.itemList().begin();
    std::list<ThemeItem_base *>::iterator i_end = tm.itemList().end();
    for (; i != i_end; ++i) {
        ThemeItem_base *resource = *i;
        if (!loadItem(*resource)) {
            // try fallback resource in theme
            if (!tm.fallback(*resource)) {
                cerr<<"Failed to read theme item: "<<resource->name()<<endl;
                cerr<<"Setting default value"<<endl;
                resource->setDefaultValue();
            }
        }
    }
    // send reconfiguration signal to theme and listeners
}

bool ThemeManager::loadItem(ThemeItem_base &resource) {
    return loadItem(resource, resource.name(), resource.altName());
}

/// handles resource item loading with specific name/altname
bool ThemeManager::loadItem(ThemeItem_base &resource, const std::string &name, const std::string &alt_name) {
    XrmValue value;
    char *value_type;

    if (XrmGetResource(*m_database, name.c_str(),
                       alt_name.c_str(), &value_type, &value)) {
        resource.setFromString(value.addr);
        resource.load(); // load additional stuff by the ThemeItem
    } else
        return false;

    return true;
}

std::string ThemeManager::resourceValue(const std::string &name, const std::string &altname) {
    XrmValue value;
    char *value_type;

    if (*m_database != 0 && XrmGetResource(*m_database, name.c_str(),
                                           altname.c_str(), &value_type, &value) && value.addr != 0) {
        return string(value.addr);
    }
    return "";
}

/*
void ThemeManager::listItems() {
    ThemeList::iterator it = m_themelist.begin();
    ThemeList::iterator it_end = m_themelist.end();
    for (; it != it_end; ++it) {
        std::list<ThemeItem_base *>::iterator item = (*it)->itemList().begin();
        std::list<ThemeItem_base *>::iterator item_end = (*it)->itemList().end();
        for (; item != item_end; ++item) {
            cerr<<(*item)->name()<<":"<<endl;
            if (typeid(**item) == typeid(ThemeItem<Texture>)) {
                cerr<<(*item)->name()<<".pixmap:"<<endl;
                cerr<<(*item)->name()<<".color:"<<endl;
                cerr<<(*item)->name()<<".colorTo:"<<endl;
            }
        }
    }

}
*/
}; // end namespace FbTk
<|endoftext|>


<commit_before>//utils.cpp
#include <cmath>
#include <iostream>

#include "utils.hpp"

namespace utils{

    DataPoint::DataPoint(double x1, double x2, double y){
        this->x[0] = x1;
        this->x[1] = x2;
        this->y = y;
    }

    //=========================FUNÇÕES BINÁRIAS===========================//

    //Função Soma
    double uAdd(double v1, double v2) {

        return (v1 + v2);
    }

    //Função Subtração
    double uSub(double v1, double v2) {

        return (v1 - v2);
    }

    //Função Multiplicação
    double uMult(double v1, double v2) {

        return (v1 * v2);
    }

    //Função Divisão
    double uDiv(double v1, double v2) {

        if (v2 == 0)
            return 0;   //Padrão
        else
            return (v1 / v2);
    }

    //Função Potência
    double uPow(double v1, double v2) {

        if ((v1 == 0)&&(v2 == 0))
            return 0;   //Padrão - Equivalente matemático a 0/0
        else
            return pow(v1, v2);
    }

    //==========================FUNÇÕES UNÁRIAS===========================//

    //Função Exponencial (e^v)
    double uExp(double v) {

        return (exp(v));
    }

    //Função Raiz Quadrada
    double uSqrt(double v) {

        if (v < 0)
            return 0;
        else
            return (sqrt(v));
    }

    //Função Logaritmo Neperiano
    double uLn(double v) {

        if (v > 0)
            return (log(v));
        else
            return 0;
    }

    //Converter radianos em graus para poder utilizar as funções trigonométricas
    double rad_to_degrees(double v) {

        double V = ((v*180)/(M_PI));    //Transforma o valor de entrada para graus
        if ((V >= 360) || (V <= -360)) V = V%360;
        if (V < 0) V = 360+V;
        return V;

    }

    //Função Seno
    double uSin(double v) {

        return (sin(rad_to_degrees(v)));
    }

    //Função Cosseno
    double uCos(double v) {

        return (cos(rad_to_degrees(v)));
    }

    //Função Tangente
    double uTan(double v) {

        double V = rad_to_degrees(v);

        if ((V == 90)||(V == 270))
            return 0;
        else
            return (tan(V));
    }

    //=====================SOLUCIONADOR DE EQUAÇÕES=======================//

    //Solucionador de equações de aridade 1
    double func1_solver(int F_id, double v) {

        switch (F_id) {
            case LN:
                return uLn(v);
            case EXP:
                return uExp(v);
            case SQRT:
                return uSqrt(v);
            case SIN:
                return uSin(v);
            case COS:
                return uCos(v);
            case TAN:
                return tan(v);
            default:
                std::cout << "ERRO FUNC1 SOLVER" << std::endl;
                return -1.0;
        }
    }

    //Solucionador de equações de aridaade 2
    double func2_solver(int F_id, double v1, double v2) {

        switch (F_id) {
            case ADD:
                return uAdd(v1, v2);
            case SUB:
                return uSub(v1, v2);
            case MULT:
                return uMult(v1, v2);
            case DIV:
                return uDiv(v1, v2);
            case POW:
                return uPow(v1, v2);
            default:
                std::cout << "ERRO FUNC2 SOLVER" << std::endl;
                return -1.0;
        }
    }
}
<commit_msg>1.2.2 Melhorado construtor do DataPoint<commit_after>//utils.cpp
#include <cmath>
#include <iostream>

#include "utils.hpp"

namespace utils{

    DataPoint::DataPoint(std::vector<double> x, double y = 0.0){

        if (x.size()==0){
            this->x.push_back(0.0);
        }
        else {
            for(int i=0; i<x.size(); i++){
                this->x.push_back(x.at(i));
            }
        }

        this->y = y;
    }

    //=========================FUNÇÕES BINÁRIAS===========================//

    //Função Soma
    double uAdd(double v1, double v2) {

        return (v1 + v2);
    }

    //Função Subtração
    double uSub(double v1, double v2) {

        return (v1 - v2);
    }

    //Função Multiplicação
    double uMult(double v1, double v2) {

        return (v1 * v2);
    }

    //Função Divisão
    double uDiv(double v1, double v2) {

        if (v2 == 0)
            return 0;   //Padrão
        else
            return (v1 / v2);
    }

    //Função Potência
    double uPow(double v1, double v2) {

        if ((v1 == 0)&&(v2 == 0))
            return 0;   //Padrão - Equivalente matemático a 0/0
        else
            return pow(v1, v2);
    }

    //==========================FUNÇÕES UNÁRIAS===========================//

    //Função Exponencial (e^v)
    double uExp(double v) {

        return (exp(v));
    }

    //Função Raiz Quadrada
    double uSqrt(double v) {

        if (v < 0)
            return 0;
        else
            return (sqrt(v));
    }

    //Função Logaritmo Neperiano
    double uLn(double v) {

        if (v > 0)
            return (log(v));
        else
            return 0;
    }

    //Converter radianos em graus para poder utilizar as funções trigonométricas
    double rad_to_degrees(double v) {

        double V = ((v*180)/(M_PI));    //Transforma o valor de entrada para graus
        if ((V >= 360) || (V <= -360)) V = V%360;
        if (V < 0) V = 360+V;
        return V;

    }

    //Função Seno
    double uSin(double v) {

        return (sin(rad_to_degrees(v)));
    }

    //Função Cosseno
    double uCos(double v) {

        return (cos(rad_to_degrees(v)));
    }

    //Função Tangente
    double uTan(double v) {

        double V = rad_to_degrees(v);

        if ((V == 90)||(V == 270))
            return 0;
        else
            return (tan(V));
    }

    //=====================SOLUCIONADOR DE EQUAÇÕES=======================//

    //Solucionador de equações de aridade 1
    double func1_solver(int F_id, double v) {

        switch (F_id) {
            case LN:
                return uLn(v);
            case EXP:
                return uExp(v);
            case SQRT:
                return uSqrt(v);
            case SIN:
                return uSin(v);
            case COS:
                return uCos(v);
            case TAN:
                return tan(v);
            default:
                std::cout << "ERRO FUNC1 SOLVER" << std::endl;
                return -1.0;
        }
    }

    //Solucionador de equações de aridaade 2
    double func2_solver(int F_id, double v1, double v2) {

        switch (F_id) {
            case ADD:
                return uAdd(v1, v2);
            case SUB:
                return uSub(v1, v2);
            case MULT:
                return uMult(v1, v2);
            case DIV:
                return uDiv(v1, v2);
            case POW:
                return uPow(v1, v2);
            default:
                std::cout << "ERRO FUNC2 SOLVER" << std::endl;
                return -1.0;
        }
    }
}
<|endoftext|>


<commit_before>/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */

#include "Function.h"
#include <gtest/gtest.h>
#include "paddle/math/SparseMatrix.h"

namespace paddle {

template <DeviceType DType>
void FunctionApi(typename Tensor<real, DType>::Matrix& output,
                 const typename Tensor<real, DType>::Matrix& input);

template <>
void FunctionApi<DEVICE_TYPE_CPU>(CpuMatrix& output, const CpuMatrix& input) {
  EXPECT_EQ(output.getHeight(), 100);
  EXPECT_EQ(output.getWidth(), 200);
}

template <>
void FunctionApi<DEVICE_TYPE_GPU>(GpuMatrix& output, const GpuMatrix& input) {
  EXPECT_EQ(output.getHeight(), 10);
  EXPECT_EQ(output.getWidth(), 20);
}

template <DeviceType DType>
void Function(const BufferArgs& arguments) {
  const auto input = arguments[0].matrix<DType>();
  auto output = arguments[1].matrix<DType>();
  FunctionApi<DType>(output, input);
}

TEST(Function, BufferArgs) {
  CpuMatrix cpuInput = CpuMatrix(100, 200);
  CpuMatrix cpuOutput = CpuMatrix(100, 200);
  BufferArgs cpuArgments;
  cpuArgments.addArg(cpuInput);
  cpuArgments.addArg(cpuOutput);
  Function<DEVICE_TYPE_CPU>(cpuArgments);

  GpuMatrix gpuInput = GpuMatrix(10, 20);
  GpuMatrix gpuOutput = GpuMatrix(10, 20);
  BufferArgs gpuArgments;
  gpuArgments.addArg(gpuInput);
  gpuArgments.addArg(gpuOutput);
  Function<DEVICE_TYPE_GPU>(gpuArgments);
}

TEST(BufferArgs, asArgument) {
  MatrixPtr matrix = Matrix::create(100, 200);
  VectorPtr vector = Vector::create(100, false);
  CpuSparseMatrix sparse(200, 300, 50);

  // prepare arguments
  BufferArgs argments;
  argments.addArg(*matrix);
  argments.addArg(*vector);
  argments.addArg(sparse);

  // function
  auto function = [=](const BufferArgs& inputs) {
    EXPECT_EQ(inputs.size(), 3);

    // check inputs[0]
    EXPECT_EQ(inputs[0].shape().ndims(), 2);
    EXPECT_EQ(inputs[0].shape()[0], 100);
    EXPECT_EQ(inputs[0].shape()[1], 200);
    EXPECT_EQ(inputs[0].data(), matrix->getData());

    EXPECT_EQ(inputs[0].matrix<DEVICE_TYPE_CPU>().getHeight(),
              matrix->getHeight());
    EXPECT_EQ(inputs[0].matrix<DEVICE_TYPE_CPU>().getWidth(),
              matrix->getWidth());
    EXPECT_EQ(inputs[0].matrix<DEVICE_TYPE_CPU>().getData(), matrix->getData());

    // check inputs[1]
    EXPECT_EQ(inputs[1].shape().ndims(), 1);
    EXPECT_EQ(inputs[1].shape()[0], 100);
    EXPECT_EQ(inputs[1].data(), vector->getData());
    CpuVector inVector = inputs[1].vector<real, DEVICE_TYPE_CPU>();
    EXPECT_EQ(inVector.getSize(), vector->getSize());
    EXPECT_EQ(inVector.getData(), vector->getData());

    // check inputs[2]
    EXPECT_EQ(inputs[2].shape().ndims(), 2);
    EXPECT_EQ(inputs[2].shape()[0], 200);
    EXPECT_EQ(inputs[2].shape()[1], 300);
    EXPECT_EQ(inputs[2].data(), sparse.getData());
    // CHECK_EQ(inputs[2].sparse().nnz(), 50);
    // CHECK_EQ(inputs[2].sparse().dataFormat(), SPARSE_CSR_FORMAT);
    // CHECK_EQ(inputs[2].sparse().dataType(), SPARSE_FLOAT_VALUE);
    EXPECT_EQ(inputs[2].sparse().getRowBuf(), sparse.getRows());
    EXPECT_EQ(inputs[2].sparse().getColBuf(), sparse.getCols());
  };

  // call function
  function(argments);
}

}  // namespace paddle
<commit_msg>Add a CheckBufferArg. It is used to check the consistency between the BufferArg type argument received by Function and the original type argument.<commit_after>/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */

#include "Function.h"
#include <gtest/gtest.h>
#include "paddle/math/SparseMatrix.h"

namespace paddle {

template <DeviceType DType>
void FunctionApi(typename Tensor<real, DType>::Matrix& output,
                 const typename Tensor<real, DType>::Matrix& input);

template <>
void FunctionApi<DEVICE_TYPE_CPU>(CpuMatrix& output, const CpuMatrix& input) {
  EXPECT_EQ(output.getHeight(), 100);
  EXPECT_EQ(output.getWidth(), 200);
}

template <>
void FunctionApi<DEVICE_TYPE_GPU>(GpuMatrix& output, const GpuMatrix& input) {
  EXPECT_EQ(output.getHeight(), 10);
  EXPECT_EQ(output.getWidth(), 20);
}

template <DeviceType DType>
void Function(const BufferArgs& arguments) {
  const auto input = arguments[0].matrix<DType>();
  auto output = arguments[1].matrix<DType>();
  FunctionApi<DType>(output, input);
}

TEST(Function, BufferArgs) {
  CpuMatrix cpuInput = CpuMatrix(100, 200);
  CpuMatrix cpuOutput = CpuMatrix(100, 200);
  BufferArgs cpuArgments;
  cpuArgments.addArg(cpuInput);
  cpuArgments.addArg(cpuOutput);
  Function<DEVICE_TYPE_CPU>(cpuArgments);

  GpuMatrix gpuInput = GpuMatrix(10, 20);
  GpuMatrix gpuOutput = GpuMatrix(10, 20);
  BufferArgs gpuArgments;
  gpuArgments.addArg(gpuInput);
  gpuArgments.addArg(gpuOutput);
  Function<DEVICE_TYPE_GPU>(gpuArgments);
}

/**
 * Some tests case are used to check the consistency between the BufferArg type
 * argument received by Function and the original type argument.
 *
 * Use Case:
 *  TEST() {
 *    Matrix matrix(...);
 *    CheckBufferArg lambda = [=](const BufferArg& arg) {
 *      // check matrix and arg are equivalent
 *      EXPECT_EQ(matrix, arg);
 *    }
 *
 *   BufferArgs argments{matrix...};
 *   std::vector<CheckBufferArg> checkFunc{lambda...};
 *   testBufferArgs(argments, checkFunc);
 *  }
 */
typedef std::function<void(const BufferArg&)> CheckBufferArg;

void testBufferArgs(const BufferArgs& inputs,
                    const std::vector<CheckBufferArg>& check) {
  EXPECT_EQ(inputs.size(), check.size());
  for (size_t i = 0; i < inputs.size(); i++) {
    check[i](inputs[i]);
  }
}

TEST(Arguments, Matrix) {
  MatrixPtr matrix = Matrix::create(100, 200);
  CheckBufferArg check = [=](const BufferArg& arg) {
    EXPECT_EQ(arg.shape().ndims(), 2);
    EXPECT_EQ(arg.shape()[0], 100);
    EXPECT_EQ(arg.shape()[1], 200);
    EXPECT_EQ(arg.data(), matrix->getData());

    EXPECT_EQ(arg.matrix<DEVICE_TYPE_CPU>().getHeight(), matrix->getHeight());
    EXPECT_EQ(arg.matrix<DEVICE_TYPE_CPU>().getWidth(), matrix->getWidth());
    EXPECT_EQ(arg.matrix<DEVICE_TYPE_CPU>().getData(), matrix->getData());
  };

  BufferArgs argments;
  argments.addArg(*matrix);
  std::vector<CheckBufferArg> checkFunc;
  checkFunc.push_back(check);
  testBufferArgs(argments, checkFunc);
}

TEST(Arguments, Vector) {
  VectorPtr vector = Vector::create(100, false);
  CheckBufferArg check = [=](const BufferArg& arg) {
    EXPECT_EQ(arg.shape().ndims(), 1);
    EXPECT_EQ(arg.shape()[0], 100);
    EXPECT_EQ(arg.data(), vector->getData());

    CpuVector inVector = arg.vector<real, DEVICE_TYPE_CPU>();
    EXPECT_EQ(inVector.getSize(), vector->getSize());
    EXPECT_EQ(inVector.getData(), vector->getData());
  };

  BufferArgs argments;
  argments.addArg(*vector);
  std::vector<CheckBufferArg> checkFunc;
  checkFunc.push_back(check);
  testBufferArgs(argments, checkFunc);
}

TEST(Arguments, CpuSparseMatrix) {
  CpuSparseMatrix sparse(200, 300, 50);
  CheckBufferArg check = [=](const BufferArg& arg) {
    EXPECT_EQ(arg.shape().ndims(), 2);
    EXPECT_EQ(arg.shape()[0], 200);
    EXPECT_EQ(arg.shape()[1], 300);
    EXPECT_EQ(arg.data(), sparse.getData());
    // CHECK_EQ(arg.sparse().nnz(), 50);
    // CHECK_EQ(arg.sparse().dataFormat(), SPARSE_CSR_FORMAT);
    // CHECK_EQ(arg.sparse().dataType(), SPARSE_FLOAT_VALUE);
    EXPECT_EQ(arg.sparse().getRowBuf(), sparse.getRows());
    EXPECT_EQ(arg.sparse().getColBuf(), sparse.getCols());
  };

  BufferArgs argments;
  argments.addArg(sparse);
  std::vector<CheckBufferArg> checkFunc;
  checkFunc.push_back(check);
  testBufferArgs(argments, checkFunc);
}

}  // namespace paddle
<|endoftext|>


<commit_before>#ifndef __NODE_MAPNIK_UTILS_H__
#define __NODE_MAPNIK_UTILS_H__

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <nan.h>
#pragma GCC diagnostic pop

// stl
#include <string>
#include <memory>

// core types
#include <mapnik/unicode.hpp>
#include <mapnik/value_types.hpp>
#include <mapnik/value.hpp>
#include <mapnik/version.hpp>
#include <mapnik/params.hpp>
#include <mapnik/utils.hpp>

#define TOSTR(obj) (*String::Utf8Value((obj)->ToString()))

#define FUNCTION_ARG(I, VAR)                                            \
    if (args.Length() <= (I) || !args[I]->IsFunction()) {               \
        NanThrowTypeError("Argument " #I " must be a function");        \
        NanReturnUndefined();                                           \
    }                                                                   \
    Local<Function> VAR = args[I].As<Function>();

#define ATTR(t, name, get, set)                                         \
    t->InstanceTemplate()->SetAccessor(NanNew(name), get, set);

#define NODE_MAPNIK_DEFINE_CONSTANT(target, name, constant)             \
    (target)->Set(NanNew(name),                                         \
                  NanNew<Integer>(constant));                            \

#define NODE_MAPNIK_DEFINE_64_BIT_CONSTANT(target, name, constant)      \
    (target)->Set(NanNew(name),                                         \
                  NanNew<Number>(constant));                            \

using namespace v8;

namespace node_mapnik {

typedef mapnik::value_integer value_integer;

// adapted to work for both mapnik features and mapnik parameters
struct value_converter
{
    Handle<Value> operator () ( value_integer val ) const
    {
        return NanNew<Number>(val);
    }

    Handle<Value> operator () (mapnik::value_bool val ) const
    {
        return NanNew<Boolean>(val);
    }

    Handle<Value> operator () ( double val ) const
    {
        return NanNew<Number>(val);
    }

    Handle<Value> operator () ( std::string const& val ) const
    {
        return NanNew<String>(val.c_str());
    }

    Handle<Value> operator () ( mapnik::value_unicode_string const& val) const
    {
        std::string buffer;
        mapnik::to_utf8(val,buffer);
        return NanNew<String>(buffer.c_str());
    }

    Handle<Value> operator () ( mapnik::value_null const& ) const
    {
        return NanNull();
    }
};

inline void params_to_object(Local<Object>& ds, std::string const& key, mapnik::value_holder const& val)
{
    ds->Set(NanNew(key.c_str()), mapnik::util::apply_visitor(value_converter(), val));
}

} // end ns
#endif
<commit_msg>remove uneeded include (also that is gone in mapnik 3)<commit_after>#ifndef __NODE_MAPNIK_UTILS_H__
#define __NODE_MAPNIK_UTILS_H__

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <nan.h>
#pragma GCC diagnostic pop

// stl
#include <string>
#include <memory>

// core types
#include <mapnik/unicode.hpp>
#include <mapnik/value_types.hpp>
#include <mapnik/value.hpp>
#include <mapnik/version.hpp>
#include <mapnik/params.hpp>

#define TOSTR(obj) (*String::Utf8Value((obj)->ToString()))

#define FUNCTION_ARG(I, VAR)                                            \
    if (args.Length() <= (I) || !args[I]->IsFunction()) {               \
        NanThrowTypeError("Argument " #I " must be a function");        \
        NanReturnUndefined();                                           \
    }                                                                   \
    Local<Function> VAR = args[I].As<Function>();

#define ATTR(t, name, get, set)                                         \
    t->InstanceTemplate()->SetAccessor(NanNew(name), get, set);

#define NODE_MAPNIK_DEFINE_CONSTANT(target, name, constant)             \
    (target)->Set(NanNew(name),                                         \
                  NanNew<Integer>(constant));                            \

#define NODE_MAPNIK_DEFINE_64_BIT_CONSTANT(target, name, constant)      \
    (target)->Set(NanNew(name),                                         \
                  NanNew<Number>(constant));                            \

using namespace v8;

namespace node_mapnik {

typedef mapnik::value_integer value_integer;

// adapted to work for both mapnik features and mapnik parameters
struct value_converter
{
    Handle<Value> operator () ( value_integer val ) const
    {
        return NanNew<Number>(val);
    }

    Handle<Value> operator () (mapnik::value_bool val ) const
    {
        return NanNew<Boolean>(val);
    }

    Handle<Value> operator () ( double val ) const
    {
        return NanNew<Number>(val);
    }

    Handle<Value> operator () ( std::string const& val ) const
    {
        return NanNew<String>(val.c_str());
    }

    Handle<Value> operator () ( mapnik::value_unicode_string const& val) const
    {
        std::string buffer;
        mapnik::to_utf8(val,buffer);
        return NanNew<String>(buffer.c_str());
    }

    Handle<Value> operator () ( mapnik::value_null const& ) const
    {
        return NanNull();
    }
};

inline void params_to_object(Local<Object>& ds, std::string const& key, mapnik::value_holder const& val)
{
    ds->Set(NanNew(key.c_str()), mapnik::util::apply_visitor(value_converter(), val));
}

} // end ns
#endif
<|endoftext|>


<commit_before><commit_msg>Fixed codegen<commit_after><|endoftext|>