// -*- C++ -*-
//
// This file was generated by CLI, a command line interface
// compiler for C++.
//

#ifndef BUILD_OPTIONS
#define BUILD_OPTIONS

// Begin prologue.
//
//
// End prologue.

#include <iosfwd>
#include <string>
#include <cstddef>
#include <exception>

namespace cl
{
  class unknown_mode
  {
    public:
    enum value
    {
      skip,
      stop,
      fail
    };

    unknown_mode (value v);

    operator value () const 
    {
      return v_;
    }

    private:
    value v_;
  };

  // Exceptions.
  //

  class exception: public std::exception
  {
    public:
    virtual void
    print (::std::ostream&) const = 0;
  };

  ::std::ostream&
  operator<< (::std::ostream&, const exception&);

  class unknown_option: public exception
  {
    public:
    virtual
    ~unknown_option () throw ();

    unknown_option (const std::string& option);

    const std::string&
    option () const;

    virtual void
    print (::std::ostream&) const;

    virtual const char*
    what () const throw ();

    private:
    std::string option_;
  };

  class unknown_argument: public exception
  {
    public:
    virtual
    ~unknown_argument () throw ();

    unknown_argument (const std::string& argument);

    const std::string&
    argument () const;

    virtual void
    print (::std::ostream&) const;

    virtual const char*
    what () const throw ();

    private:
    std::string argument_;
  };

  class missing_value: public exception
  {
    public:
    virtual
    ~missing_value () throw ();

    missing_value (const std::string& option);

    const std::string&
    option () const;

    virtual void
    print (::std::ostream&) const;

    virtual const char*
    what () const throw ();

    private:
    std::string option_;
  };

  class invalid_value: public exception
  {
    public:
    virtual
    ~invalid_value () throw ();

    invalid_value (const std::string& option,
                   const std::string& value);

    const std::string&
    option () const;

    const std::string&
    value () const;

    virtual void
    print (::std::ostream&) const;

    virtual const char*
    what () const throw ();

    private:
    std::string option_;
    std::string value_;
  };

  class eos_reached: public exception
  {
    public:
    virtual void
    print (::std::ostream&) const;

    virtual const char*
    what () const throw ();
  };

  class scanner
  {
    public:
    virtual
    ~scanner ();

    virtual bool
    more () = 0;

    virtual const char*
    peek () = 0;

    virtual const char*
    next () = 0;

    virtual void
    skip () = 0;
  };

  class argv_scanner: public scanner
  {
    public:
    argv_scanner (int& argc, char** argv, bool erase = false);
    argv_scanner (int start, int& argc, char** argv, bool erase = false);

    int
    end () const;

    virtual bool
    more ();

    virtual const char*
    peek ();

    virtual const char*
    next ();

    virtual void
    skip ();

    private:
    int i_;
    int& argc_;
    char** argv_;
    bool erase_;
  };

  template <typename X>
  struct parser;
}

#include <cstdint>

class options
{
  public:
  options ();

  options (int& argc,
           char** argv,
           bool erase = false,
           ::cl::unknown_mode option = ::cl::unknown_mode::fail,
           ::cl::unknown_mode argument = ::cl::unknown_mode::stop);

  options (int start,
           int& argc,
           char** argv,
           bool erase = false,
           ::cl::unknown_mode option = ::cl::unknown_mode::fail,
           ::cl::unknown_mode argument = ::cl::unknown_mode::stop);

  options (int& argc,
           char** argv,
           int& end,
           bool erase = false,
           ::cl::unknown_mode option = ::cl::unknown_mode::fail,
           ::cl::unknown_mode argument = ::cl::unknown_mode::stop);

  options (int start,
           int& argc,
           char** argv,
           int& end,
           bool erase = false,
           ::cl::unknown_mode option = ::cl::unknown_mode::fail,
           ::cl::unknown_mode argument = ::cl::unknown_mode::stop);

  options (::cl::scanner&,
           ::cl::unknown_mode option = ::cl::unknown_mode::fail,
           ::cl::unknown_mode argument = ::cl::unknown_mode::stop);

  // Option accessors.
  //
  const bool&
  help () const;

  const bool&
  version () const;

  const bool&
  v () const;

  const bool&
  q () const;

  const std::uint16_t&
  verbose () const;

  bool
  verbose_specified () const;

  // Print usage information.
  //
  static void
  print_usage (::std::ostream&);

  // Implementation details.
  //
  protected:
  bool
  _parse (const char*, ::cl::scanner&);

  private:
  void
  _parse (::cl::scanner&,
          ::cl::unknown_mode option,
          ::cl::unknown_mode argument);

  public:
  bool help_;
  bool version_;
  bool v_;
  bool q_;
  std::uint16_t verbose_;
  bool verbose_specified_;
};

#include <build/options.ixx>

// Begin epilogue.
//
//
// End epilogue.

#endif // BUILD_OPTIONS