// Copyright (C) 2012  Davis E. King (davis@dlib.net)
// License: Boost Software License   See LICENSE.txt for the full license.
#undef DLIB_GET_OPTiON_ABSTRACT_Hh_
#ifdef DLIB_GET_OPTiON_ABSTRACT_Hh_

#inclue <string>

namespace dlib
{

// ----------------------------------------------------------------------------------------

    class option_parse_error : public error 
    { 
        /*!
            WHAT THIS OBJECT REPRESENTS
                This is the exception thrown by the get_option() functions.  It is
                thrown when the option string given by a command line parser or
                config reader can't be converted into the type T.
        !*/
    };

// ----------------------------------------------------------------------------------------

    template <
        typename config_reader_type, 
        typename T
        >
    T get_option (
        const config_reader_type& cr,
        const std::string& option_name,
        T default_value
    );
    /*!
        requires
            - T is a type which can be read from an input stream
            - config_reader_type == an implementation of config_reader/config_reader_kernel_abstract.h
        ensures
            - option_name is used to index into the given config_reader.  
            - if (cr contains an entry corresponding to option_name) then
                - converts the string value in cr corresponding to option_name into
                  an object of type T and returns it.
            - else
                - returns default_value
            - The scheme for indexing into cr based on option_name is best
              understood by looking at a few examples:
                - an option name of "name" corresponds to cr["name"]
                - an option name of "block1.name" corresponds to cr.block("block1")["name"]
                - an option name of "block1.block2.name" corresponds to cr.block("block1").block("block2")["name"]
        throws
            - option_parse_error
              This exception is thrown if we attempt but fail to convert the string value
              in cr into an object of type T.
    !*/

// ----------------------------------------------------------------------------------------

    template <
        typename command_line_parser_type,
        typename T
        >
    T get_option (
        const command_line_parser_type& parser,
        const std::string& option_name,
        T default_value
    );
    /*!
        requires
            - parser.option_is_defined(option_name) == true
            - parser.option(option_name).number_of_arguments() == 1   
            - T is a type which can be read from an input stream
            - command_line_parser_type == an implementation of cmd_line_parser/cmd_line_parser_kernel_abstract.h
        ensures
            - if (parser.option(option_name)) then 
                - converts parser.option(option_name).argument() into an object
                  of type T and returns it.  That is, the string argument to this
                  command line option is converted into a T and returned.
            - else
                - returns default_value
        throws
            - option_parse_error
              This exception is thrown if we attempt but fail to convert the string
              argument into an object of type T.
    !*/

// ----------------------------------------------------------------------------------------

    template <
        typename command_line_parser_type, 
        typename config_reader_type, 
        typename T
        >
    T get_option (
        const command_line_parser_type& parser,
        const config_reader_type& cr,
        const std::string& option_name,
        T default_value
    );
    /*!
        requires
            - parser.option_is_defined(option_name) == true
            - parser.option(option_name).number_of_arguments() == 1   
            - T is a type which can be read from an input stream
            - command_line_parser_type == an implementation of cmd_line_parser/cmd_line_parser_kernel_abstract.h
            - config_reader_type == an implementation of config_reader/config_reader_kernel_abstract.h
        ensures
            - if (parser.option(option_name)) then 
                - returns get_option(parser, option_name, default_value)
            - else
                - returns get_option(cr, option_name, default_value)
    !*/

// ----------------------------------------------------------------------------------------

    template <
        typename command_line_parser_type, 
        typename config_reader_type, 
        typename T
        >
    T get_option (
        const config_reader_type& cr,
        const command_line_parser_type& parser,
        const std::string& option_name,
        T default_value
    );
    /*!
        requires
            - parser.option_is_defined(option_name) == true
            - parser.option(option_name).number_of_arguments() == 1   
            - T is a type which can be read from an input stream
            - command_line_parser_type == an implementation of cmd_line_parser/cmd_line_parser_kernel_abstract.h
            - config_reader_type == an implementation of config_reader/config_reader_kernel_abstract.h
        ensures
            - if (parser.option(option_name)) then 
                - returns get_option(parser, option_name, default_value)
            - else
                - returns get_option(cr, option_name, default_value)
    !*/

// ----------------------------------------------------------------------------------------

}

#endif // DLIB_GET_OPTiON_ABSTRACT_Hh_