Skip to content

Commit

Permalink
Add backport of std::variant (open-telemetry#59)
Browse files Browse the repository at this point in the history
* Add varint files

* Fill out variant backport

* Add type_pack_element

* Add variant_size

* Add variant_alternative

* Fill out variant

* Fill out variant backport

* Fill out variant back port

* Fill out variant backport

* Fill out variant

* Fill out variant

* Add variant test

* Add get tests

* Add visit test

* Add more tests

* Fix variant tests

* Rename

* Reformat

* Add copyrights

* Add more variant tests

* Reformat

* Add more tests

* Fix for gcc-4.8

* Fix gcc-4.8 issue

* Rename macro

* Handle bools better
  • Loading branch information
rnburn authored May 1, 2020
1 parent 7479aa1 commit 176966a
Show file tree
Hide file tree
Showing 23 changed files with 2,385 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
- run: ./ci/setup_ci_environment.sh
- run: ./ci/install_bazelisk.sh
- run: ./ci/install_gcc48.sh
- run: CC=/usr/bin/g++-4.8 ./ci/do_ci.sh bazel.legacy.test
- run: CC=/usr/bin/gcc-4.8 ./ci/do_ci.sh bazel.legacy.test

bazel_test:
resource_class: xlarge
Expand Down
11 changes: 11 additions & 0 deletions api/include/opentelemetry/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#pragma once

#ifndef __has_include
# define OPENTELEMETRY_HAS_INCLUDE(x) 0
#else
# define OPENTELEMETRY_HAS_INCLUDE(x) __has_include(x)
#endif

#if !defined(__GLIBCXX__) || OPENTELEMETRY_HAS_INCLUDE(<codecvt>) // >= libstdc++-5
# define OPENTELEMETRY_TRIVIALITY_TYPE_TRAITS
#endif
18 changes: 18 additions & 0 deletions api/include/opentelemetry/nostd/detail/all.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#pragma once

#include <type_traits>

#include "opentelemetry/nostd/utility.h"
#include "opentelemetry/version.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace nostd
{
namespace detail
{
template <bool... Bs>
using all = std::is_same<integer_sequence<bool, true, Bs...>, integer_sequence<bool, Bs..., true>>;

} // namespace detail
} // namespace nostd
OPENTELEMETRY_END_NAMESPACE
13 changes: 13 additions & 0 deletions api/include/opentelemetry/nostd/detail/decay.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once

#include <type_traits>

#include "opentelemetry/version.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace nostd
{
template <class T>
using decay_t = typename std::decay<T>::type;
} // namespace nostd
OPENTELEMETRY_END_NAMESPACE
17 changes: 17 additions & 0 deletions api/include/opentelemetry/nostd/detail/dependent_type.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once

#include <type_traits>

#include "opentelemetry/version.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace nostd
{
namespace detail
{
template <typename T, bool>
struct dependent_type : T
{};
} // namespace detail
} // namespace nostd
OPENTELEMETRY_END_NAMESPACE
61 changes: 61 additions & 0 deletions api/include/opentelemetry/nostd/detail/find_index.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// MPark.Variant
//
// Copyright Michael Park, 2015-2017
// Copyright OpenTelemetry Authors, 2020
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file third_party/boost/LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)

#pragma once

#include <cstddef>

#include "opentelemetry/nostd/type_traits.h"
#include "opentelemetry/nostd/utility.h"
#include "opentelemetry/version.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace nostd
{
namespace detail
{
constexpr std::size_t not_found = static_cast<std::size_t>(-1);
constexpr std::size_t ambiguous = static_cast<std::size_t>(-2);

inline constexpr std::size_t find_index_impl(std::size_t result, std::size_t)
{
return result;
}

template <typename... Bs>
inline constexpr std::size_t find_index_impl(std::size_t result, std::size_t idx, bool b, Bs... bs)
{
return b ? (result != not_found ? ambiguous : find_index_impl(idx, idx + 1, bs...))
: find_index_impl(result, idx + 1, bs...);
}

template <typename T, typename... Ts>
inline constexpr std::size_t find_index()
{
return find_index_impl(not_found, 0, std::is_same<T, Ts>::value...);
}

template <std::size_t I>
using find_index_sfinae_impl =
enable_if_t<I != not_found && I != ambiguous, std::integral_constant<std::size_t, I>>;

template <typename T, typename... Ts>
using find_index_sfinae = find_index_sfinae_impl<find_index<T, Ts...>()>;

template <std::size_t I>
struct find_index_checked_impl : std::integral_constant<std::size_t, I>
{
static_assert(I != not_found, "the specified type is not found.");
static_assert(I != ambiguous, "the specified type is ambiguous.");
};

template <typename T, typename... Ts>
using find_index_checked = find_index_checked_impl<find_index<T, Ts...>()>;
} // namespace detail
} // namespace nostd
OPENTELEMETRY_END_NAMESPACE
60 changes: 60 additions & 0 deletions api/include/opentelemetry/nostd/detail/functional.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#pragma once

#include <utility>

#include "opentelemetry/version.h"

#define OPENTELEMETRY_RETURN(...) \
noexcept(noexcept(__VA_ARGS__))->decltype(__VA_ARGS__) { return __VA_ARGS__; }

OPENTELEMETRY_BEGIN_NAMESPACE
namespace nostd
{
namespace detail
{
struct equal_to
{
template <typename Lhs, typename Rhs>
inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
OPENTELEMETRY_RETURN(std::forward<Lhs>(lhs) == std::forward<Rhs>(rhs))
};

struct not_equal_to
{
template <typename Lhs, typename Rhs>
inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
OPENTELEMETRY_RETURN(std::forward<Lhs>(lhs) != std::forward<Rhs>(rhs))
};

struct less
{
template <typename Lhs, typename Rhs>
inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
OPENTELEMETRY_RETURN(std::forward<Lhs>(lhs) < std::forward<Rhs>(rhs))
};

struct greater
{
template <typename Lhs, typename Rhs>
inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
OPENTELEMETRY_RETURN(std::forward<Lhs>(lhs) > std::forward<Rhs>(rhs))
};

struct less_equal
{
template <typename Lhs, typename Rhs>
inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
OPENTELEMETRY_RETURN(std::forward<Lhs>(lhs) <= std::forward<Rhs>(rhs))
};

struct greater_equal
{
template <typename Lhs, typename Rhs>
inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
OPENTELEMETRY_RETURN(std::forward<Lhs>(lhs) >= std::forward<Rhs>(rhs))
};
} // namespace detail
} // namespace nostd
OPENTELEMETRY_END_NAMESPACE

#undef OPENTELEMETRY_RETURN
155 changes: 155 additions & 0 deletions api/include/opentelemetry/nostd/detail/invoke.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
#pragma once

#include <type_traits>
#include <utility>

#include "opentelemetry/nostd/detail/decay.h"
#include "opentelemetry/nostd/detail/void.h"
#include "opentelemetry/version.h"

#define OPENTELEMETRY_RETURN(...) \
noexcept(noexcept(__VA_ARGS__))->decltype(__VA_ARGS__) { return __VA_ARGS__; }

OPENTELEMETRY_BEGIN_NAMESPACE
namespace nostd
{
namespace detail
{

template <typename T>
struct is_reference_wrapper : std::false_type
{};

template <typename T>
struct is_reference_wrapper<std::reference_wrapper<T>> : std::true_type
{};

template <bool, int>
struct Invoke;

template <>
struct Invoke<true /* pmf */, 0 /* is_base_of */>
{
template <typename R, typename T, typename Arg, typename... Args>
inline static constexpr auto invoke(R T::*pmf, Arg &&arg, Args &&... args)
OPENTELEMETRY_RETURN((std::forward<Arg>(arg).*pmf)(std::forward<Args>(args)...))
};

template <>
struct Invoke<true /* pmf */, 1 /* is_reference_wrapper */>
{
template <typename R, typename T, typename Arg, typename... Args>
inline static constexpr auto invoke(R T::*pmf, Arg &&arg, Args &&... args)
OPENTELEMETRY_RETURN((std::forward<Arg>(arg).get().*pmf)(std::forward<Args>(args)...))
};

template <>
struct Invoke<true /* pmf */, 2 /* otherwise */>
{
template <typename R, typename T, typename Arg, typename... Args>
inline static constexpr auto invoke(R T::*pmf, Arg &&arg, Args &&... args)
OPENTELEMETRY_RETURN(((*std::forward<Arg>(arg)).*pmf)(std::forward<Args>(args)...))
};

template <>
struct Invoke<false /* pmo */, 0 /* is_base_of */>
{
template <typename R, typename T, typename Arg>
inline static constexpr auto invoke(R T::*pmo, Arg &&arg)
OPENTELEMETRY_RETURN(std::forward<Arg>(arg).*pmo)
};

template <>
struct Invoke<false /* pmo */, 1 /* is_reference_wrapper */>
{
template <typename R, typename T, typename Arg>
inline static constexpr auto invoke(R T::*pmo, Arg &&arg)
OPENTELEMETRY_RETURN(std::forward<Arg>(arg).get().*pmo)
};

template <>
struct Invoke<false /* pmo */, 2 /* otherwise */>
{
template <typename R, typename T, typename Arg>
inline static constexpr auto invoke(R T::*pmo, Arg &&arg)
OPENTELEMETRY_RETURN((*std::forward<Arg>(arg)).*pmo)
};

template <typename R, typename T, typename Arg, typename... Args>
inline constexpr auto invoke_impl(R T::*f, Arg &&arg, Args &&... args)
OPENTELEMETRY_RETURN(Invoke<std::is_function<R>::value,
(std::is_base_of<T, decay_t<Arg>>::value
? 0
: is_reference_wrapper<decay_t<Arg>>::value ? 1 : 2)>::
invoke(f, std::forward<Arg>(arg), std::forward<Args>(args)...))

#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable : 4100)
#endif
template <typename F, typename... Args>
inline constexpr auto invoke_impl(F &&f, Args &&... args)
OPENTELEMETRY_RETURN(std::forward<F>(f)(std::forward<Args>(args)...))
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // namespace detail

template <typename F, typename... Args>
inline constexpr auto invoke(F &&f, Args &&... args)
OPENTELEMETRY_RETURN(detail::invoke_impl(std::forward<F>(f), std::forward<Args>(args)...));

namespace detail
{

template <typename Void, typename, typename...>
struct invoke_result
{};

template <typename F, typename... Args>
struct invoke_result<void_t<decltype(nostd::invoke(std::declval<F>(), std::declval<Args>()...))>,
F,
Args...>
{
using type = decltype(nostd::invoke(std::declval<F>(), std::declval<Args>()...));
};

} // namespace detail

template <typename F, typename... Args>
using invoke_result = detail::invoke_result<void, F, Args...>;

template <typename F, typename... Args>
using invoke_result_t = typename invoke_result<F, Args...>::type;

namespace detail
{

template <typename Void, typename, typename...>
struct is_invocable : std::false_type
{};

template <typename F, typename... Args>
struct is_invocable<void_t<invoke_result_t<F, Args...>>, F, Args...> : std::true_type
{};

template <typename Void, typename, typename, typename...>
struct is_invocable_r : std::false_type
{};

template <typename R, typename F, typename... Args>
struct is_invocable_r<void_t<invoke_result_t<F, Args...>>, R, F, Args...>
: std::is_convertible<invoke_result_t<F, Args...>, R>
{};

} // namespace detail

template <typename F, typename... Args>
using is_invocable = detail::is_invocable<void, F, Args...>;

template <typename R, typename F, typename... Args>
using is_invocable_r = detail::is_invocable_r<void, R, F, Args...>;
} // namespace nostd
OPENTELEMETRY_END_NAMESPACE

#undef OPENTELEMETRY_RETURN
Loading

0 comments on commit 176966a

Please sign in to comment.