LCOV - code coverage report
Current view: top level - include/llvm/Support - FormatVariadicDetails.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 9 9 100.0 %
Date: 2018-07-13 00:08:38 Functions: 104 447 23.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- FormatVariadicDetails.h - Helpers for FormatVariadic.h ----*- C++-*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : 
      10             : #ifndef LLVM_SUPPORT_FORMATVARIADIC_DETAILS_H
      11             : #define LLVM_SUPPORT_FORMATVARIADIC_DETAILS_H
      12             : 
      13             : #include "llvm/ADT/StringRef.h"
      14             : #include "llvm/Support/raw_ostream.h"
      15             : 
      16             : #include <type_traits>
      17             : 
      18             : namespace llvm {
      19             : template <typename T, typename Enable = void> struct format_provider {};
      20             : 
      21             : namespace detail {
      22      145530 : class format_adapter {
      23             : protected:
      24             :   virtual ~format_adapter() {}
      25             : 
      26             : public:
      27             :   virtual void format(raw_ostream &S, StringRef Options) = 0;
      28             : };
      29             : 
      30      401867 : template <typename T> class provider_format_adapter : public format_adapter {
      31             :   T Item;
      32             : 
      33             : public:
      34       11017 :   explicit provider_format_adapter(T &&Item) : Item(std::forward<T>(Item)) {}
      35             : 
      36      143590 :   void format(llvm::raw_ostream &S, StringRef Options) override {
      37      153578 :     format_provider<typename std::decay<T>::type>::format(Item, S, Options);
      38      143590 :   }
      39             : };
      40             : 
      41             : template <typename T>
      42          15 : class stream_operator_format_adapter : public format_adapter {
      43             :   T Item;
      44             : 
      45             : public:
      46             :   explicit stream_operator_format_adapter(T &&Item)
      47           2 :       : Item(std::forward<T>(Item)) {}
      48             : 
      49           3 :   void format(llvm::raw_ostream &S, StringRef Options) override { S << Item; }
      50             : };
      51             : 
      52             : template <typename T> class missing_format_adapter;
      53             : 
      54             : // Test if format_provider<T> is defined on T and contains a member function
      55             : // with the signature:
      56             : //   static void format(const T&, raw_stream &, StringRef);
      57             : //
      58             : template <class T> class has_FormatProvider {
      59             : public:
      60             :   using Decayed = typename std::decay<T>::type;
      61             :   typedef void (*Signature_format)(const Decayed &, llvm::raw_ostream &,
      62             :                                    StringRef);
      63             : 
      64             :   template <typename U>
      65             :   static char test(SameType<Signature_format, &U::format> *);
      66             : 
      67             :   template <typename U> static double test(...);
      68             : 
      69             :   static bool const value =
      70             :       (sizeof(test<llvm::format_provider<Decayed>>(nullptr)) == 1);
      71             : };
      72             : 
      73             : // Test if raw_ostream& << T -> raw_ostream& is findable via ADL.
      74             : template <class T> class has_StreamOperator {
      75             : public:
      76             :   using ConstRefT = const typename std::decay<T>::type &;
      77             : 
      78             :   template <typename U>
      79             :   static char test(typename std::enable_if<
      80             :                    std::is_same<decltype(std::declval<llvm::raw_ostream &>()
      81             :                                          << std::declval<U>()),
      82             :                                 llvm::raw_ostream &>::value,
      83             :                    int *>::type);
      84             : 
      85             :   template <typename U> static double test(...);
      86             : 
      87             :   static bool const value = (sizeof(test<ConstRefT>(nullptr)) == 1);
      88             : };
      89             : 
      90             : // Simple template that decides whether a type T should use the member-function
      91             : // based format() invocation.
      92             : template <typename T>
      93             : struct uses_format_member
      94             :     : public std::integral_constant<
      95             :           bool,
      96             :           std::is_base_of<format_adapter,
      97             :                           typename std::remove_reference<T>::type>::value> {};
      98             : 
      99             : // Simple template that decides whether a type T should use the format_provider
     100             : // based format() invocation.  The member function takes priority, so this test
     101             : // will only be true if there is not ALSO a format member.
     102             : template <typename T>
     103             : struct uses_format_provider
     104             :     : public std::integral_constant<
     105             :           bool, !uses_format_member<T>::value && has_FormatProvider<T>::value> {
     106             : };
     107             : 
     108             : // Simple template that decides whether a type T should use the operator<<
     109             : // based format() invocation.  This takes last priority.
     110             : template <typename T>
     111             : struct uses_stream_operator
     112             :     : public std::integral_constant<bool, !uses_format_member<T>::value &&
     113             :                                               !uses_format_provider<T>::value &&
     114             :                                               has_StreamOperator<T>::value> {};
     115             : 
     116             : // Simple template that decides whether a type T has neither a member-function
     117             : // nor format_provider based implementation that it can use.  Mostly used so
     118             : // that the compiler spits out a nice diagnostic when a type with no format
     119             : // implementation can be located.
     120             : template <typename T>
     121             : struct uses_missing_provider
     122             :     : public std::integral_constant<bool, !uses_format_member<T>::value &&
     123             :                                               !uses_format_provider<T>::value &&
     124             :                                               !uses_stream_operator<T>::value> {
     125             : };
     126             : 
     127             : template <typename T>
     128             : typename std::enable_if<uses_format_member<T>::value, T>::type
     129             : build_format_adapter(T &&Item) {
     130             :   return std::forward<T>(Item);
     131             : }
     132             : 
     133             : template <typename T>
     134             : typename std::enable_if<uses_format_provider<T>::value,
     135             :                         provider_format_adapter<T>>::type
     136             : build_format_adapter(T &&Item) {
     137             :   return provider_format_adapter<T>(std::forward<T>(Item));
     138             : }
     139             : 
     140             : template <typename T>
     141             : typename std::enable_if<uses_stream_operator<T>::value,
     142             :                         stream_operator_format_adapter<T>>::type
     143             : build_format_adapter(T &&Item) {
     144             :   return stream_operator_format_adapter<T>(std::forward<T>(Item));
     145             : }
     146             : 
     147             : template <typename T>
     148             : typename std::enable_if<uses_missing_provider<T>::value,
     149             :                         missing_format_adapter<T>>::type
     150             : build_format_adapter(T &&Item) {
     151             :   return missing_format_adapter<T>();
     152             : }
     153             : }
     154             : }
     155             : 
     156             : #endif

Generated by: LCOV version 1.13