diff --git a/cmake/stf-config.cmake b/cmake/stf-config.cmake index 6648e8b..4b8502b 100644 --- a/cmake/stf-config.cmake +++ b/cmake/stf-config.cmake @@ -25,7 +25,11 @@ include(stf_linker_setup) setup_stf_linker(true) -add_compile_options(-Werror -std=c++17 -fPIC -Wall -Wextra -pedantic -Wconversion -Wno-unused-parameter -Wno-unused-function -Wno-gnu-zero-variadic-macro-arguments -pipe) +add_compile_options(-Werror -std=c++17 -fPIC -Wall -Wextra -pedantic -Wconversion -Wno-unused-parameter -Wno-unused-function -pipe) + +if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wno-gnu-zero-variadic-macro-arguments) +endif() if (CMAKE_BUILD_TYPE MATCHES "^[Rr]elease") if(NOT DISABLE_STF_DOXYGEN) diff --git a/stf-inc/stf_object.hpp b/stf-inc/stf_object.hpp index 60287d0..637ecf7 100644 --- a/stf-inc/stf_object.hpp +++ b/stf-inc/stf_object.hpp @@ -46,7 +46,7 @@ namespace stf { * \param data Data to write */ template - static inline std::enable_if_t> + static inline std::enable_if_t> write_(STFOFstream& writer, Ts&&... data) { writer << PackedContainer>...>(std::forward(data)...); } @@ -57,7 +57,7 @@ namespace stf { * \param data Data to write */ template - static inline std::enable_if_t>> + static inline std::enable_if_t>> write_(STFOFstream& writer, Ts&&... data) { (writer << ... << data); } @@ -132,7 +132,7 @@ namespace stf { */ template __attribute__((always_inline)) - static inline std::enable_if_t, size_t> + static inline std::enable_if_t, size_t> read_(STFIFstream& reader, Ts&&... data) { PackedContainerView...> temp; reader >> temp; @@ -148,7 +148,7 @@ namespace stf { */ template __attribute__((always_inline)) - static inline std::enable_if_t>, size_t> + static inline std::enable_if_t>, size_t> read_(STFIFstream& reader, Ts&&... data) { (reader >> ... >> data); diff --git a/stf-inc/stf_packed_container.hpp b/stf-inc/stf_packed_container.hpp index 432dc3f..ea967e9 100644 --- a/stf-inc/stf_packed_container.hpp +++ b/stf-inc/stf_packed_container.hpp @@ -14,7 +14,7 @@ namespace stf { */ template class __attribute__ ((packed)) PackedContainer { - static_assert(type_utils::are_trivially_copyable_v, + static_assert(type_utils::are_pod_v, "All types held in a PackedContainer must be trivially copyable!"); private: @@ -49,7 +49,7 @@ namespace stf { template class __attribute__ ((packed)) PackedContainer /**< Specialized definition for the single-member variant */ { - static_assert(std::is_trivially_copyable_v, + static_assert(std::is_pod_v, "All types held in a PackedContainer must be trivially copyable!"); private: diff --git a/stf-inc/stf_protocol_fields.hpp b/stf-inc/stf_protocol_fields.hpp index a3078ce..92c4525 100644 --- a/stf-inc/stf_protocol_fields.hpp +++ b/stf-inc/stf_protocol_fields.hpp @@ -25,6 +25,19 @@ #define DEFAULT_VIS #endif +// Some GCC versions complain about Formatter lambdas that are defined in this header. As far as I can tell, +// these warnings are spurious. This disables the warnings if we're running GCC, but only around fields with +// custom formatters +#if defined(__GNUC__) && !defined(__clang__) + #define FORMATTER_PRAGMA_START \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wsubobject-linkage\"") + #define FORMATTER_PRAGMA_END _Pragma("GCC diagnostic pop") +#else + #define FORMATTER_PRAGMA_START + #define FORMATTER_PRAGMA_END +#endif + // Defines r-value and l-value field class constructors for the given argument type // parent_class_tuple and arg_type should either be bare type names or tuples packed with STF_PACK_TEMPLATE #define __FIELD_CONSTRUCTOR(parent_class_tuple, field_name, arg_type) \ @@ -69,8 +82,10 @@ // The __VA_ARGS__ correspond to the field class template parameters. // The first template parameter *must* be the underlying type of the field #define _FIELD_FORMAT_WRAPPER(fmt, field_macro, field_name, ...) \ - inline static const auto _FIELD_FORMATTER_NAME(field_name) = fmt; \ - field_macro(field_name, __VA_ARGS__, _FIELD_FORMATTER_NAME(field_name)) + FORMATTER_PRAGMA_START \ + inline static constexpr auto _FIELD_FORMATTER_NAME(field_name) = fmt; \ + field_macro(field_name, __VA_ARGS__, _FIELD_FORMATTER_NAME(field_name)); \ + FORMATTER_PRAGMA_END // Declares a subclass of ProtocolField // The __VA_ARGS__ are the template parameters supplied to ProtocolField diff --git a/stf-inc/type_utils.hpp b/stf-inc/type_utils.hpp index 834a8c2..9d1a5cf 100644 --- a/stf-inc/type_utils.hpp +++ b/stf-inc/type_utils.hpp @@ -22,6 +22,12 @@ namespace stf { template inline constexpr bool are_trivially_copyable_v = are_trivially_copyable::value; + template + struct are_pod : std::conjunction>...> {}; + + template + inline constexpr bool are_pod_v = are_pod::value; + template struct is_iterable : std::false_type {};