switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / Utils / Console / Traits.ih
1 // $Id$
2 //
3 // Copyright (C) 2008
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at 
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis, 
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
24 //
25 // Contributor(s):
26 //   Stefan Bund <g0dil@berlios.de>
27
28 /** \file
29     \brief Traits internal header */
30
31 #ifndef IH_SENF_Scheduler_Console_Traits_
32 #define IH_SENF_Scheduler_Console_Traits_ 1
33
34 // Custom includes
35 #include <string>
36 #include <limits>
37 #include <boost/preprocessor/seq/for_each.hpp>
38 #include <boost/preprocessor/stringize.hpp>
39 #include <boost/preprocessor/facilities/empty.hpp>
40 #include <boost/bimap.hpp>
41 #include <boost/assign/list_inserter.hpp>
42 #include <boost/algorithm/string/case_conv.hpp>
43 #include <boost/mpl/if.hpp>
44
45 //-/////////////////////////////////////////////////////////////////////////////////////////////////
46
47 namespace senf {
48 namespace console {
49
50     template <class _> struct ArgumentTraits;
51     template <class _> struct ReturnValueTraits;
52
53 namespace detail {
54
55     template <class CharT>
56     struct MatchingShortType
57         : public boost::mpl::if_c<std::numeric_limits<CharT>::is_signed,short,unsigned short>
58     {};
59
60     template <class CharT>
61     struct CharArgumentTraits
62         : public ArgumentTraits<typename MatchingShortType<CharT>::type>
63     {
64         typedef ArgumentTraits<typename MatchingShortType<CharT>::type> base;
65         typedef CharT type;
66         static void parse(ParseCommandInfo::TokensRange const & tokens, CharT & out);
67         static std::string description();
68     };
69
70     template <class CharT>
71     struct CharReturnValueTraits
72         : public ReturnValueTraits<typename MatchingShortType<CharT>::type>
73     {
74         typedef CharT type;
75     };
76
77 #ifndef DOXYGEN
78     struct StringILess
79     {
80         bool operator()(std::string const & left, std::string const & right) const
81             { return boost::algorithm::to_lower_copy(left)
82                   < boost::algorithm::to_lower_copy(right); }
83     };
84
85     typedef boost::bimap<boost::bimaps::set_of<std::string, StringILess>, long> EnumTable;
86
87     long parseEnum(EnumTable const & table, ParseCommandInfo::TokensRange const & tokens);
88     std::string formatEnum(EnumTable const & table, long value);
89
90 #   define SENF_CONSOLE_REGISTER_ENUM_ELT(r,d,e)                        \
91         BOOST_PP_IF( SENF_CONSOLE_REGISTER_ENUM_HASKEY(e),              \
92                      SENF_CONSOLE_REGISTER_ENUM_WITHKEY,                \
93                      SENF_CONSOLE_REGISTER_ENUM_NOKEY )(d, e)
94
95 #   define SENF_CONSOLE_REGISTER_ENUM_GOBBLE__key(k,e)
96 #   define SENF_CONSOLE_REGISTER_ENUM_GET_KEY__key(k,e) k
97 #   define SENF_CONSOLE_REGISTER_ENUM_GET_ENUM__key(k,e) e
98 #   define SENF_CONSOLE_REGISTER_ENUM_HASKEY(e)                         \
99         BOOST_PP_IS_EMPTY( SENF_CAT_RECURS1(SENF_CONSOLE_REGISTER_ENUM_GOBBLE__, e) )
100
101 #   define SENF_CONSOLE_REGISTER_ENUM_KEY_GETENUM(e)                    \
102         SENF_CAT_RECURS2(SENF_CONSOLE_REGISTER_ENUM_GET_ENUM__, e)
103 #   define SENF_CONSOLE_REGISTER_ENUM_KEY_GETKEY(e)                     \
104         SENF_CAT_RECURS3(SENF_CONSOLE_REGISTER_ENUM_GET_KEY__, e)
105
106 #   define SENF_CONSOLE_REGISTER_ENUM_NOKEY(prefix, e)                  \
107         ( BOOST_PP_STRINGIZE(e), static_cast<long>(prefix e) )
108
109 #   define SENF_CONSOLE_REGISTER_ENUM_WITHKEY(prefix, e)                \
110         ( SENF_CONSOLE_REGISTER_ENUM_KEY_GETKEY(e),                     \
111           static_cast<long>(prefix SENF_CONSOLE_REGISTER_ENUM_KEY_GETENUM(e)) )
112
113
114 #   define SENF_CONSOLE_REGISTER_ENUM_(Prefix, Type, Values)                                      \
115         inline senf::console::detail::EnumTable & senf_console_enum_table(Prefix Type)            \
116         {                                                                                         \
117             static senf::console::detail::EnumTable table;                                        \
118             if (table.empty())                                                                    \
119                 boost::assign::insert(table)                                                      \
120                     BOOST_PP_SEQ_FOR_EACH( SENF_CONSOLE_REGISTER_ENUM_ELT, Prefix, Values );      \
121             return table;                                                                         \
122         }                                                                                         \
123         inline void senf_console_parse_argument(                                                  \
124             senf::console::ParseCommandInfo::TokensRange const & tokens, Prefix Type & out)       \
125         {                                                                                         \
126             out = static_cast<Prefix Type>(                                                       \
127                 senf::console::detail::parseEnum(                                                 \
128                     senf_console_enum_table( Prefix Type() ), tokens) );                          \
129         }                                                                                         \
130         inline void senf_console_format_value(Prefix Type value, std::ostream & os)               \
131         {                                                                                         \
132             os << senf::console::detail::formatEnum(                                              \
133                 senf_console_enum_table( Prefix Type() ), static_cast<long>(value) );             \
134         }
135
136 #endif
137
138 }}}
139
140 //-/////////////////////////////////////////////////////////////////////////////////////////////////
141 #endif
142
143 \f
144 // Local Variables:
145 // mode: c++
146 // fill-column: 100
147 // comment-column: 40
148 // c-file-style: "senf"
149 // indent-tabs-mode: nil
150 // ispell-local-dictionary: "american"
151 // compile-command: "scons -u test"
152 // End: