Skip to content

iceoryx_hoofs/cxx/functional_interface.hpp🔗

Namespaces🔗

Name
iox
building block to easily create free function for logging in a library context
iox::cxx
iox::cxx::internal

Source code🔗

// Copyright (c) 2022 by Apex.AI Inc. 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_HOOFS_CXX_FUNCTIONAL_POLICY_HPP
#define IOX_HOOFS_CXX_FUNCTIONAL_POLICY_HPP

#include "iceoryx_hoofs/cxx/function_ref.hpp"
#include "iceoryx_hoofs/cxx/helplets.hpp"
#include <iostream>
#include <utility>

namespace iox
{
namespace cxx
{
namespace internal
{
template <typename Derived, class = void>
struct HasValueMethod : std::false_type
{
};

template <typename Derived>
struct HasValueMethod<Derived, cxx::void_t<decltype(std::declval<Derived>().value())>> : std::true_type
{
};

template <typename Derived, class = void>
struct HasGetErrorMethod : std::false_type
{
};

template <typename Derived>
struct HasGetErrorMethod<Derived, cxx::void_t<decltype(std::declval<Derived>().get_error())>> : std::true_type
{
};

template <typename Derived>
struct Expect
{
    void expect(const char* const msg) const noexcept;
};

template <typename Derived, typename ValueType>
struct ExpectWithValue
{
    //         the method prints the provided message and induces a fatal error
    ValueType& expect(const char* const msg) & noexcept;

    //         the method prints the provided message and induces a fatal error
    const ValueType& expect(const char* const msg) const& noexcept;

    //         the method prints the provided message and induces a fatal error
    ValueType&& expect(const char* const msg) && noexcept;

    //         the method prints the provided message and induces a fatal error
    const ValueType&& expect(const char* const msg) const&& noexcept;
};

template <typename Derived, typename ValueType>
struct ValueOr
{
    template <typename U>
    ValueType value_or(U&& alternative) const& noexcept;

    template <typename U>
    ValueType value_or(U&& alternative) && noexcept;
};

template <typename Derived, typename ValueType>
struct AndThenWithValue
{
    using and_then_callback_t = cxx::function_ref<void(ValueType&)>;
    using const_and_then_callback_t = cxx::function_ref<void(const ValueType&)>;

    Derived& and_then(const and_then_callback_t& callable) & noexcept;

    const Derived& and_then(const const_and_then_callback_t& callable) const& noexcept;

    Derived&& and_then(const and_then_callback_t& callable) && noexcept;

    const Derived&& and_then(const const_and_then_callback_t& callable) const&& noexcept;
};

template <typename Derived>
struct AndThen
{
    using and_then_callback_t = cxx::function_ref<void()>;

    Derived& and_then(const and_then_callback_t& callable) & noexcept;

    const Derived& and_then(const and_then_callback_t& callable) const& noexcept;

    Derived&& and_then(const and_then_callback_t& callable) && noexcept;

    const Derived&& and_then(const and_then_callback_t& callable) const&& noexcept;
};

template <typename Derived, typename ErrorType>
struct OrElseWithValue
{
    using or_else_callback_t = cxx::function_ref<void(ErrorType&)>;
    using const_or_else_callback_t = cxx::function_ref<void(const ErrorType&)>;

    Derived& or_else(const or_else_callback_t& callable) & noexcept;

    const Derived& or_else(const const_or_else_callback_t& callable) const& noexcept;

    Derived&& or_else(const or_else_callback_t& callable) && noexcept;

    const Derived&& or_else(const const_or_else_callback_t& callable) const&& noexcept;
};

template <typename Derived>
struct OrElse
{
    using or_else_callback_t = cxx::function_ref<void()>;

    Derived& or_else(const or_else_callback_t& callable) & noexcept;

    const Derived& or_else(const or_else_callback_t& callable) const& noexcept;

    Derived&& or_else(const or_else_callback_t& callable) && noexcept;

    const Derived&& or_else(const or_else_callback_t& callable) const&& noexcept;
};

template <typename Derived, typename ValueType, typename ErrorType>
struct FunctionalInterfaceImpl : public ExpectWithValue<Derived, ValueType>,
                                 public ValueOr<Derived, ValueType>,
                                 public AndThenWithValue<Derived, ValueType>,
                                 public OrElseWithValue<Derived, ErrorType>
{
};

template <typename Derived>
struct FunctionalInterfaceImpl<Derived, void, void>
    : public Expect<Derived>, public AndThen<Derived>, public OrElse<Derived>
{
};

template <typename Derived, typename ValueType>
struct FunctionalInterfaceImpl<Derived, ValueType, void> : public ExpectWithValue<Derived, ValueType>,
                                                           public ValueOr<Derived, ValueType>,
                                                           public AndThenWithValue<Derived, ValueType>,
                                                           public OrElse<Derived>
{
};

template <typename Derived, typename ErrorType>
struct FunctionalInterfaceImpl<Derived, void, ErrorType>
    : public Expect<Derived>, public AndThen<Derived>, public OrElseWithValue<Derived, ErrorType>
{
};
} // namespace internal

template <typename Derived, typename ValueType, typename ErrorType>
using FunctionalInterface = internal::FunctionalInterfaceImpl<Derived, ValueType, ErrorType>;

} // namespace cxx
} // namespace iox

#include "iceoryx_hoofs/internal/cxx/functional_interface.inl"

#endif

Updated on 2 April 2022 at 16:37:47 CEST