/* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Copyright 2013-2016 Danny Robson */ #ifdef __UTIL_CMDLINE_IPP #error #endif #define __UTIL_CMDLINE_IPP #include #include #include "./introspection.hpp" #include "./iterator.hpp" namespace util { namespace cmdopt { /////////////////////////////////////////////////////////////////////////// template option::value::value (T &_data): m_data (_data) { ; } //------------------------------------------------------------------------- template inline void option::value::execute (const char *restrict str) { try { std::istringstream is (str); is.exceptions ( std::istringstream::failbit | std::istringstream::badbit ); is >> m_data; } catch (...) { throw invalid_value (__func__); } seen (true); } //------------------------------------------------------------------------- namespace option { template <> inline void value::execute (const char *restrict str) { static const std::string TRUE_STRING[] = { "true", "yes", "y", "1" }; if (std::any_of (std::begin (TRUE_STRING), std::end (TRUE_STRING), [str] (auto i) { return i == str; })) { m_data = true; return; } static const std::string FALSE_STRING[] = { "false", "no", "n", "0" }; if (std::any_of (std::begin (FALSE_STRING), std::end (FALSE_STRING), [str] (auto i) { return i == str; })) { m_data = false; return; } base::execute (str); seen (true); } } //------------------------------------------------------------------------- namespace detail { template std::enable_if_t::value, const std::string&> value_example (void) { static const std::string EXAMPLE = std::string {"<"} + std::string {to_string ()} + std::string {">"}; return EXAMPLE; } template std::enable_if_t::value, const std::string&> value_example (void) { static const std::string EXAMPLE = [] (void) { std::ostringstream os; std::copy (std::cbegin (enum_traits::names), std::cend (enum_traits::names), infix_iterator (os, "|")); return os.str (); } (); return EXAMPLE; } } //------------------------------------------------------------------------- template const std::string& option::value::example (void) const { return detail::value_example (); } //----------------------------------------------------------------------------- template const T& option::value::data (void) const& { return m_data; } //----------------------------------------------------------------------------- template T& option::value::data (void) & { return m_data; } //----------------------------------------------------------------------------- template T& option::value::data (T _data) & { return m_data = _data; } /////////////////////////////////////////////////////////////////////////// template T& parser::add (char shortname, std::string longname, std::string description, Args&&... args) { auto handler = std::make_unique (std::forward (args)...); T& ref = *handler; m_short.emplace_back (shortname, ref); m_long .emplace_back (std::move (longname), ref); m_options.emplace_back (std::move (description), std::move (handler)); return ref; } //------------------------------------------------------------------------- template T& parser::append (std::string description, Args &&...args) { auto handler = std::make_unique (std::forward (args)...); auto &ref = *handler; m_positional.push_back (ref); m_options.emplace_back (std::move (description), std::move (handler)); return ref; } } }