/* This file is part of Telegram Desktop, the official desktop application for the Telegram messaging service. For license and copyright information please follow this link: https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once #include inline bool operator<(std::nullopt_t, std::nullopt_t) { return false; } inline bool operator>(std::nullopt_t, std::nullopt_t) { return false; } inline bool operator<=(std::nullopt_t, std::nullopt_t) { return true; } inline bool operator>=(std::nullopt_t, std::nullopt_t) { return true; } inline bool operator==(std::nullopt_t, std::nullopt_t) { return true; } inline bool operator!=(std::nullopt_t, std::nullopt_t) { return false; } #include #include #include "base/match_method.h" #include "base/assertion.h" // We use base::variant<> alias and base::get_if() helper while we don't have std::variant<>. namespace base { template using variant = mapbox::util::variant; template inline T *get_if(variant *v) { return (v && v->template is()) ? &v->template get_unchecked() : nullptr; } template inline const T *get_if(const variant *v) { return (v && v->template is()) ? &v->template get_unchecked() : nullptr; } namespace type_list = rpl::details::type_list; template struct normalized_variant { using list = type_list::list; using distinct = type_list::distinct_t; using type = std::conditional_t< type_list::size_v == 1, type_list::get_t<0, distinct>, type_list::extract_to_t>; }; template using normalized_variant_t = typename normalized_variant::type; template struct match_helper; template < typename Type, typename ...Types, typename Variant, typename ...Methods> struct match_helper, Variant, Methods...> { static decltype(auto) call(Variant &value, Methods &&...methods) { if (const auto v = get_if(&value)) { return match_method( *v, std::forward(methods)...); } return match_helper< type_list::list, Variant, Methods...>::call( value, std::forward(methods)...); } }; template < typename Type, typename Variant, typename ...Methods> struct match_helper, Variant, Methods...> { static decltype(auto) call(Variant &value, Methods &&...methods) { if (const auto v = get_if(&value)) { return match_method( *v, std::forward(methods)...); } Unexpected("Valueless variant in base::match()."); } }; template inline decltype(auto) match( variant &value, Methods &&...methods) { return match_helper< type_list::list, variant, Methods...>::call(value, std::forward(methods)...); } template inline decltype(auto) match( const variant &value, Methods &&...methods) { return match_helper< type_list::list, const variant, Methods...>::call(value, std::forward(methods)...); } } // namespace base