source: NonGTP/Boost/boost/program_options/options_description.hpp @ 857

Revision 857, 9.2 KB checked in by igarcia, 18 years ago (diff)
Line 
1// Copyright Vladimir Prus 2002-2004.
2// Copyright Bertolt Mildner 2004.
3// Distributed under the Boost Software License, Version 1.0.
4// (See accompanying file LICENSE_1_0.txt
5// or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7
8#ifndef BOOST_OPTION_DESCRIPTION_VP_2003_05_19
9#define BOOST_OPTION_DESCRIPTION_VP_2003_05_19
10
11#include <boost/program_options/config.hpp>
12#include <boost/program_options/errors.hpp>
13#include <boost/program_options/value_semantic.hpp>
14
15#include <boost/function.hpp>
16#include <boost/shared_ptr.hpp>
17#include <boost/detail/workaround.hpp>
18#include <boost/any.hpp>
19
20#include <string>
21#include <vector>
22#include <set>
23#include <map>
24#include <stdexcept>
25
26#include <iosfwd>
27
28/** Boost namespace */
29namespace boost {
30/** Namespace for the library. */
31namespace program_options {
32
33    /** Describes one possible command line/config file option. There are two
34        kinds of properties of an option. First describe it syntactically and
35        are used only to validate input. Second affect interpretation of the
36        option, for example default value for it or function that should be
37        called  when the value is finally known. Routines which perform parsing
38        never use second kind of properties -- they are side effect free.
39        @sa options_description
40    */
41    class BOOST_PROGRAM_OPTIONS_DECL option_description {
42    public:
43
44        option_description();
45
46        /** Initializes the object with the passed data.
47
48            Note: it would be nice to make the second parameter auto_ptr,
49            to explicitly pass ownership. Unfortunately, it's often needed to
50            create objects of types derived from 'value_semantic':
51               options_description d;
52               d.add_options()("a", parameter<int>("n")->default_value(1));
53            Here, the static type returned by 'parameter' should be derived
54            from value_semantic.
55
56            Alas, derived->base conversion for auto_ptr does not really work,
57            see
58            http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2000/n1232.pdf
59            http://std.dkuug.dk/jtc1/sc22/wg21/docs/cwg_defects.html#84
60
61            So, we have to use plain old pointers. Besides, users are not
62            expected to use the constructor directly.
63
64           
65            The 'name' parameter is interpreted by the following rules:
66            - if there's no "," character in 'name', it specifies long name
67            - otherwise, the part before "," specifies long name and the part
68            after -- long name.
69        */
70        option_description(const char* name,
71                           const value_semantic* s);
72
73        /** Initializes the class with the passed data.
74         */
75        option_description(const char* name,
76                           const value_semantic* s,
77                           const char* description);
78
79        virtual ~option_description();
80
81        /** Given 'option', specified in the input source,
82            return 'true' is 'option' specifies *this.
83        */
84        bool match(const std::string& option, bool approx) const;
85
86        /** Return the key that should identify the option, in
87            particular in the variables_map class.
88            The 'option' parameter is the option spelling from the
89            input source.
90            If option name contains '*', returns 'option'.
91            If long name was specified, it's the long name, otherwise
92            it's a short name with prepended '-'.
93        */
94        const std::string& key(const std::string& option) const;
95
96        const std::string& long_name() const;
97
98        /// Explanation of this option
99        const std::string& description() const;
100
101        /// Semantic of option's value
102        shared_ptr<const value_semantic> semantic() const;
103       
104        /// Returns the option name, formatted suitably for usage message.
105        std::string format_name() const;
106
107        /** Return the parameter name and properties, formatted suitably for
108            usage message. */
109        std::string format_parameter() const;
110
111    private:
112   
113        option_description& set_name(const char* name);
114
115        std::string m_short_name, m_long_name, m_description;
116        // shared_ptr is needed to simplify memory management in
117        // copy ctor and destructor.
118        shared_ptr<const value_semantic> m_value_semantic;
119    };
120
121    class options_description;
122
123    /** Class which provides convenient creation syntax to option_description.
124     */       
125    class BOOST_PROGRAM_OPTIONS_DECL options_description_easy_init {
126    public:
127        options_description_easy_init(options_description* owner);
128
129        options_description_easy_init&
130        operator()(const char* name,
131                   const char* description);
132
133        options_description_easy_init&
134        operator()(const char* name,
135                   const value_semantic* s);
136       
137        options_description_easy_init&
138        operator()(const char* name,
139                   const value_semantic* s,
140                   const char* description);
141       
142    private:
143        options_description* owner;
144    };
145
146
147    /** A set of option descriptions. This provides convenient interface for
148        adding new option (the add_options) method, and facilities to search
149        for options by name.
150       
151        See @ref a_adding_options "here" for option adding interface discussion.
152        @sa option_description
153    */
154    class BOOST_PROGRAM_OPTIONS_DECL options_description {
155    public:
156        static const unsigned m_default_line_length = 80;
157       
158        /** Creates the instance. */
159        options_description(unsigned line_length = m_default_line_length);
160        /** Creates the instance. The 'caption' parameter gives the name of
161            this 'options_description' instance. Primarily useful for output.
162        */
163        options_description(const std::string& caption,
164                            unsigned line_length = m_default_line_length);
165        /** Adds new variable description. Throws duplicate_variable_error if
166            either short or long name matches that of already present one.
167        */
168        void add(shared_ptr<option_description> desc);
169        /** Adds a group of option description. This has the same
170            effect as adding all option_descriptions in 'desc'
171            individually, except that output operator will show
172            a separate group.
173            Returns *this.
174        */
175        options_description& add(const options_description& desc);
176
177    public:
178        /** Returns an object of implementation-defined type suitable for adding
179            options to options_description. The returned object will
180            have overloaded operator() with parameter type matching
181            'option_description' constructors. Calling the operator will create
182            new option_description instance and add it.
183        */
184        options_description_easy_init add_options();
185
186        const option_description& find(const std::string& name, bool approx)
187            const;
188
189        const option_description* find_nothrow(const std::string& name,
190                                               bool approx) const;
191
192
193        const std::vector< shared_ptr<option_description> >& options() const;
194
195        /** Produces a human readable output of 'desc', listing options,
196            their descriptions and allowed parameters. Other options_description
197            instances previously passed to add will be output separately. */
198        friend BOOST_PROGRAM_OPTIONS_DECL std::ostream& operator<<(std::ostream& os,
199                                             const options_description& desc);
200
201        /** Output 'desc' to the specified stream, calling 'f' to output each
202            option_description element. */
203        void print(std::ostream& os) const;
204
205    private:
206        typedef std::map<std::string, int>::const_iterator name2index_iterator;
207        typedef std::pair<name2index_iterator, name2index_iterator>
208            approximation_range;
209
210        //approximation_range find_approximation(const std::string& prefix) const;
211
212        std::string m_caption;
213        const unsigned m_line_length;
214        // Data organization is chosen because:
215        // - there could be two names for one option
216        // - option_add_proxy needs to know the last added option
217        std::vector< shared_ptr<option_description> > m_options;
218
219        // Whether the option comes from one of declared groups.
220#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, BOOST_TESTED_AT(313))
221        // vector<bool> is buggy there, see
222        // http://support.microsoft.com/default.aspx?scid=kb;en-us;837698
223        std::vector<char> belong_to_group;
224#else
225        std::vector<bool> belong_to_group;
226#endif
227
228        std::vector< shared_ptr<options_description> > groups;
229
230    };
231
232    /** Class thrown when duplicate option description is found. */
233    class BOOST_PROGRAM_OPTIONS_DECL duplicate_option_error : public error {
234    public:
235        duplicate_option_error(const std::string& what) : error(what) {}
236    };
237}}
238
239#endif
Note: See TracBrowser for help on using the repository browser.