1 //===-- include/flang/Evaluate/formatting.h ---------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef FORTRAN_EVALUATE_FORMATTING_H_ 10 #define FORTRAN_EVALUATE_FORMATTING_H_ 11 12 // It is inconvenient in C++ to have llvm::raw_ostream::operator<<() as a direct 13 // friend function of a class template with many instantiations, so the 14 // various representational class templates in lib/Evaluate format themselves 15 // via AsFortran(llvm::raw_ostream &) member functions, which the operator<<() 16 // overload below will call. Others have AsFortran() member functions that 17 // return strings. 18 // 19 // This header is meant to be included by the headers that define the several 20 // representational class templates that need it, not by external clients. 21 22 #include "flang/Common/indirection.h" 23 #include "llvm/Support/raw_ostream.h" 24 #include <optional> 25 #include <type_traits> 26 27 namespace Fortran::evaluate { 28 29 template <typename A> 30 auto operator<<(llvm::raw_ostream &o, const A &x) -> decltype(x.AsFortran(o)) { 31 return x.AsFortran(o); 32 } 33 34 template <typename A> 35 auto operator<<(llvm::raw_ostream &o, const A &x) 36 -> decltype(o << x.AsFortran()) { 37 return o << x.AsFortran(); 38 } 39 40 template <typename A, bool COPYABLE> 41 auto operator<<( 42 llvm::raw_ostream &o, const Fortran::common::Indirection<A, COPYABLE> &x) 43 -> decltype(o << x.value()) { 44 return o << x.value(); 45 } 46 47 template <typename A> 48 auto operator<<(llvm::raw_ostream &o, const std::optional<A> &x) 49 -> decltype(o << *x) { 50 if (x) { 51 o << *x; 52 } else { 53 o << "(nullopt)"; 54 } 55 return o; 56 } 57 } // namespace Fortran::evaluate 58 #endif // FORTRAN_EVALUATE_FORMATTING_H_ 59