/******************************************************************************** * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * * * * This software is distributed under the terms of the * * GNU Lesser General Public Licence version 3 (LGPL) version 3, * * copied verbatim in the file "LICENSE" * ********************************************************************************/ /* * File: FairProgOptionsHelper.h * Author: winckler * * Created on March 11, 2015, 5:38 PM */ #ifndef FAIRPROGOPTIONSHELPER_H #define FAIRPROGOPTIONSHELPER_H #include #include #include #include #include #include #include #include template std::ostream& operator<<(std::ostream& os, const std::vector& v) { std::copy(v.begin(), v.end(), std::ostream_iterator(os, " ")); return os; } namespace FairMQ { namespace po = boost::program_options; template bool is_this_type(const po::variable_value& varValue) { auto& value = varValue.value(); if (auto q = boost::any_cast(&value)) return true; else return false; } template std::string ConvertVariableValueToString(const po::variable_value& varValue) { auto& value = varValue.value(); std::ostringstream ostr; if (auto q = boost::any_cast(&value)) { ostr << *q; } std::string valueStr = ostr.str(); return valueStr; } // string specialization template<> inline std::string ConvertVariableValueToString(const po::variable_value& varValue) { auto& value = varValue.value(); std::string valueStr; if (auto q = boost::any_cast(&value)) { valueStr = *q; } return valueStr; } // boost::filesystem::path specialization template<> inline std::string ConvertVariableValueToString(const po::variable_value& varValue) { auto& value = varValue.value(); std::string valueStr; if (auto q = boost::any_cast(&value)) { valueStr = (*q).string(); } return valueStr; } #if defined(__GNUC__) || defined(__GNUG__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Weffc++" #endif // policy to convert boost variable value into string struct ToString { typedef std::string returned_type; template std::string Value(const po::variable_value& varValue, const std::string&, const std::string&, const std::string&) { return ConvertVariableValueToString(varValue); } returned_type DefaultValue(const std::string&, const std::string&) { return std::string("empty value"); } }; // policy to convert variable value content into a tuple with value, type, defaulted, empty information struct ToVarInfo { typedef std::tuple returned_type; template returned_type Value(const po::variable_value& varValue, const std::string& type, const std::string& defaulted, const std::string& empty) { std::string valueStr = ConvertVariableValueToString(varValue); return make_tuple(valueStr, type, defaulted, empty); } returned_type DefaultValue(const std::string& defaulted, const std::string& empty) { return make_tuple(std::string("Unknown value"), std::string(" [Unknown]"), defaulted, empty); } }; // host class that take one of the two policy defined above template struct ConvertVariableValue : T { //typename T::returned_type Run(const po::variable_value& varValue) //-> decltype(T::returned_type) auto Run(const po::variable_value& varValue) -> typename T::returned_type { std::string defaultedValue; std::string emptyValue; if (varValue.empty()) { emptyValue = " [empty]"; } else { if (varValue.defaulted()) { defaultedValue = " [default]"; } else { defaultedValue = " [provided]"; } } // emptyValue += " *"; //////////////////////////////// std types // std::string albeit useless here if (is_this_type(varValue)) return T::template Value(varValue, std::string(""), defaultedValue, emptyValue); // std::vector if (is_this_type>(varValue)) return T::template Value>(varValue, std::string(">"), defaultedValue, emptyValue); // int if (is_this_type(varValue)) return T::template Value(varValue, std::string(""), defaultedValue, emptyValue); // std::vector if (is_this_type>(varValue)) return T::template Value>(varValue, std::string(">"), defaultedValue, emptyValue); // float if (is_this_type(varValue)) return T::template Value(varValue, std::string(""), defaultedValue, emptyValue); // std::vector float if (is_this_type>(varValue)) return T::template Value>(varValue, std::string(">"), defaultedValue, emptyValue); // double if (is_this_type(varValue)) return T::template Value(varValue, std::string(""), defaultedValue, emptyValue); // std::vector double if (is_this_type>(varValue)) return T::template Value>(varValue, std::string(">"), defaultedValue, emptyValue); // short if (is_this_type(varValue)) return T::template Value(varValue, std::string(""), defaultedValue, emptyValue); // std::vector short if (is_this_type>(varValue)) return T::template Value>(varValue, std::string(">"), defaultedValue, emptyValue); // long if (is_this_type(varValue)) return T::template Value(varValue, std::string(""), defaultedValue, emptyValue); // std::vector short if (is_this_type>(varValue)) return T::template Value>(varValue, std::string(">"), defaultedValue, emptyValue); // size_t if (is_this_type(varValue)) return T::template Value(varValue, std::string(""), defaultedValue, emptyValue); // uint64_t if (is_this_type(varValue)) return T::template Value(varValue, std::string(""), defaultedValue, emptyValue); // std::vector size_t if (is_this_type>(varValue)) return T::template Value>(varValue, std::string(">"), defaultedValue, emptyValue); // bool if (is_this_type(varValue)) return T::template Value(varValue, std::string(""), defaultedValue, emptyValue); // std::vector bool if (is_this_type>(varValue)) return T::template Value>(varValue, std::string(">"), defaultedValue, emptyValue); //////////////////////////////// boost types // boost::filesystem::path if (is_this_type(varValue)) return T::template Value(varValue, std::string(""), defaultedValue, emptyValue); // if we get here, the type is not supported return unknown info return T::DefaultValue(defaultedValue, emptyValue); } }; #if defined(__GNUC__) || defined(__GNUG__) #pragma GCC diagnostic pop #endif } // FairMQ namespace #endif /* FAIRPROGOPTIONSHELPER_H */