Skip to content

Commit

Permalink
Reintroduce friend declarations for MSVC.
Browse files Browse the repository at this point in the history
This commit reintroduces the friend decrations removed in `20be06f` for
MSVC. Certain versions of MSVC (toolset 141, possibly others) fail to
compile otherwise.

Furthermore, this commit adds CI to compile HighFive on a wider range of
MSVC compilers.
  • Loading branch information
1uc committed Apr 5, 2023
1 parent d04c691 commit 4aec900
Show file tree
Hide file tree
Showing 11 changed files with 120 additions and 6 deletions.
47 changes: 45 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,13 @@ jobs:

# Job testing in Windows
# ======================
Windows:
runs-on: Windows-latest
Windows-2022:
runs-on: ${{matrix.os}}
strategy:
matrix:
os: [ "windows-2022"]
vs-toolset: [ "v141", "v143" ]
cxxstd: ["14", "17"]
steps:
- uses: actions/checkout@v3
with:
Expand All @@ -276,6 +281,8 @@ jobs:
shell: bash -l {0}
run: |
CMAKE_OPTIONS=(
-T ${{matrix.vs-toolset}}
-DCMAKE_CXX_STANDARD=${{matrix.cxxstd}}
-DHIGHFIVE_UNIT_TESTS=ON
-DHIGHFIVE_USE_BOOST:BOOL=ON
-DHIGHFIVE_USE_EIGEN:BOOL=ON
Expand All @@ -289,3 +296,39 @@ jobs:
shell: bash -l {0}
run: ctest --output-on-failure -C $BUILD_TYPE

Windows-2019:
runs-on: ${{matrix.os}}
strategy:
matrix:
os: [ "windows-2019"]
vs-toolset: [ "v142" ]
cxxstd: ["14", "17"]
steps:
- uses: actions/checkout@v3
with:
submodules: true

- uses: mamba-org/provision-with-micromamba@main
with:
environment-file: doc/environment.yaml
environment-name: win-test

- name: Build
shell: bash -l {0}
run: |
CMAKE_OPTIONS=(
-T ${{matrix.vs-toolset}}
-DCMAKE_CXX_STANDARD=${{matrix.cxxstd}}
-DHIGHFIVE_UNIT_TESTS=ON
-DHIGHFIVE_USE_BOOST:BOOL=ON
-DHIGHFIVE_USE_EIGEN:BOOL=ON
-DHIGHFIVE_USE_XTENSOR:BOOL=ON
-DHIGHFIVE_TEST_SINGLE_INCLUDES=ON
)
source $GITHUB_WORKSPACE/.github/build.sh
- name: Test
working-directory: ${{github.workspace}}/build
shell: bash -l {0}
run: ctest --output-on-failure -C $BUILD_TYPE

4 changes: 4 additions & 0 deletions CMake/HighFiveTargetDeps.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ if(NOT TARGET libdeps)
target_compile_definitions(libdeps INTERFACE -D_GLIBCXX_ASSERTIONS)
endif()

if(HIGHFIVE_HAS_FRIEND_DECLARATIONS)
target_compile_definitions(libdeps INTERFACE -DHIGHFIVE_HAS_FRIEND_DECLARATIONS=1)
endif()

if(HIGHFIVE_SANITIZER)
target_compile_options(libdeps INTERFACE -fsanitize=${HIGHFIVE_SANITIZER})
target_link_options(libdeps INTERFACE -fsanitize=${HIGHFIVE_SANITIZER})
Expand Down
27 changes: 27 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,33 @@ option(HIGHFIVE_BUILD_DOCS "Enable documentation building" ON)
option(HIGHFIVE_VERBOSE "Set logging level to verbose." OFF)
option(HIGHFIVE_GLIBCXX_ASSERTIONS "Enable bounds check for STL." OFF)

# Controls if HighFive classes are friends of each other.
#
# There are two compiler bugs that require incompatible choices. The
# GCC compiler bug [1] prevents us from writing:
#
# template<class D>
# friend class NodeTraits<D>;
#
# While a MSVC compiler bug [2] complains that it can't access a
# protected constructor, e.g., `HighFive::Object::Object`.
#
# Starting with `2.7.0` these friend declarations don't matter
# anymore. It's mearly a means of appeasing a compiler.
#
# The values of `HIGHFIVE_HAS_FRIEND_DECLARATIONS` are:
# - that the macro is undefined.
# - `0` which implies not adding the friend declarations.
# - any non-zero integer, i.e. `1`, to add the friend declarations.
#
# Not defining the macro implies that it'll be set to `1` if MSVC is
# detected (or other compilers requiring the friend declarations).
#
# [1]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52625
# [2]: https://developercommunity.visualstudio.com/t/MSVC-compiler-improperly-implements-N489/1516410
option(HIGHFIVE_HAS_FRIEND_DECLARATIONS "Enable additional friend declarations. Certain compiler require this On, others Off." OFF)
mark_as_advanced(HIGHFIVE_HAS_FRIEND_DECLARATIONS)

set(HIGHFIVE_SANITIZER OFF CACHE STRING "Enable a group of sanitizers, requires compiler support. Supported: 'address' and 'undefined'.")
mark_as_advanced(HIGHFIVE_SANITIZER)

Expand Down
9 changes: 8 additions & 1 deletion include/highfive/H5Attribute.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include "H5DataType.hpp"
#include "H5Object.hpp"
#include "bits/H5Friends.hpp"
#include "bits/H5Path_traits.hpp"

namespace HighFive {
Expand Down Expand Up @@ -112,9 +113,15 @@ class Attribute: public Object, public PathTraits<Attribute> {
// No empty attributes
Attribute() = delete;

private:
protected:
using Object::Object;

private:
#if HIGHFIVE_HAS_FRIEND_DECLARATIONS
template <typename Derivate>
friend class ::HighFive::AnnotateTraits;
#endif

friend Attribute detail::make_attribute(hid_t);
};

Expand Down
3 changes: 1 addition & 2 deletions include/highfive/H5File.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,9 @@ class File: public Object, public NodeTraits<File>, public AnnotateTraits<File>

protected:
File() = default;

private:
using Object::Object;

private:
mutable std::string _filename{};

template <typename>
Expand Down
5 changes: 5 additions & 0 deletions include/highfive/H5Group.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <H5Gpublic.h>

#include "H5Object.hpp"
#include "bits/H5Friends.hpp"
#include "bits/H5_definitions.hpp"
#include "bits/H5Annotate_traits.hpp"
#include "bits/H5Node_traits.hpp"
Expand Down Expand Up @@ -66,6 +67,10 @@ class Group: public Object,
friend Group detail::make_group(hid_t);
friend class File;
friend class Reference;
#if HIGHFIVE_HAS_FRIEND_DECLARATIONS
template <typename Derivate>
friend class ::HighFive::NodeTraits;
#endif
};

inline std::pair<unsigned int, unsigned int> Group::getEstimatedLinkInfo() const {
Expand Down
10 changes: 10 additions & 0 deletions include/highfive/H5Object.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <H5Opublic.h>

#include "bits/H5_definitions.hpp"
#include "bits/H5Friends.hpp"

namespace HighFive {

Expand Down Expand Up @@ -107,6 +108,15 @@ class Object {
friend Object detail::make_object(hid_t);
friend class Reference;
friend class CompoundType;

#if HIGHFIVE_HAS_FRIEND_DECLARATIONS
template <typename Derivate>
friend class NodeTraits;
template <typename Derivate>
friend class AnnotateTraits;
template <typename Derivate>
friend class PathTraits;
#endif
};


Expand Down
8 changes: 7 additions & 1 deletion include/highfive/H5Selection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "H5DataSet.hpp"
#include "H5DataSpace.hpp"
#include "bits/H5Slice_traits.hpp"
#include "bits/H5Friends.hpp"

namespace HighFive {

Expand Down Expand Up @@ -50,12 +51,17 @@ class Selection: public SliceTraits<Selection> {
/// \return return the datatype of the selection
const DataType getDataType() const;

private:
protected:
Selection(const DataSpace& memspace, const DataSpace& file_space, const DataSet& set);

private:
DataSpace _mem_space, _file_space;
DataSet _set;

#if HIGHFIVE_HAS_FRIEND_DECLARATIONS
template <typename Derivate>
friend class ::HighFive::SliceTraits;
#endif
friend Selection detail::make_selection(const DataSpace&, const DataSpace&, const DataSet&);
};

Expand Down
2 changes: 2 additions & 0 deletions include/highfive/H5Utility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#include <string>
#include <iostream>

#include "bits/H5Friends.hpp"

namespace HighFive {

///
Expand Down
10 changes: 10 additions & 0 deletions include/highfive/bits/H5Friends.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once

#ifndef HIGHFIVE_HAS_FRIEND_DECLARATIONS
#ifdef _MSC_VER
// This prevents a compiler bug on certain versions of MSVC.
// Known to fail: Toolset 141.
// See `CMakeLists.txt` for more information.
#define HIGHFIVE_HAS_FRIEND_DECLARATIONS 1
#endif
#endif
1 change: 1 addition & 0 deletions include/highfive/bits/H5Utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <H5public.h>

#include "../H5Exception.hpp"
#include "H5Friends.hpp"

namespace HighFive {

Expand Down

0 comments on commit 4aec900

Please sign in to comment.