IMHO, crossing the lines gives an object, so it would be fair to have
boost::variant<Empty, Point, Line> intersect(Line const & l1, Line const & l2)
and helper functions like
boost::optional<Point> getIntersectionPoint(Line const & l1, Line const & l2)
bool isParallel(Line const & l1, Line const & l2)
Edit: If you do not want to use the boost library, you can easily create simple analogs:
struct intersection_result_t { enum isec_t { isec_empty, isec_point, isec_line } intersection_result_t() : type_(isec_empty) { new (storage_) Empty(); } intersection_result_t(Empty const & e) : type_(isec_empty) { new (storage_) Empty(e); } intersection_result_t(Point const & p) : type_(isec_point) { new (storage_) Point(p); } ... intersection_result_t(intersection_result_t & ir) : type_(ir.type_) { switch(ir.type_) { case isec_empty: new (storage_) Empty(*static_cast<Empty*>(ir.storage_)); case .... } } private: void destroy() { switch(type_) { case isec_empty: operator delete (static_cast<Empty*>(storage_), storage_); case .... } } private: char storage_[MAX(sizeof(Empty), sizeof(Point), sizeof(Line))]; isec_t type_; };
etc. etc. A few more switches are required. Or you can use patterns. For additional use, use initialized_
instead of type_
to track the state of the construct.
source share