Utils/Termlib: Extend the completion API
[senf.git] / Utils / Console / Traits.ih
index b9f3b1b..40e55e5 100644 (file)
@@ -33,6 +33,7 @@
 #include <boost/preprocessor/facilities/empty.hpp>
 #include <boost/bimap.hpp>
 #include <boost/assign/list_inserter.hpp>
+#include <boost/algorithm/string/case_conv.hpp>
 #include "../../Utils/singleton.hh"
 
 ///////////////////////////////ih.p////////////////////////////////////////
@@ -42,45 +43,41 @@ namespace console {
 namespace detail {
 
 #ifndef DOXYGEN
+    struct StringILess
+    {
+        bool operator()(std::string const & left, std::string const & right) const
+            { return boost::algorithm::to_lower_copy(left) 
+                  < boost::algorithm::to_lower_copy(right); }
+    };
 
-    typedef boost::bimap<std::string, long> EnumTable;
+    typedef boost::bimap<boost::bimaps::set_of<std::string, StringILess>, long> EnumTable;
 
     long parseEnum(EnumTable const & table, ParseCommandInfo::TokensRange const & tokens);
     std::string formatEnum(EnumTable const & table, long value);
 
-    template <class EnumType>
-    struct EnumTraits : public senf::singleton< EnumTraits<EnumType> >
-    {
-        using senf::singleton< EnumTraits<EnumType> >::instance;
-        EnumTable table;
-    };
-
 #   define SENF_CONSOLE_REGISTER_ENUM_ELT(r,d,e) \
-        (BOOST_PP_STRINGIZE(e), static_cast<long>(d e))
+        ( BOOST_PP_STRINGIZE(e), static_cast<long>(d e) )
 
 #   define SENF_CONSOLE_REGISTER_ENUM_(Prefix, Type, Values)                                      \
-        void senf_console_init_enum_table(Prefix Type)                                            \
+        inline senf::console::detail::EnumTable & senf_console_enum_table(Prefix Type)            \
         {                                                                                         \
-            senf::console::detail::EnumTraits<Prefix Type> & traits (                             \
-                senf::console::detail::EnumTraits<Prefix Type>::instance() );                     \
-            if (traits.table.empty())                                                             \
-                boost::assign::insert(traits.table)                                               \
+            static senf::console::detail::EnumTable table;                                        \
+            if (table.empty())                                                                    \
+                boost::assign::insert(table)                                                      \
                     BOOST_PP_SEQ_FOR_EACH( SENF_CONSOLE_REGISTER_ENUM_ELT, Prefix, Values );      \
+            return table;                                                                         \
         }                                                                                         \
-        void senf_console_parse_argument(                                                         \
+        inline void senf_console_parse_argument(                                                  \
             senf::console::ParseCommandInfo::TokensRange const & tokens, Prefix Type & out)       \
         {                                                                                         \
-            senf_console_init_enum_table( Prefix Type() );                                        \
             out = static_cast<Prefix Type>(                                                       \
                 senf::console::detail::parseEnum(                                                 \
-                    senf::console::detail::EnumTraits<Prefix Type>::instance().table, tokens));   \
+                    senf_console_enum_table( Prefix Type() ), tokens) );                          \
         }                                                                                         \
-        void senf_console_format_value(Prefix Type value, std::ostream & os)                      \
+        inline void senf_console_format_value(Prefix Type value, std::ostream & os)               \
         {                                                                                         \
-            senf_console_init_enum_table( Prefix Type() );                                        \
             os << senf::console::detail::formatEnum(                                              \
-                senf::console::detail::EnumTraits<Prefix Type>::instance().table,                 \
-                static_cast<long>(value) );                                                       \
+                senf_console_enum_table( Prefix Type() ), static_cast<long>(value) );             \
         }
 
 #endif