diff --git a/Installation/include/CGAL/config.h b/Installation/include/CGAL/config.h index c31b233091e..ed00178900b 100644 --- a/Installation/include/CGAL/config.h +++ b/Installation/include/CGAL/config.h @@ -293,7 +293,9 @@ using std::max; // Macros to detect features of clang. We define them for the other // compilers. // See https://clang.llvm.org/docs/LanguageExtensions.html -// See also https://en.cppreference.com/w/cpp/experimental/feature_test +// +// Some of those macro have been standardized. See C++20 feature testing: +// https://en.cppreference.com/w/cpp/feature_test #ifndef __has_feature #define __has_feature(x) 0 // Compatibility with non-clang compilers. #endif @@ -316,6 +318,10 @@ using std::max; #define __has_warning(x) 0 // Compatibility with non-clang compilers. #endif +#if __has_include() +# include +#endif + // Macro to specify a 'unused' attribute. #if __has_cpp_attribute(maybe_unused) # define CGAL_UNUSED [[maybe_unused]] diff --git a/STL_Extension/include/CGAL/Compact_container.h b/STL_Extension/include/CGAL/Compact_container.h index 81ff5cf1bce..8e665e83c1e 100644 --- a/STL_Extension/include/CGAL/Compact_container.h +++ b/STL_Extension/include/CGAL/Compact_container.h @@ -1166,6 +1166,24 @@ public: } }; +struct With_point_tag {}; + +template +struct Output_rep, With_point_tag> + : public Output_rep> +{ + using Base = Output_rep>; + using Base::Base; + + std::ostream& operator()(std::ostream& out) const { + Base::operator()(out); + if(this->it.operator->() != nullptr) + return out << "= " << this->it->point(); + else + return out; + } +}; + } //namespace CGAL namespace std { diff --git a/STL_Extension/include/CGAL/Time_stamper.h b/STL_Extension/include/CGAL/Time_stamper.h index f48f5307ef0..0fcee819220 100644 --- a/STL_Extension/include/CGAL/Time_stamper.h +++ b/STL_Extension/include/CGAL/Time_stamper.h @@ -69,7 +69,10 @@ struct Time_stamper static auto display_id(const T* pt) { - return std::string("#") + std::to_string(pt->time_stamp()); + if(pt == nullptr) + return std::string("nullptr"); + else + return std::string("#") + std::to_string(pt->time_stamp()); } static std::size_t hash_value(const T* p) { diff --git a/Stream_support/include/CGAL/IO/io.h b/Stream_support/include/CGAL/IO/io.h index d9c2ea7f761..7dd4e0c7e15 100644 --- a/Stream_support/include/CGAL/IO/io.h +++ b/Stream_support/include/CGAL/IO/io.h @@ -990,6 +990,52 @@ inline void read_float_or_quotient(std::istream& is, Rat &z) } // namespace CGAL +#if __has_include() && \ + (__cpp_lib_format >= 201907L || __cplusplus >= 202000L || _MSVC_LANG >= 202000L) +# include +# include + +namespace std { + +template +struct formatter, CharT> : public std::formatter> +{ + constexpr auto parse(std::basic_format_parse_context& ctx) + { + auto it = ctx.begin(); + const auto end = ctx.end(); + if(it == end) + return it; + if(*it != CharT('.')) + return it; + if(++it == end) + throw std::format_error("Missing precision"); + if(*it < CharT('0') || *it > CharT('9')) + throw std::format_error("Invalid value for precision"); + precision = *it - CharT('0'); + while(++it != end) { + if(*it < CharT('0') || *it > CharT('9')) + return it; + precision = precision * 10 + (*it - CharT('0')); + } + return it; + } + + template + auto format(const CGAL::Output_rep &rep, FormatContext& ctx) const + { + std::basic_stringstream ss; + ss.precision(precision); + ss << rep; + return std::formatter>::format(ss.str(), ctx); + } + + int precision = 17; +}; + +} // namespace std +#endif // __cpp_lib_format >= 201907L + #include #endif // CGAL_IO_H diff --git a/Triangulation_2/include/CGAL/Constrained_triangulation_2.h b/Triangulation_2/include/CGAL/Constrained_triangulation_2.h index 884644147f1..42c8cb407ca 100644 --- a/Triangulation_2/include/CGAL/Constrained_triangulation_2.h +++ b/Triangulation_2/include/CGAL/Constrained_triangulation_2.h @@ -37,28 +37,6 @@ #include #include -#ifdef CGAL_CDT_2_DEBUG_INTERSECTIONS -# include -# include -# include -namespace CGAL { - -struct With_point_tag {}; - -template -struct Output_rep, With_point_tag> - : public Output_rep> -{ - using Base = Output_rep>; - using Base::Base; - - std::ostream& operator()(std::ostream& out) const { - return Base::operator()(out) << "= " << this->it->point(); - } -}; -} // namespace CGAL -#endif // CGAL_CDT_2_DEBUG_INTERSECTIONS - namespace CGAL { struct No_constraint_intersection_tag{};