iceoryx_utils/internal/cxx/smart_c.inl🔗
Namespaces🔗
Name |
---|
iox building block to easily create free function for logging in a library context |
iox::cxx |
Defines🔗
Name | |
---|---|
IOX_UTILS_CXX_SMART_C_INL |
Macro Documentation🔗
define IOX_UTILS_CXX_SMART_C_INL🔗
#define IOX_UTILS_CXX_SMART_C_INL
Source code🔗
// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0
#ifndef IOX_UTILS_CXX_SMART_C_INL
#define IOX_UTILS_CXX_SMART_C_INL
namespace iox
{
namespace cxx
{
template <typename Function, typename ReturnType, typename... FunctionArguments>
inline SmartC<Function, ReturnType, FunctionArguments...>
makeSmartCImpl(const char* file,
const int line,
const char* func,
const Function& f_function,
const ReturnMode& f_mode,
const std::initializer_list<ReturnType>& f_returnValues,
const std::initializer_list<int>& f_ignoredValues,
FunctionArguments... f_args) noexcept
{
auto retval = SmartC<Function, ReturnType, FunctionArguments...>(file,
line,
func,
f_function,
f_mode,
f_returnValues,
f_ignoredValues,
std::forward<FunctionArguments>(f_args)...);
bool doIgnoreEINTR = false;
if (retval.hasErrors())
{
for (auto& value : f_ignoredValues)
{
if (value == EINTR)
{
doIgnoreEINTR = true;
break;
}
}
}
if (!doIgnoreEINTR)
{
for (int remainingRetrys = 5; retval.hasErrors() && retval.getErrNum() == EINTR && remainingRetrys > 0;
--remainingRetrys)
{
retval = SmartC<Function, ReturnType, FunctionArguments...>(file,
line,
func,
f_function,
f_mode,
f_returnValues,
f_ignoredValues,
std::forward<FunctionArguments>(f_args)...);
}
}
if (retval.hasErrors() && retval.getErrNum())
{
if (!(doIgnoreEINTR && retval.getErrNum() == EINTR))
{
std::cerr << file << ":" << line << " { " << func << " } ::: [ " << retval.getErrNum() << " ] "
<< retval.getErrorString() << std::endl;
}
}
return retval;
}
template <typename Function, typename ReturnType, typename... FunctionArguments>
int SmartC<Function, ReturnType, FunctionArguments...>::resetErrnoAndInitErrnum() noexcept
{
errno = 0;
return 0;
}
template <typename Function, typename ReturnType, typename... FunctionArguments>
SmartC<Function, ReturnType, FunctionArguments...>::SmartC(const char* file,
const int line,
const char* func,
const Function& f_function,
const ReturnMode& f_mode,
const std::initializer_list<ReturnType>& f_returnValues,
const std::initializer_list<int>& f_ignoredValues,
FunctionArguments... f_args) noexcept
: m_errnum(resetErrnoAndInitErrnum())
, m_returnValue(f_function(f_args...))
, m_errorSource{file, line, func}
{
switch (f_mode)
{
case ReturnMode::PRE_DEFINED_ERROR_CODE:
{
m_hasErrors = false;
for (const auto value : f_returnValues)
{
if (value == m_returnValue)
{
m_errnum = errno;
m_errorString.unsafe_assign(std::strerror(m_errnum));
for (const auto ignored : f_ignoredValues)
{
if (m_errnum == ignored)
{
return;
}
}
m_hasErrors = true;
if (m_errnum != EINTR)
{
std::cerr << m_errorSource.file << ":" << m_errorSource.line << " { " << m_errorSource.func
<< " } ::: [ " << m_errnum << " ] " << m_errorString << std::endl;
}
break;
}
}
break;
}
case ReturnMode::PRE_DEFINED_SUCCESS_CODE:
{
m_hasErrors = true;
for (const auto value : f_returnValues)
{
if (value == m_returnValue)
{
m_hasErrors = false;
return;
}
}
m_errnum = errno;
m_errorString.unsafe_assign(std::strerror(m_errnum));
for (const auto ignored : f_ignoredValues)
{
if (m_errnum == ignored)
{
m_hasErrors = false;
return;
}
}
if (m_errnum != EINTR)
{
std::cerr << m_errorSource.file << ":" << m_errorSource.line << " { " << m_errorSource.func << " } ::: [ "
<< m_returnValue << " ] " << m_errorString << std::endl;
}
break;
}
}
}
template <typename Function, typename ReturnType, typename... FunctionArguments>
inline ReturnType SmartC<Function, ReturnType, FunctionArguments...>::getReturnValue() const noexcept
{
return m_returnValue;
}
template <typename Function, typename ReturnType, typename... FunctionArguments>
inline SmartC<Function, ReturnType, FunctionArguments...>::operator ReturnType() const noexcept
{
return getReturnValue();
}
template <typename Function, typename ReturnType, typename... FunctionArguments>
inline bool SmartC<Function, ReturnType, FunctionArguments...>::hasErrors() const noexcept
{
return m_hasErrors;
}
template <typename Function, typename ReturnType, typename... FunctionArguments>
inline const char* SmartC<Function, ReturnType, FunctionArguments...>::getErrorString() const noexcept
{
return m_errorString.c_str();
}
template <typename Function, typename ReturnType, typename... FunctionArguments>
inline int32_t SmartC<Function, ReturnType, FunctionArguments...>::getErrNum() const noexcept
{
return m_errnum;
}
} // namespace cxx
} // namespace iox
#endif // IOX_UTILS_CXX_SMART_C_INL
Updated on 31 May 2022 at 15:29:15 CEST