Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 57 additions & 9 deletions include/iris/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,27 @@

#include <version>

#if defined(_MSC_VER) && \
!defined(__clang__) && \
!defined(__INTEL_COMPILER) && !defined(__INTEL_LLVM_COMPILER)
# define IRIS_COMPILER_STRICTLY_MSVC 1
#else
# define IRIS_COMPILER_STRICTLY_MSVC 0
#endif

#if defined(_MSC_VER) && defined(__clang__)
# define IRIS_COMPILER_CLANG_CL 1
#else
# define IRIS_COMPILER_CLANG_CL 0
#endif

#if defined(_MSC_VER) && defined(__INTELLISENSE__)
# define IRIS_MSVC_INTELLISENSE 1
#else
# define IRIS_MSVC_INTELLISENSE 0
#endif


#if _MSC_VER
# include <CppCoreCheck/warnings.h>
# pragma warning(default: CPPCORECHECK_LIFETIME_WARNINGS)
Expand All @@ -18,26 +39,53 @@
# error "Too old MSVC version; we don't support this because it leads to ODR violation regarding the existence of [[(msvc::)no_unique_address]]"
#endif

#if _MSC_VER && __INTELLISENSE__ // Memory Layout view shows wrong layout without this workaround
#if IRIS_MSVC_INTELLISENSE // Memory Layout view shows wrong layout without this workaround
# define IRIS_NO_UNIQUE_ADDRESS [[msvc::no_unique_address, no_unique_address]]

#elif _MSC_VER // normal MSVC
#elif IRIS_COMPILER_STRICTLY_MSVC
# define IRIS_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]]

#else // other compilers
#elif defined(_MSC_VER)
# if __has_cpp_attribute(msvc::no_unique_address)
# define IRIS_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]]
# else
# define IRIS_NO_UNIQUE_ADDRESS [[no_unique_address]]
# endif

#else
# define IRIS_NO_UNIQUE_ADDRESS [[no_unique_address]]
#endif

#ifndef IRIS_LIFETIMEBOUND
# ifdef __clang__
# define IRIS_LIFETIMEBOUND [[clang::lifetimebound]]
# elifdef _MSC_VER
# define IRIS_LIFETIMEBOUND [[msvc::lifetimebound]]

#if IRIS_COMPILER_STRICTLY_MSVC
# define IRIS_EBO __declspec(empty_bases)

#elif IRIS_COMPILER_CLANG_CL
# if __has_declspec_attribute(empty_bases)
# define IRIS_EBO __declspec(empty_bases)
# else
# define IRIS_LIFETIMEBOUND
# define IRIS_EBO
# endif

#else
# define IRIS_EBO
#endif


#if IRIS_MSVC_INTELLISENSE
# define IRIS_LIFETIMEBOUND [[msvc::lifetimebound]]

#elif __has_cpp_attribute(clang::lifetimebound)
# define IRIS_LIFETIMEBOUND [[clang::lifetimebound]]

#elif __has_cpp_attribute(msvc::lifetimebound)
# define IRIS_LIFETIMEBOUND [[msvc::lifetimebound]]

#else
# define IRIS_LIFETIMEBOUND
#endif


#if __cpp_consteval >= 202211L
# define IRIS_CONSTEXPR_UP constexpr
#else
Expand Down
43 changes: 43 additions & 0 deletions test/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,49 @@

namespace unit_test {

TEST_CASE("EBO")
{
// https://learn.microsoft.com/en-us/cpp/cpp/empty-bases

struct Empty1 {};
STATIC_CHECK(sizeof(Empty1) == 1);

struct Struct1 { char c; };
STATIC_CHECK(sizeof(Struct1) == 1);

struct Derived1 : Empty1 { char c; };
STATIC_CHECK(sizeof(Derived1) == 1);

struct Empty2 : Empty1 {};
struct Derived2 : Empty2 { char c; };
STATIC_CHECK(sizeof(Derived2) == 1);

struct Empty3 {};
struct Derived3 : Empty2, Empty3 { char c; };
struct Derived4 : Empty2, Empty3 { std::int32_t i; };
struct Struct2 : Struct1, Empty1 {};
STATIC_CHECK(sizeof(Struct2) == 1);

#if !IRIS_COMPILER_STRICTLY_MSVC
STATIC_CHECK(sizeof(Derived3) == 1);
STATIC_CHECK(sizeof(Derived4) == 4);
#endif

struct IRIS_EBO Derived3_fixed : Empty2, Empty3 { char c; };
STATIC_CHECK(sizeof(Derived3_fixed) == 1);

struct IRIS_EBO Derived4_fixed : Empty2, Empty3 { std::int32_t i; };
STATIC_CHECK(sizeof(Derived4_fixed) == 4);

struct IRIS_EBO Derived5 : Derived4 {};
#if !IRIS_COMPILER_STRICTLY_MSVC
STATIC_CHECK(sizeof(Derived5) == 4);
#endif

struct Derived5_fixed : Derived4_fixed {};
STATIC_CHECK(sizeof(Derived5_fixed) == 4);
}

TEST_CASE("pack_indexing")
{
STATIC_REQUIRE(std::is_same_v<iris::pack_indexing_t<0, int>, int>);
Expand Down
Loading