blob: 349da1db5f661da1d39a370a617b05d68a157865 [file] [log] [blame]
//===--- SimpleDisplay.h - Simple Type Display ------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines the main customization point, simple_display, for
// displaying values of a given type
// encoding of (static) type information for use as a simple replacement
// for run-time type information.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_BASIC_SIMPLE_DISPLAY_H
#define SWIFT_BASIC_SIMPLE_DISPLAY_H
#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/Support/raw_ostream.h"
#include <tuple>
#include <type_traits>
#include <utility>
namespace swift {
template<typename T>
struct HasTrivialDisplay {
static const bool value = false;
};
#define HAS_TRIVIAL_DISPLAY(Type) \
template<> \
struct HasTrivialDisplay<Type> { \
static const bool value = true; \
}
HAS_TRIVIAL_DISPLAY(unsigned char);
HAS_TRIVIAL_DISPLAY(signed char);
HAS_TRIVIAL_DISPLAY(char);
HAS_TRIVIAL_DISPLAY(short);
HAS_TRIVIAL_DISPLAY(unsigned short);
HAS_TRIVIAL_DISPLAY(int);
HAS_TRIVIAL_DISPLAY(unsigned int);
HAS_TRIVIAL_DISPLAY(long);
HAS_TRIVIAL_DISPLAY(unsigned long);
HAS_TRIVIAL_DISPLAY(long long);
HAS_TRIVIAL_DISPLAY(unsigned long long);
HAS_TRIVIAL_DISPLAY(float);
HAS_TRIVIAL_DISPLAY(double);
HAS_TRIVIAL_DISPLAY(bool);
HAS_TRIVIAL_DISPLAY(std::string);
#undef HAS_TRIVIAL_DISPLAY
template<typename T>
typename std::enable_if<HasTrivialDisplay<T>::value>::type
simple_display(llvm::raw_ostream &out, const T &value) {
out << value;
}
template<unsigned I, typename ...Types,
typename std::enable_if<I == sizeof...(Types)>::type* = nullptr>
void simple_display_tuple(llvm::raw_ostream &out,
const std::tuple<Types...> &value);
template<unsigned I, typename ...Types,
typename std::enable_if<I < sizeof...(Types)>::type* = nullptr>
void simple_display_tuple(llvm::raw_ostream &out,
const std::tuple<Types...> &value) {
// Start or separator.
if (I == 0) out << "(";
else out << ", ";
// Current element.
simple_display(out, std::get<I>(value));
// Print the remaining elements.
simple_display_tuple<I+1>(out, value);
}
template<unsigned I, typename ...Types,
typename std::enable_if<I == sizeof...(Types)>::type*>
void simple_display_tuple(llvm::raw_ostream &out,
const std::tuple<Types...> &value) {
// Last element.
out << ")";
}
template<typename ...Types>
void simple_display(llvm::raw_ostream &out,
const std::tuple<Types...> &value) {
simple_display_tuple<0>(out, value);
}
template<typename T1, typename T2>
void simple_display(llvm::raw_ostream &out,
const std::pair<T1, T2> &value) {
out << "(";
simple_display(out, value.first);
out << ", ";
simple_display(out, value.second);
out << ")";
}
template<typename T>
void simple_display(llvm::raw_ostream &out,
const llvm::TinyPtrVector<T> &vector) {
out << "{";
bool first = true;
for (const T &value : vector) {
if (first) first = false;
else out << ", ";
simple_display(out, value);
}
out << "}";
}
template<typename T>
void simple_display(llvm::raw_ostream &out,
const llvm::ArrayRef<T> &array) {
out << "{";
bool first = true;
for (const T &value : array) {
if (first) first = false;
else out << ", ";
simple_display(out, value);
}
out << "}";
}
template<typename T>
void simple_display(llvm::raw_ostream &out,
const llvm::SmallVectorImpl<T> &vec) {
out << "{";
bool first = true;
for (const T &value : vec) {
if (first) first = false;
else out << ", ";
simple_display(out, value);
}
out << "}";
}
template<typename T>
void simple_display(llvm::raw_ostream &out,
const std::vector<T> &vec) {
out << "{";
bool first = true;
for (const T &value : vec) {
if (first) first = false;
else out << ", ";
simple_display(out, value);
}
out << "}";
}
template<typename T, typename U>
void simple_display(llvm::raw_ostream &out,
const llvm::PointerUnion<T, U> &ptrUnion) {
if (const auto t = ptrUnion.template dyn_cast<T>())
simple_display(out, t);
else
simple_display(out, ptrUnion.template get<U>());
}
}
#endif // SWIFT_BASIC_SIMPLE_DISPLAY_H