/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2017-2018 Danny Robson */ #ifndef CRUFT_UTIL_VARIADIC_HPP #define CRUFT_UTIL_VARIADIC_HPP #include #include #include #include namespace cruft::variadic { /////////////////////////////////////////////////////////////////////////// /// do nothing with a set of parameters. /// /// useful for temporarily silencing unused argument warnings in parameter /// packs, or for avoiding assignment of [[gnu::warn_unused_result]] to a /// temporary value we'd just cast to void anyway (GCC#66425). /// /// it is guaranteed that this function will never be defined out in /// debug/release/whatever builds. so it is safe to use to guarantee /// parameter evaluation. template void ignore (const Args&...) noexcept ((std::is_nothrow_destructible_v && ...)) { ; } /////////////////////////////////////////////////////////////////////////// namespace detail { // using the strategy of discarding assignment from: // https://attugit.github.io/2015/02/Accessing-nth-element-of-parameter-pack/ struct discard { template constexpr discard (ArgsT&&...) { ; } }; template using discard_n = discard; template > struct getter; template struct getter> { template decltype(auto) operator() (discard_n..., ValueT &&val, TailT&&...) const { return std::forward (val); } }; } /// Returns the argument at index `IndexV', as if we called: /// std::get (std::make_tuple (...)) template decltype(auto) get (ArgsT&& ...args) { return detail::getter {}(std::forward (args)...); } /////////////////////////////////////////////////////////////////////////// /// returns a tuple of all arguments that satisfy the trait QueryT template