Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include <functional> #252

Merged
merged 1 commit into from
Mar 29, 2023
Merged

Conversation

ts826848
Copy link
Contributor

@ts826848 ts826848 commented Mar 28, 2023

This is necessary to avoid compilation errors using recent libc++ versions with C++23 due to libc++ taking steps to remove transitive includes in newer C++ versions 0.

For a more concrete example, this program builds using Clang 16.0.0 and C++20, but fails to build with C++23:

#include <magic_enum.hpp>
enum class ec { RED };
template <>
constexpr auto magic_enum::customize::enum_name(ec val) noexcept
    -> magic_enum::customize::customize_t {
  switch (val) {
  case ec::RED: return "Red";
  };
  return invalid_tag;
}

The compiler hits the "too many errors" threshold when building with C++23, but I believe this is due to compiling failing to recover after the first error. The error message starts with:

include % /usr/local/opt/llvm/bin/clang++ -std=c++2b -c test.cpp
In file included from test.cpp:1:
./magic_enum.hpp:324:61: error: no member named 'equal_to' in namespace 'std'
  return std::is_same_v<std::decay_t<BinaryPredicate>, std::equal_to<string_view::value_type>> ||
                                                       ~~~~~^
./magic_enum.hpp:324:93: error: expected '(' for function-style cast or type construction
  return std::is_same_v<std::decay_t<BinaryPredicate>, std::equal_to<string_view::value_type>> ||
                                                                     ~~~~~~~~~~~~~~~~~~~~~~~^
./magic_enum.hpp:324:96: error: expected expression
  return std::is_same_v<std::decay_t<BinaryPredicate>, std::equal_to<string_view::value_type>> ||
                                                                                               ^

std::equal_to is defined in <functional>, but <functional> is not directly included by magic_enum.hpp. <string> 1 and <string_view> 2 both include <functional> for C++20 and earlier, but they no longer include <functional> in C++23 and later, so a definition for std::equal_to is no longer visible, leading to the above error.

Directly including <functional> fixes this error, but I'm not sure there aren't similar errors.

@Neargye
Copy link
Owner

Neargye commented Mar 29, 2023

Could you check the commit? For me it shows that no files have changed

@ts826848 ts826848 force-pushed the add-functional-include branch from 4d37118 to cfceaeb Compare March 29, 2023 10:29
This is necessary to avoid compilation errors using recent libc++
versions with C++23 due to libc++ taking steps to remove transitive
includes in newer C++ versions [0].

For a more concrete example, this program builds using Clang 16.0.0 and
C++20, but fails to build with C++23:

    #include <magic_enum.hpp>
    enum class ec { RED };
    template <>
    constexpr auto magic_enum::customize::enum_name(ec val) noexcept
        -> magic_enum::customize::customize_t {
      switch (val) {
      case ec::RED: return "Red";
      };
      return invalid_tag;
    }

The compiler hits the "too many errors" threshold when building with
C++23, but I believe this is due to compiling failing to recover after
the first error. The error message starts with:

    include % /usr/local/opt/llvm/bin/clang++ -std=c++2b -c test.cpp
    In file included from test.cpp:1:
    ./magic_enum.hpp:324:61: error: no member named 'equal_to' in namespace 'std'
      return std::is_same_v<std::decay_t<BinaryPredicate>, std::equal_to<string_view::value_type>> ||
                                                           ~~~~~^
    ./magic_enum.hpp:324:93: error: expected '(' for function-style cast or type construction
      return std::is_same_v<std::decay_t<BinaryPredicate>, std::equal_to<string_view::value_type>> ||
                                                                         ~~~~~~~~~~~~~~~~~~~~~~~^
    ./magic_enum.hpp:324:96: error: expected expression
      return std::is_same_v<std::decay_t<BinaryPredicate>, std::equal_to<string_view::value_type>> ||
                                                                                                   ^

std::equal_to is defined in <functional>, but <functional> is not
directly included by magic_enum.hpp. <string> [1] and <string_view> [2]
both include <functional> for C++20 and earlier, but they no longer
include <functional> in C++23 and later, so a definition for
std::equal_to is no longer visible, leading to the above error.

Directly including <functional> fixes this error, but I'm not sure there
aren't similar errors.

[0]: llvm/llvm-project@8ff2d6a

[1]: https://github.com/llvm/llvm-project/blob/llvmorg-16.0.0/libcxx/include/string#L4625

[2]: https://github.com/llvm/llvm-project/blob/llvmorg-16.0.0/libcxx/include/string_view#L1027
@ts826848 ts826848 force-pushed the add-functional-include branch from cfceaeb to c532a95 Compare March 29, 2023 10:32
@ts826848
Copy link
Contributor Author

Ack, sorry! I put off adding the change to grab error messages for the commit message and forgot that I did that!

@Neargye Neargye merged commit 95c71da into Neargye:master Mar 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants