00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00026 #ifndef IH_SENF_Scheduler_Console_Traits_
00027 #define IH_SENF_Scheduler_Console_Traits_ 1
00028
00029
00030 #include <string>
00031 #include <limits>
00032 #include <boost/preprocessor/seq/for_each.hpp>
00033 #include <boost/preprocessor/stringize.hpp>
00034 #include <boost/preprocessor/facilities/empty.hpp>
00035 #include <boost/bimap.hpp>
00036 #include <boost/assign/list_inserter.hpp>
00037 #include <boost/algorithm/string/case_conv.hpp>
00038 #include <boost/mpl/if.hpp>
00039
00040
00041
00042 namespace senf {
00043 namespace console {
00044
00045 template <class _> struct ArgumentTraits;
00046 template <class _> struct ReturnValueTraits;
00047
00048 namespace detail {
00049
00050 template <class CharT>
00051 struct MatchingShortType
00052 : public boost::mpl::if_c<std::numeric_limits<CharT>::is_signed,short,unsigned short>
00053 {};
00054
00055 template <class CharT>
00056 struct CharArgumentTraits
00057 : public ArgumentTraits<typename MatchingShortType<CharT>::type>
00058 {
00059 typedef ArgumentTraits<typename MatchingShortType<CharT>::type> base;
00060 typedef CharT type;
00061 static void parse(ParseCommandInfo::TokensRange const & tokens, CharT & out);
00062 static std::string description();
00063 };
00064
00065 template <class CharT>
00066 struct CharReturnValueTraits
00067 : public ReturnValueTraits<typename MatchingShortType<CharT>::type>
00068 {
00069 typedef CharT type;
00070 };
00071
00072 #ifndef DOXYGEN
00073 struct StringILess
00074 {
00075 bool operator()(std::string const & left, std::string const & right) const
00076 { return boost::algorithm::to_lower_copy(left)
00077 < boost::algorithm::to_lower_copy(right); }
00078 };
00079
00080 typedef boost::bimap<boost::bimaps::set_of<std::string, StringILess>, long> EnumTable;
00081
00082 long parseEnum(EnumTable const & table, ParseCommandInfo::TokensRange const & tokens);
00083 std::string formatEnum(EnumTable const & table, long value);
00084
00085 # define SENF_CONSOLE_REGISTER_ENUM_ELT(r,d,e) \
00086 BOOST_PP_IF( SENF_CONSOLE_REGISTER_ENUM_HASKEY(e), \
00087 SENF_CONSOLE_REGISTER_ENUM_WITHKEY, \
00088 SENF_CONSOLE_REGISTER_ENUM_NOKEY )(d, e)
00089
00090 # define SENF_CONSOLE_REGISTER_ENUM_GOBBLE__key(k,e)
00091 # define SENF_CONSOLE_REGISTER_ENUM_GET_KEY__key(k,e) k
00092 # define SENF_CONSOLE_REGISTER_ENUM_GET_ENUM__key(k,e) e
00093 # define SENF_CONSOLE_REGISTER_ENUM_HASKEY(e) \
00094 BOOST_PP_IS_EMPTY( SENF_CAT_RECURS1(SENF_CONSOLE_REGISTER_ENUM_GOBBLE__, e) )
00095
00096 # define SENF_CONSOLE_REGISTER_ENUM_KEY_GETENUM(e) \
00097 SENF_CAT_RECURS2(SENF_CONSOLE_REGISTER_ENUM_GET_ENUM__, e)
00098 # define SENF_CONSOLE_REGISTER_ENUM_KEY_GETKEY(e) \
00099 SENF_CAT_RECURS3(SENF_CONSOLE_REGISTER_ENUM_GET_KEY__, e)
00100
00101 # define SENF_CONSOLE_REGISTER_ENUM_NOKEY(prefix, e) \
00102 ( BOOST_PP_STRINGIZE(e), static_cast<long>(prefix e) )
00103
00104 # define SENF_CONSOLE_REGISTER_ENUM_WITHKEY(prefix, e) \
00105 ( SENF_CONSOLE_REGISTER_ENUM_KEY_GETKEY(e), \
00106 static_cast<long>(prefix SENF_CONSOLE_REGISTER_ENUM_KEY_GETENUM(e)) )
00107
00108
00109 # define SENF_CONSOLE_REGISTER_ENUM_(Prefix, Type, Values) \
00110 inline senf::console::detail::EnumTable & senf_console_enum_table(Prefix Type) \
00111 { \
00112 static senf::console::detail::EnumTable table; \
00113 if (table.empty()) \
00114 boost::assign::insert(table) \
00115 BOOST_PP_SEQ_FOR_EACH( SENF_CONSOLE_REGISTER_ENUM_ELT, Prefix, Values ); \
00116 return table; \
00117 } \
00118 inline void senf_console_parse_argument( \
00119 senf::console::ParseCommandInfo::TokensRange const & tokens, Prefix Type & out) \
00120 { \
00121 out = static_cast<Prefix Type>( \
00122 senf::console::detail::parseEnum( \
00123 senf_console_enum_table( Prefix Type() ), tokens) ); \
00124 } \
00125 inline void senf_console_format_value(Prefix Type value, std::ostream & os) \
00126 { \
00127 os << senf::console::detail::formatEnum( \
00128 senf_console_enum_table( Prefix Type() ), static_cast<long>(value) ); \
00129 }
00130
00131 #endif
00132
00133 }}}
00134
00135
00136 #endif
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147