blob: b3af737c744243ec9df94830b1bede517da85494 [file] [log] [blame]
Davide Pesavento51493502019-07-17 02:26:44 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
Davide Pesavento09904412021-03-24 16:40:53 -04003 * Copyright (c) 2013-2021 Regents of the University of California.
Davide Pesavento51493502019-07-17 02:26:44 -04004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
21
Davide Pesavento09904412021-03-24 16:40:53 -040022#ifndef NDN_CXX_UTIL_OVERLOAD_HPP
23#define NDN_CXX_UTIL_OVERLOAD_HPP
Davide Pesavento51493502019-07-17 02:26:44 -040024
Davide Pesavento75c56012019-08-31 22:51:27 -040025#include <boost/predef/compiler/gcc.h>
Davide Pesavento51493502019-07-17 02:26:44 -040026#include <boost/version.hpp>
27
Davide Pesavento75c56012019-08-31 22:51:27 -040028// Hana does not support GCC < 6.0.0
29#if (BOOST_VERSION >= 106100) && (!BOOST_COMP_GNUC || (BOOST_COMP_GNUC >= BOOST_VERSION_NUMBER(6,0,0)))
30
Davide Pesavento51493502019-07-17 02:26:44 -040031#include <boost/hana/functional/overload.hpp>
32
33namespace ndn {
Davide Pesavento51493502019-07-17 02:26:44 -040034constexpr boost::hana::make_overload_t overload{};
Davide Pesavento51493502019-07-17 02:26:44 -040035} // namespace ndn
36
37#else
Davide Pesavento75c56012019-08-31 22:51:27 -040038
Davide Pesavento51493502019-07-17 02:26:44 -040039#include <type_traits>
40
41namespace ndn {
42namespace detail {
Davide Pesavento51493502019-07-17 02:26:44 -040043
44// The following code is copied from the Boost.Hana library.
45// Copyright Louis Dionne 2013-2017
46// Distributed under the Boost Software License, Version 1.0.
47// (See http://boost.org/LICENSE_1_0.txt)
48
49//! Pick one of several functions to call based on overload resolution.
50//!
51//! Specifically, `overload(f1, f2, ..., fn)` is a function object such
52//! that
53//! @code
54//! overload(f1, f2, ..., fn)(x...) == fk(x...)
55//! @endcode
56//!
57//! where `fk` is the function of `f1, ..., fn` that would be called if
58//! overload resolution was performed amongst that set of functions only.
59//! If more than one function `fk` would be picked by overload resolution,
60//! then the call is ambiguous.
61#ifndef DOXYGEN
62template <typename F, typename ...G>
63struct overload_t
64 : overload_t<F>::type
65 , overload_t<G...>::type
66{
67 using type = overload_t;
68 using overload_t<F>::type::operator();
69 using overload_t<G...>::type::operator();
70
71 template <typename F_, typename ...G_>
72 constexpr explicit overload_t(F_&& f, G_&& ...g)
73 : overload_t<F>::type(static_cast<F_&&>(f))
74 , overload_t<G...>::type(static_cast<G_&&>(g)...)
75 { }
76};
77
78template <typename F>
79struct overload_t<F> { using type = F; };
80
81template <typename R, typename ...Args>
82struct overload_t<R(*)(Args...)> {
83 using type = overload_t;
84 R (*fptr_)(Args...);
85
86 explicit constexpr overload_t(R (*fp)(Args...))
87 : fptr_(fp)
88 { }
89
90 constexpr R operator()(Args ...args) const
91 { return fptr_(static_cast<Args&&>(args)...); }
92};
93
94struct make_overload_t {
95 template <typename ...F,
96 typename Overload = typename overload_t<
97 typename std::decay<F>::type...
98 >::type
99 >
100 constexpr Overload operator()(F&& ...f) const {
101 return Overload(static_cast<F&&>(f)...);
102 }
103};
104#endif // DOXYGEN
105
Davide Pesavento51493502019-07-17 02:26:44 -0400106} // namespace detail
Davide Pesavento75c56012019-08-31 22:51:27 -0400107
108constexpr detail::make_overload_t overload{};
109
Davide Pesavento51493502019-07-17 02:26:44 -0400110} // namespace ndn
111
112#endif // BOOST_VERSION >= 106100
Davide Pesavento09904412021-03-24 16:40:53 -0400113#endif // NDN_CXX_UTIL_OVERLOAD_HPP