libjmmcg  release_579_6_g8cffd
A C++ library containing an eclectic mix of useful, advanced components.
syscall_wrapper_impl.hpp
Go to the documentation of this file.
1 /******************************************************************************
2 ** Copyright © 2020 by J.M.McGuiness, coder@hussar.me.uk
3 **
4 ** This library is free software; you can redistribute it and/or
5 ** modify it under the terms of the GNU Lesser General Public
6 ** License as published by the Free Software Foundation; either
7 ** version 2.1 of the License, or (at your option) any later version.
8 **
9 ** This library is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 ** Lesser General Public License for more details.
13 **
14 ** You should have received a copy of the GNU Lesser General Public
15 ** License along with this library; if not, write to the Free Software
16 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18 
19 namespace jmmcg { namespace LIBJMMCG_VER_NAMESPACE {
20 
21 template<class FailureTraits, class ...FnArgs>
22 template<class HandleError>
23 inline auto
24 syscall::traits_base<FailureTraits, FnArgs...>::report(fn_ret_code ret, HandleError &&handle_error) noexcept(false) {
25  if (LIKELY(!failure_detection::result(ret, reinterpret_cast<fn_ret_code>(failure_code::value)))) {
26  return ret;
27  } else {
28  handle_error();
29  return fn_ret_code{};
30  }
31 }
32 
33 template<class FailureTraits, class ...Args>
34 void
35 syscall::traits_base<FailureTraits, Args...>::report_error(int err, char const *file_name, unsigned line_num, char const *fn_name, tchar const * const rev_info, tchar const * const err_msg, fn_ret_code (*fn)(Args...), Args ...args) noexcept(false) {
36  info::function fun(
37  line_num,
38  fn_name,
39  typeid(fn)
40  );
41  fun.add_args(info::function::argument(exception_t::thread_traits::demangle_name(typeid(args)).begin(), args)...);
42  throw exception_t(err_msg, std::move(fun), info::revision(rev_info, file_name), err);
43 }
44 
45 template<class FailureTraits, class ...Args>
46 inline auto
47 syscall::simple_report_traits<FailureTraits, Args...>::select_error(int err, char const *file_name, unsigned line_num, char const *fn_name, tchar const * const rev_info, tchar const * const err_msg, fn_ret_code (*fn)(Args...), Args ...args) {
48  return base_t::report_error(err, file_name, line_num, fn_name, rev_info, err_msg, fn, args...);
49 }
50 
51 template<class CaseStatements, class FailureTraits, class ...Args>
52 inline constexpr auto
53 syscall::switch_traits<CaseStatements, FailureTraits, Args...>::select_error(int err, char const *file_name, unsigned line_num, char const *fn_name, tchar const * const rev_info, tchar const * const err_msg, fn_ret_code (*fn)(Args...), Args ...args) {
54  enum : std::size_t {
55  num_statements=std::tuple_size<std::decay_t<case_statements>>::value
56  };
57  BOOST_MPL_ASSERT_RELATION(num_statements, >, 1);
58  private_::unroller<num_statements-1, case_statements>::result(
59  err,
60  [err, file_name, line_num, fn_name, rev_info, err_msg, fn, args...]() {
61  base_t::report_error(err, file_name, line_num, fn_name, rev_info, err_msg, fn, args...);
62  }
63  );
64 }
65 
66 template<
67  template<class, class ...> class Traits,
68  template<class, template<class> class, template<class> class> class FailureTraits,
69  template<class> class FailureCode,
70  template<class> class FailureDetection,
71  class FnReturnType,
72  class ...FnArgs,
73  class ...PassedInArgs
74 >
75 inline FnReturnType
76 syscall::process([[maybe_unused]] char const * const file_name, [[maybe_unused]] unsigned line_num, [[maybe_unused]] char const * const fn_name, [[maybe_unused]] tchar const * const rev_info, [[maybe_unused]] tchar const * const err_msg, FnReturnType (*fn)(FnArgs...), PassedInArgs ...args) noexcept(std::is_same<FnReturnType, void>::value) {
77  using traits_t=Traits<
78  FailureTraits<
79  FnReturnType,
80  FailureCode,
81  FailureDetection
82  >,
83  FnArgs...
84  >;
85  if constexpr (std::is_same<FnReturnType, void>::value) {
86  fn(static_cast<FnArgs>(args)...);
87  } else {
88  auto ret=fn(static_cast<FnArgs>(args)...);
89  return traits_t::report(
90  ret,
91  std::bind(traits_t::select_error, errno, file_name, line_num, fn_name, rev_info, err_msg, fn, args...)
92  );
93  }
94 }
95 
96 } }