// Copyright (c) 2003 // Utrecht University (The Netherlands), // ETH Zurich (Switzerland), // INRIA Sophia-Antipolis (France), // Max-Planck-Institute Saarbruecken (Germany), // and Tel-Aviv University (Israel). All rights reserved. // // This file is part of CGAL (www.cgal.org) // // $URL$ // $Id$ // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Michael Hoffmann // Lutz Kettner // Sylvain Pion #ifndef CGAL_UTILITY_H #define CGAL_UTILITY_H 1 #include #include #include #include #include // The Triple and Quadruple classes are NOT RECOMMENDED anymore. // We recommend that you use std::tuple or std::array instead // for new uses. namespace CGAL { namespace internal { template struct Tuple_get; template struct Tuple_get<0, T> { typedef typename T::first_type result_type; static result_type & get(T & t) { return t.first; } static result_type const & get(T const & t) { return t.first; } }; template struct Tuple_get<1, T> { typedef typename T::second_type result_type; static result_type & get(T & t) { return t.second; } static result_type const & get(T const & t) { return t.second; } }; template struct Tuple_get<2, T> { typedef typename T::third_type result_type; static result_type & get(T & t) { return t.third; } static result_type const & get(T const & t) { return t.third; } }; template struct Tuple_get<3, T> { typedef typename T::fourth_type result_type; static result_type & get(T & t) { return t.fourth; } static result_type const & get(T const & t) { return t.fourth; } }; } //+---------------------------------------------------------------------+ //| Triple class | //+---------------------------------------------------------------------+ template class Triple { typedef Triple Self; public: typedef T1 first_type; typedef T2 second_type; typedef T3 third_type; T1 first; T2 second; T3 third; Triple() {} Triple(const T1& a, const T2& b, const T3& c) : first(a), second(b), third(c) {} template Triple(const U& a, const V& b, const W& c) : first(a), second(b), third(c) {} template Triple& operator=(const Triple &t) { first = t.first; second = t.second; third = t.third; return *this; } template < int i > typename internal::Tuple_get::result_type const & get() const { return internal::Tuple_get::get(*this); } template < int i > typename internal::Tuple_get::result_type & get() { return internal::Tuple_get::get(*this); } friend std::size_t hash_value(Triple const& t) { std::size_t seed = 0; boost::hash_combine(seed, t.first); boost::hash_combine(seed, t.second); boost::hash_combine(seed, t.third); return seed; } }; template inline Triple make_triple(const T1& x, const T2& y, const T3& z) { return Triple(x, y, z); } template inline Triple make_tuple(const T1& x, const T2& y, const T3& z) { return Triple(x, y, z); } template inline bool operator==(const Triple& x, const Triple& y) { return ( (x.first == y.first) && (x.second == y.second) && (x.third == y.third) ); } template inline bool operator!=(const Triple& x, const Triple& y) { return !(x == y); } template inline bool operator<(const Triple& x, const Triple& y) { return ( x.first < y.first || ( !(y.first < x.first) && ( x.second < y.second || ( !(y.second < x.second) && x.third < y.third ) ) ) ); } //+---------------------------------------------------------------------+ //| Quadruple class | //+---------------------------------------------------------------------+ template class Quadruple { typedef Quadruple Self; public: typedef T1 first_type; typedef T2 second_type; typedef T3 third_type; typedef T4 fourth_type; T1 first; T2 second; T3 third; T4 fourth; Quadruple() {} Quadruple(const T1& a, const T2& b, const T3& c, const T4& d) : first(a), second(b), third(c), fourth(d) {} template Quadruple(const U& a, const V& b, const W& c, const X& d) : first(a), second(b), third(c), fourth(d) {} template Quadruple& operator=(const Quadruple &q) { first = q.first; second = q.second; third = q.third; fourth = q.fourth; return *this; } template < int i > typename internal::Tuple_get::result_type const & get() const { return internal::Tuple_get::get(*this); } template < int i > typename internal::Tuple_get::result_type & get() { return internal::Tuple_get::get(*this); } }; template inline Quadruple make_quadruple(const T1& x, const T2& y, const T3& z, const T4& zz) { return Quadruple(x, y, z, zz); } template inline Quadruple make_tuple(const T1& x, const T2& y, const T3& z, const T4& zz) { return Quadruple(x, y, z, zz); } template inline bool operator==(const Quadruple& x, const Quadruple& y) { return ( (x.first == y.first) && (x.second == y.second) && (x.third == y.third) && (x.fourth == y.fourth) ); } template inline bool operator!=(const Quadruple& x, const Quadruple& y) { return ! (x == y); } template inline bool operator<(const Quadruple& x, const Quadruple& y) { return ( x.first < y.first || ( !(y.first < x.first) && ( x.second < y.second || ( !(y.second < x.second) && ( x.third < y.third || (!(y.third < x.third) && x.fourth < y.fourth)) ) ) ) ); } struct Default_using_type { template struct Get { typedef Argument type; }; template struct Get { typedef typename Value::type type; }; }; template , class T1, class T2, class A = typename Default_using_type::Get::type, typename std::decay::type > >::type, class P = std::pair > inline P make_sorted_pair(T1&& t1, T2&& t2, Compare comp = Compare()) { return comp(t1, t2) ? P(std::forward(t1), std::forward(t2)) : P(std::forward(t2), std::forward(t1)); } template auto make_sorted_pair(Pair&& pair) { auto&& [a, b] = std::forward(pair); return make_sorted_pair(std::forward(a), std::forward(b)); } template class [[nodiscard]] Scope_exit { CGAL_NO_UNIQUE_ADDRESS F exit_function; public: template explicit Scope_exit(G&& g, std::enable_if_t, Scope_exit>>* = nullptr) : exit_function(std::forward(g)) { } Scope_exit(const Scope_exit&) = delete; Scope_exit& operator=(const Scope_exit&) = delete; Scope_exit(Scope_exit&&) = delete; Scope_exit& operator=(Scope_exit&&) = delete; ~Scope_exit() { exit_function(); } }; template Scope_exit(F) -> Scope_exit; template Scope_exit make_scope_exit(F&& f) { return Scope_exit(std::forward(f)); } template struct overloaded : Ts... { using Ts::operator()...; }; template overloaded(Ts...) -> overloaded; } //namespace CGAL namespace std { #if defined(BOOST_MSVC) # pragma warning(push) # pragma warning(disable:4099) // For VC10 it is class hash #endif #ifndef CGAL_CFG_NO_STD_HASH template struct hash> { std::size_t operator()(const CGAL::Triple& t) const { return hash_value(t); } }; #endif // CGAL_CFG_NO_STD_HASH #if defined(BOOST_MSVC) # pragma warning(pop) #endif } // std namespace #endif // CGAL_UTILITY_H