// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- // vim: ts=8 sw=2 smarttab /* * Ceph - scalable distributed file system * * Copyright (C) 2004-2006 Sage Weil * * This is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software * Foundation. See file COPYING. * */ #include #include #include #include #include #include #include #ifndef CEPH_COMMON_CONVENIENCE_H #define CEPH_COMMON_CONVENIENCE_H namespace ceph { // boost::optional is wonderful! Unfortunately it lacks a function for // the thing you would most obviously want to do with it: apply a // function to its contents. // There are two obvious candidates. The first is a function that // takes a function and an optional value and returns an optional // value, either holding the return value of the function or holding // nothing. // // I'd considered making more overloads for mutable lvalue // references, but those are going a bit beyond likely use cases. // template auto maybe_do(const boost::optional& t, F&& f) -> boost::optional)>> { if (t) return { std::forward(f)(*t) }; else return boost::none; } // The other obvious function takes an optional but returns an // ‘unwrapped’ value, either the result of evaluating the function or // a provided alternate value. // template auto maybe_do_or(const boost::optional& t, F&& f, U&& u) -> std::result_of_t)> { static_assert(std::is_convertible_v>, "Alternate value must be convertible to function return type."); if (t) return std::forward(f)(*t); else return std::forward(u); } // Same thing but for std::optional template auto maybe_do(const std::optional& t, F&& f) -> std::optional)>> { if (t) return { std::forward(f)(*t) }; else return std::nullopt; } // The other obvious function takes an optional but returns an // ‘unwrapped’ value, either the result of evaluating the function or // a provided alternate value. // template auto maybe_do_or(const std::optional& t, F&& f, U&& u) -> std::result_of_t)> { static_assert(std::is_convertible_v>, "Alternate value must be convertible to function return type."); if (t) return std::forward(f)(*t); else return std::forward(u); } namespace _convenience { template inline void for_each_helper(const std::tuple& t, const F& f, std::index_sequence) { (f(std::get(t)), ..., void()); } template inline void for_each_helper(std::tuple& t, const F& f, std::index_sequence) { (f(std::get(t)), ..., void()); } template inline void for_each_helper(const std::tuple& t, F& f, std::index_sequence) { (f(std::get(t)), ..., void()); } template inline void for_each_helper(std::tuple& t, F& f, std::index_sequence) { (f(std::get(t)), ..., void()); } } template inline void for_each(const std::tuple& t, const F& f) { _convenience::for_each_helper(t, f, std::index_sequence_for{}); } template inline void for_each(std::tuple& t, const F& f) { _convenience::for_each_helper(t, f, std::index_sequence_for{}); } template inline void for_each(const std::tuple& t, F& f) { _convenience::for_each_helper(t, f, std::index_sequence_for{}); } template inline void for_each(std::tuple& t, F& f) { _convenience::for_each_helper(t, f, std::index_sequence_for{}); } } #endif // CEPH_COMMON_CONVENIENCE_H