/** * server/src/core/to.hpp * * This file is part of the traintastic source code. * * Copyright (C) 2019-2020 Reinder Feenstra * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef TRAINTASTIC_SERVER_CORE_TO_HPP #define TRAINTASTIC_SERVER_CORE_TO_HPP #include #include #include #include #include "../utils/json.hpp" class not_writable_error : public std::runtime_error { public: not_writable_error() : std::runtime_error("not writable error") { } }; class invalid_value_error : public std::runtime_error { public: invalid_value_error() : std::runtime_error("invalid value error") { } }; class conversion_error : public std::runtime_error { public: conversion_error() : std::runtime_error("conversion error") { } }; class out_of_range_error : public std::runtime_error { public: out_of_range_error() : std::runtime_error("out of range error") { } }; template To to(const From& value) { if constexpr(std::is_same_v) return value; else if constexpr(std::is_integral_v && std::is_enum_v) return static_cast(value); else if constexpr(std::is_enum_v && std::is_integral_v) { // TODO: test if enum value is valid !! return static_cast(value); } else if constexpr(!std::is_same_v && std::is_integral_v && !std::is_same_v && std::is_integral_v) { if constexpr(std::numeric_limits::min() <= std::numeric_limits::min() && std::numeric_limits::max() >= std::numeric_limits::max()) return value; else if(value >= std::numeric_limits::min() && value <= std::numeric_limits::max()) return static_cast(value); else throw out_of_range_error(); } else if constexpr(std::is_floating_point_v && (std::is_integral_v || std::is_floating_point_v)) return static_cast(value); else if constexpr(!std::is_same_v && std::is_integral_v && std::is_floating_point_v) { if(value >= std::numeric_limits::min() && value <= std::numeric_limits::max()) return static_cast(std::round(value)); else throw out_of_range_error(); } else if constexpr(std::is_same_v && std::is_integral_v && !std::is_same_v) { return std::to_string(value); } else if constexpr(std::is_same_v && std::is_same_v) return std::stof(value); else if constexpr(std::is_same_v && std::is_same_v) return std::stod(value); else if constexpr(std::is_same_v && std::is_same_v) { return std::string(value); } else if constexpr(std::is_same_v) { if constexpr(std::is_enum_v) { To e; from_json(value, e); return e; } else return value; } else if constexpr(std::is_same_v) { if constexpr(std::is_enum_v) { To json; to_json(json, value); return json; } else return value; } throw conversion_error(); } #endif