/* -*- c++ -*-
 * baseout.h: header for baseout.cpp.
 */

#include <memory>
using std::unique_ptr;

/*
 * Construct an OutputGenerator for numbers written in standard
 * positional notation in any integer base from 2 to 36.
 */
unique_ptr<OutputGenerator> base_format(
    Spigot spig, int base, int uppercase,
    bool has_digitlimit, int digitlimit, RoundingMode rmode, int minintdigits);

/*
 * Construct an OutputGenerator for numbers written in 'reversed
 * scientific notation', i.e. with the exponent first.
 */
unique_ptr<OutputGenerator> revsci_format(
    Spigot spig, int expbase, int digitbase, int uppercase,
    bool has_digitlimit, int digitlimit, RoundingMode rmode);

/*
 * Construct an OutputGenerator for numbers formatted like IEEE bit
 * patterns (with optional trailing digits for extra precision).
 */
unique_ptr<OutputGenerator> ieee_format(
    Spigot spig, int ieee_bits,
    bool has_digitlimit, int digitlimit, RoundingMode rmode);

/*
 * Construct an OutputGenerator to format a string based on a
 * 'printf' float-type specification.
 *
 * 'width' and 'precision' are the numbers given in the specification,
 * or -1 in each case to indicate that none was provided. 'specifier'
 * is the char value of the main formatting directive (one of
 * 'e','f','g','a' or its uppercase equivalent). 'flags' is a bit-mask
 * with the flag bits defined below. 'pad' is the padding character to
 * use if the number takes up less space than 'width'.
 *
 * 'nibble_mode' controls the choice of exponent in %a formats. If it
 * is false, the chosen exponent is always as large as possible, so
 * that the leading digit (for any nonzero number) is 1. If true, the
 * chosen exponent is always a multiple of 4, so that the hex digits
 * of the output align to the hex digits in ordinary -b16 mode.
 */
#define PrintfFlag_LIST(X)                                              \
    X(PRINTF_SIGN_PLUS)                                                 \
    X(PRINTF_SIGN_SPACE)                                                \
    X(PRINTF_FORCE_POINT)                                               \
    X(PRINTF_ALIGN_LEFT)                                                \
    /*                                                                  \
     * Alignment CENTRE means centring the whole formatted number       \
     * within the available space (Python's string.format has this      \
     * option, though standard printf doesn't). Alignment MIDDLE means  \
     * putting the padding characters in the middle of the formatted    \
     * number, between the sign and the leading nonzero digit (i.e.     \
     * what happens if you use the '0' flag in standard printf).        \
     */                                                                 \
    X(PRINTF_ALIGN_CENTRE)                                              \
    X(PRINTF_ALIGN_MIDDLE)                                              \
    X(PRINTF_COMMAS)                                                    \
    /* end of list */

#define PrintfFlag_BITPOS_DECL(name) BITPOS_ ## name,
enum { PrintfFlag_LIST(PrintfFlag_BITPOS_DECL) };
#define PrintfFlag_DECL(name) constexpr int name = 1 << BITPOS_ ## name;
PrintfFlag_LIST(PrintfFlag_DECL)

unique_ptr<OutputGenerator> printf_format(
    Spigot spig, RoundingMode rmode, int width, int precision, int flags,
    char pad, int specifier, bool nibble_mode);
