lean4-htt/src/util/format.h
2020-05-22 14:17:25 -07:00

97 lines
3.6 KiB
C++

/*
Copyright (c) 2013 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Soonho Kong
*/
#pragma once
#include <algorithm>
#include <iostream>
#include <numeric>
#include <sstream>
#include <utility>
#include <string>
#include <vector>
#include <lean/debug.h>
#include "util/object_ref.h"
#include "util/name.h"
#include "util/pair.h"
namespace lean {
class options;
/**
inductive Format
| nil : Format
| line : Format
| text : String → Format
| nest : Nat → Format → Format
| compose : Bool → Format → Format → Format
| choice : Format → Format → Format
*/
class format : public object_ref {
enum format_kind { NIL, LINE, TEXT, NEST, COMPOSE, CHOICE };
public:
// Constructors
format():object_ref(box(static_cast<unsigned>(NIL))) {}
explicit format(object * o):object_ref(o) {}
explicit format(object_ref const & o):object_ref(o) {}
format(object * o, bool b):object_ref(o, b) {}
explicit format(char const * v):object_ref(mk_cnstr(static_cast<unsigned>(TEXT), mk_string(v))) {}
explicit format(std::string const & v):object_ref(mk_cnstr(static_cast<unsigned>(TEXT), mk_string(v))) {}
explicit format(string_ref const & v):object_ref(mk_cnstr(static_cast<unsigned>(TEXT), v)) {}
explicit format(int v):format(std::to_string(v)) {}
explicit format(unsigned v):format(std::to_string(v)) {}
explicit format(name const & v):format(v.to_string()) {}
format(format const & f):object_ref(f) {}
format(format && other):object_ref(other) {}
format & operator=(format const & other) { object_ref::operator=(other); return *this; }
format & operator=(format && other) { object_ref::operator=(other); return *this; }
format(format const & f1, format const & f2);
format_kind kind() const { return static_cast<format_kind>(cnstr_tag(raw())); }
bool is_nil_fmt() const { return kind() == format_kind::NIL; }
friend format compose(format const & f1, format const & f2);
friend format nest(int i, format const & f);
friend format group(format const & f);
friend format bracket(std::string const & l, format const & x, std::string const & r);
// x + y = x <> y
friend format operator+(format const & f1, format const & f2);
format & operator+=(format const & f) {
*this = *this + f;
return *this;
}
static std::ostream & pretty(std::ostream & out, unsigned w, format const & f);
friend std::ostream & pretty(std::ostream & out, unsigned w, format const & f);
friend std::ostream & pretty(std::ostream & out, options const & o, format const & f);
friend std::ostream & operator<<(std::ostream & out, format const & f);
friend std::ostream & operator<<(std::ostream & out, pair<format const &, options const &> const & p);
friend void initialize_format();
};
format compose(format const & f1, format const & f2);
format nest(int i, format const & f);
format line();
format space();
format bracket(std::string const & l, format const & x, std::string const & r);
format group(format const & f);
format paren(format const & x);
class options;
/** \brief Extract indentation from options */
unsigned get_pp_indent(options const & o);
/** \brief Return unicode characters flag */
bool get_pp_unicode(options const & o);
/** \brief Format a hierarchical name */
format pp(name const & n);
/** \brief Return true iff \c f1 and \c f2 are equal when formatted with options \c o */
bool format_pp_eq(format const & f1, format const & f2, options const & o);
void initialize_format();
void finalize_format();
}