Commit ea2785c9 authored by Philip Trettner's avatar Philip Trettner

conversion ctors

parent c9fd6f7c
#pragma once
#include <type_traits>
namespace tg
{
using u8 = unsigned char;
......@@ -209,11 +211,44 @@ template <class Container, class ElementT>
auto container_test(Container* c) -> decltype(static_cast<ElementT*>(c->data()), static_cast<decltype(sizeof(0))>(c->size()), 0);
template <class Container, class ElementT>
char container_test(...);
template <class Container, class ElementT, class = void>
struct is_range_t : false_type
{
};
template <class ElementT, size_t N>
struct is_range_t<ElementT[N], ElementT> : true_type
{
};
template <class ElementT, size_t N>
struct is_range_t<ElementT[N], ElementT const> : true_type
{
};
template <class ElementT, size_t N>
struct is_range_t<ElementT (&)[N], ElementT> : true_type
{
};
template <class ElementT, size_t N>
struct is_range_t<ElementT (&)[N], ElementT const> : true_type
{
};
template <class Container, class ElementT>
struct is_range_t<Container,
ElementT,
std::void_t< //
decltype(static_cast<ElementT&>(*std::declval<Container>().begin())), //
decltype(std::declval<Container>().end()) //
>> : std::true_type
{
};
}
template <class Container, class ElementT>
static constexpr bool is_container = sizeof(detail::container_test<Container, ElementT>(nullptr)) == sizeof(int);
template <class Container, class ElementT>
static constexpr bool is_range = detail::is_range_t<Container, ElementT>::value;
template <class C>
constexpr auto begin(C& c) -> decltype(c.begin())
{
......
......@@ -66,6 +66,11 @@ struct aabb
TG_CONTRACT(min[i] <= max[i]);
}
template <class OtherT, class OtherTraitsT>
constexpr aabb(aabb<D, OtherT, OtherTraitsT> const& v) : min(v.min), max(v.max)
{
}
template <class OtherT>
constexpr aabb(pos<D, OtherT> min, pos<D, OtherT> max) : aabb(pos_t(min), pos_t(max))
{
......
......@@ -76,6 +76,11 @@ struct box<D, ScalarT, D, TraitsT>
constexpr box(pos_t center, mat_t const& half_extents) : center(center), half_extents(half_extents) {}
constexpr box(aabb<D, ScalarT, TraitsT> const& b); // requires tg.hh
template <class OtherT, class OtherTraitsT>
constexpr box(box<D, OtherT, D, OtherTraitsT> const& v) : center(v.center), half_extents(v.half_extents)
{
}
/// Note that the box goes from -1 to 1 instead of the usual 0 to 1
[[nodiscard]] constexpr pos_t operator[](comp<D, ScalarT> const& c) const;
......@@ -98,6 +103,11 @@ struct box<2, ScalarT, 3, TraitsT>
constexpr box() = default;
constexpr box(pos_t center, mat_t const& half_extents) : center(center), half_extents(half_extents) {}
template <class OtherT, class OtherTraitsT>
constexpr box(box<2, OtherT, 3, OtherTraitsT> const& v) : center(v.center), half_extents(v.half_extents)
{
}
/// Note that the box goes from -1 to 1 instead of the usual 0 to 1
[[nodiscard]] constexpr pos_t operator[](comp<2, ScalarT> const& c) const;
......
......@@ -42,6 +42,11 @@ struct capsule<3, ScalarT, TraitsT>
constexpr capsule(seg_t const& axis, scalar_t radius) : axis(axis), radius(radius) {}
constexpr capsule(pos_t const& p0, pos_t const& p1, scalar_t radius) : axis(p0, p1), radius(radius) {}
template <class OtherT, class OtherTraitsT>
constexpr capsule(capsule<3, OtherT, OtherTraitsT> const& v) : axis(v.axis), radius(v.radius)
{
}
[[nodiscard]] bool operator==(capsule const& rhs) const { return axis == rhs.axis && radius == rhs.radius; }
[[nodiscard]] bool operator!=(capsule const& rhs) const { return !operator==(rhs); }
};
......
......@@ -44,6 +44,11 @@ struct cylinder<3, ScalarT, TraitsT>
constexpr cylinder(seg_t const& axis, scalar_t radius) : axis(axis), radius(radius) {}
constexpr cylinder(pos_t const& p0, pos_t const& p1, scalar_t radius) : axis(p0, p1), radius(radius) {}
template <class OtherT, class OtherTraitsT>
constexpr cylinder(cylinder<3, OtherT, OtherTraitsT> const& v) : axis(v.axis), radius(v.radius)
{
}
[[nodiscard]] bool operator==(cylinder const& rhs) const { return axis == rhs.axis && radius == rhs.radius; }
[[nodiscard]] bool operator!=(cylinder const& rhs) const { return !operator==(rhs); }
};
......
......@@ -60,6 +60,11 @@ struct halfspace
constexpr halfspace(dir_t n, scalar_t d) : normal(n), dis(d) {}
constexpr halfspace(dir_t n, pos_t p);
template <class OtherT>
constexpr halfspace(halfspace<D, OtherT> const& v) : normal(v.normal), dis(v.dis)
{
}
[[nodiscard]] bool operator==(halfspace const& rhs) const { return normal == rhs.normal && dis == rhs.dis; }
[[nodiscard]] bool operator!=(halfspace const& rhs) const { return !operator==(rhs); }
};
......
......@@ -63,6 +63,11 @@ struct hemisphere
constexpr hemisphere() = default;
constexpr hemisphere(pos_t const& c, ScalarT r, dir_t const& normal) : center(c), radius(r), normal(normal) {}
template <class OtherT, class OtherTraitsT>
constexpr hemisphere(hemisphere<D, OtherT, OtherTraitsT> const& v) : center(v.center), radius(v.radius), normal(v.normal)
{
}
[[nodiscard]] bool operator==(hemisphere const& rhs) const { return center == rhs.center && radius == rhs.radius && normal == rhs.normal; }
[[nodiscard]] bool operator!=(hemisphere const& rhs) const { return !operator==(rhs); }
};
......
......@@ -44,6 +44,11 @@ struct inf_cone
}
explicit constexpr inf_cone(cone<D, ScalarT, TraitsT> const& c);
template <class OtherT, class OtherTraitsT>
constexpr inf_cone(inf_cone<D, OtherT, OtherTraitsT> const& v) : apex(v.apex), opening_dir(v.opening_dir), opening_angle(v.opening_angle)
{
}
[[nodiscard]] bool operator==(inf_cone const& rhs) const
{
return apex == rhs.apex && opening_dir == rhs.opening_dir && opening_angle == rhs.opening_angle;
......
......@@ -39,6 +39,11 @@ struct inf_cylinder
constexpr inf_cylinder() = default;
constexpr inf_cylinder(line_t const& axis, ScalarT radius) : axis(axis), radius(radius) {}
template <class OtherT, class OtherTraitsT>
constexpr inf_cylinder(inf_cylinder<D, OtherT, OtherTraitsT> const& v) : axis(v.axis), radius(v.radius)
{
}
[[nodiscard]] bool operator==(inf_cylinder const& rhs) const { return axis == rhs.axis && radius == rhs.radius; }
[[nodiscard]] bool operator!=(inf_cylinder const& rhs) const { return !operator==(rhs); }
};
......
......@@ -55,6 +55,11 @@ struct line
constexpr line() = default;
constexpr line(pos_t p, dir_t dir) : pos(p), dir(dir) {}
template <class OtherT>
constexpr line(line<D, OtherT> const& v) : pos(v.pos), dir(v.dir)
{
}
static constexpr line from_points(pos_t a, pos_t b);
[[nodiscard]] constexpr pos_t operator[](ScalarT t) const;
......
......@@ -63,6 +63,11 @@ struct plane
constexpr plane(dir_t n, scalar_t d) : normal(n), dis(d) {}
constexpr plane(dir_t n, pos_t p);
template <class OtherT>
constexpr plane(plane<D, OtherT> const& v) : normal(v.normal), dis(v.dis)
{
}
[[nodiscard]] bool operator==(plane const& rhs) const { return normal == rhs.normal && dis == rhs.dis; }
[[nodiscard]] bool operator!=(plane const& rhs) const { return !operator==(rhs); }
};
......
......@@ -46,6 +46,11 @@ struct pyramid
constexpr pyramid() = default;
constexpr pyramid(base_t const& base, scalar_t height) : base(base), height(height) {}
template <class OtherT, class OtherTraitsT>
constexpr pyramid(pyramid<OtherT, OtherTraitsT> const& v) : base(v.base), height(v.height)
{
}
[[nodiscard]] bool operator==(pyramid const& rhs) const { return base == rhs.base && height == rhs.height; }
[[nodiscard]] bool operator!=(pyramid const& rhs) const { return !operator==(rhs); }
};
......
......@@ -51,7 +51,12 @@ struct quad
constexpr quad() = default;
constexpr quad(pos_t p00, pos_t p10, pos_t p11, pos_t p01) : pos00(p00), pos10(p10), pos11(p11), pos01(p01) {}
template <class Range, class = std::void_t<decltype(pos_t(tg::begin(std::declval<Range>())))>>
template <class OtherT>
constexpr quad(quad<D, OtherT> const& v) : pos00(v.pos00), pos10(v.pos10), pos11(v.pos11), pos01(v.pos01)
{
}
template <class Range, class = std::enable_if_t<tg::is_range<Range, pos_t>>>
explicit constexpr quad(Range&& r)
{
auto it = tg::begin(r);
......
......@@ -53,6 +53,11 @@ struct ray
constexpr ray() = default;
constexpr ray(pos_t origin, dir_t dir) : origin(origin), dir(dir) {}
template <class OtherT>
constexpr ray(ray<D, OtherT> const& v) : origin(v.origin), dir(v.dir)
{
}
[[nodiscard]] constexpr pos_t operator[](ScalarT t) const;
[[nodiscard]] bool operator==(ray const& rhs) const { return origin == rhs.origin && dir == rhs.dir; }
......
......@@ -52,6 +52,23 @@ struct segment
constexpr segment() = default;
constexpr segment(pos_t p0, pos_t p1) : pos0(p0), pos1(p1) {}
template <class OtherT>
constexpr segment(segment<D, OtherT> const& v) : pos0(v.pos0), pos1(v.pos1)
{
}
template <class Range, class = std::enable_if_t<tg::is_range<Range, pos_t>>>
explicit constexpr segment(Range&& r)
{
auto it = tg::begin(r);
auto end = tg::end(r);
TG_CONTRACT(it != end);
pos0 = pos_t(*it++);
TG_CONTRACT(it != end);
pos1 = pos_t(*it++);
TG_CONTRACT(!(it != end));
}
[[nodiscard]] constexpr pos_t operator[](ScalarT t) const;
[[nodiscard]] bool operator==(segment const& rhs) const { return pos0 == rhs.pos0 && pos1 == rhs.pos1; }
......
......@@ -101,6 +101,11 @@ struct sphere<D, ScalarT, D, TraitsT>
constexpr sphere() = default;
constexpr sphere(pos_t c, ScalarT r) : center(c), radius(r) {}
template <class OtherT, class OtherTraitsT>
constexpr sphere(sphere<D, OtherT, D, OtherTraitsT> const& v) : center(v.center), radius(v.radius)
{
}
[[nodiscard]] bool operator==(sphere const& rhs) const { return center == rhs.center && radius == rhs.radius; }
[[nodiscard]] bool operator!=(sphere const& rhs) const { return !operator==(rhs); }
};
......@@ -119,6 +124,11 @@ struct sphere<2, ScalarT, 3, TraitsT>
constexpr sphere() = default;
constexpr sphere(pos_t c, ScalarT r, dir_t n) : center(c), radius(r), normal(n) {}
template <class OtherT, class OtherTraitsT>
constexpr sphere(sphere<2, OtherT, 3, OtherTraitsT> const& v) : center(v.center), radius(v.radius), normal(v.normal)
{
}
[[nodiscard]] bool operator==(sphere const& rhs) const { return center == rhs.center && radius == rhs.radius && normal == rhs.normal; }
[[nodiscard]] bool operator!=(sphere const& rhs) const { return !operator==(rhs); }
};
......
......@@ -50,7 +50,12 @@ struct triangle
constexpr triangle() = default;
constexpr triangle(pos_t p0, pos_t p1, pos_t p2) : pos0(p0), pos1(p1), pos2(p2) {}
template <class Range, class = std::void_t<decltype(pos_t(tg::begin(std::declval<Range>())))>>
template <class OtherT>
constexpr triangle(triangle<D, OtherT> const& v) : pos0(v.pos0), pos1(v.pos1), pos2(v.pos2)
{
}
template <class Range, class = std::enable_if_t<tg::is_range<Range, pos_t>>>
explicit constexpr triangle(Range&& r)
{
auto it = tg::begin(r);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment