GEOSX
Format.hpp
1 /*
2  * ------------------------------------------------------------------------------------------------------------
3  * SPDX-License-Identifier: LGPL-2.1-only
4  *
5  * Copyright (c) 2018-2020 Lawrence Livermore National Security LLC
6  * Copyright (c) 2018-2020 The Board of Trustees of the Leland Stanford Junior University
7  * Copyright (c) 2018-2020 TotalEnergies
8  * Copyright (c) 2019- GEOSX Contributors
9  * All rights reserved
10  *
11  * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details.
12  * ------------------------------------------------------------------------------------------------------------
13  */
14 
15 #ifndef GEOS_COMMON_FORMAT_HPP_
16 #define GEOS_COMMON_FORMAT_HPP_
17 
18 #include <type_traits>
19 
20 #if __cplusplus < 202002L
21 #define GEOSX_USE_FMT
22 #endif
23 
24 #ifdef GEOSX_USE_FMT
25 #define FMT_HEADER_ONLY
26 // Differentiate between standalone fmt path and umpire's fmt path
27 #include "../include/fmt/core.h"
28 #include "../include/fmt/chrono.h"
29 #include "../include/fmt/ranges.h"
30 #include "../include/fmt/xchar.h"
31 #define GEOS_FMT_NS fmt
32 #else // use C++20's <format>
33 #include <format>
34 #define GEOS_FMT_NS std
35 #endif
36 
37 #ifdef GEOSX_USE_FMT
43 template< typename T >
44 struct fmt::formatter< T, std::enable_if_t< std::is_enum< T >::value > >
45 {
52  template< typename ParseContext >
53  constexpr auto parse( ParseContext & ctx )
54  {
55  return ctx.end();
56  }
57 
65  template< typename FormatContext >
66  auto format( const T & value, FormatContext & ctx )
67  {
68  return fmt::format_to( ctx.out(), "{}", static_cast< std::underlying_type_t< T > >( value ) );
69  }
70 };
71 #endif
72 
77 #define GEOS_FMT( msg, ... ) GEOS_FMT_NS::format( msg, __VA_ARGS__ )
78 
86 #define GEOS_FMT_TO( iter, size, msg, ... ) *GEOS_FMT_NS::format_to_n( iter, size - 1, msg, __VA_ARGS__ ).out = '\0'
87 
88 // The following workaround is needed to fix compilation with NVCC on some PowerPC machines.
89 // The issue causes the following assertion error message:
90 // "Cannot format an argument. To make type T formattable provide a formatter<T> specialization"
91 // The standard definition of the has_const_formatter check of fmt fails due to a compiler bug, see the issue below:
92 // https://github.com/fmtlib/fmt/issues/2746
93 // The workaround was originally implemented in fmt:
94 // https://github.com/fmtlib/fmt/commit/70de324aa801eaf52e94c402d526a3849797c620
95 // but later removed:
96 // https://github.com/fmtlib/fmt/commit/466e0650ec2d153d255a40ec230eb77d7f1c3334
97 // This workaround bypasse the check for a const formatter whenever the foramt context GEOS_FMT_NS::format_context is used
98 #ifdef GEOS_USE_FMT_CONST_FORMATTER_WORKAROUND
99 template< >
100 constexpr auto GEOS_FMT_NS::detail::has_const_formatter_impl< GEOS_FMT_NS::format_context >( ... ) -> bool
101 {
102  return true;
103 }
104 #endif
105 // End of the workaround for fmt compilation issues
106 
107 #endif //GEOS_COMMON_FORMAT_HPP_
auto format(const T &value, FormatContext &ctx)
Formatter for the fmtlib formatting library.
Definition: Format.hpp:66
constexpr auto parse(ParseContext &ctx)
Parser for the fmtlib formatting library.
Definition: Format.hpp:53