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

feat: Minimal example for using C++20 concepts #2034

Merged
merged 8 commits into from
Apr 17, 2023
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
6 changes: 6 additions & 0 deletions Core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,15 @@ configure_file(
# source files will be added later
add_library(
ActsCore SHARED "")

target_compile_features(
ActsCore
PUBLIC ${ACTS_CXX_STANDARD_FEATURE})

if(ACTS_CONCEPTS_SUPPORTED)
target_compile_definitions(ActsCore PUBLIC ACTS_CONCEPTS_SUPPORTED)
endif()

target_include_directories(
ActsCore
PUBLIC
Expand Down
25 changes: 25 additions & 0 deletions Core/include/Acts/Geometry/SurfaceVisitorConcept.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// This file is part of the Acts project.
//
// Copyright (C) 2023 CERN for the benefit of the Acts project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#pragma once

#include "Acts/Surfaces/Surface.hpp"

#if defined(ACTS_CONCEPTS_SUPPORTED)
#include <concepts>

namespace Acts {

template <typename T>
concept SurfaceVisitor = requires(T v) {
{v(std::declval<const Surface*>())};
};

} // namespace Acts

#endif
4 changes: 3 additions & 1 deletion Core/include/Acts/Geometry/TrackingGeometry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
#include "Acts/Definitions/Algebra.hpp"
#include "Acts/Geometry/GeometryContext.hpp"
#include "Acts/Geometry/GeometryIdentifier.hpp"
#include "Acts/Geometry/SurfaceVisitorConcept.hpp"
#include "Acts/Geometry/TrackingVolume.hpp"
#include "Acts/Utilities/Concepts.hpp"
#include "Acts/Utilities/Logger.hpp"

#include <memory>
Expand Down Expand Up @@ -97,7 +99,7 @@ class TrackingGeometry {
///
/// @param visitor The callable. Will be called for each sensitive surface
/// that is found
template <typename visitor_t>
template <ACTS_CONCEPT(SurfaceVisitor) visitor_t>
void visitSurfaces(visitor_t&& visitor) const {
highestTrackingVolume()->template visitSurfaces<visitor_t>(
std::forward<visitor_t>(visitor));
Expand Down
4 changes: 3 additions & 1 deletion Core/include/Acts/Geometry/TrackingVolume.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@
#include "Acts/Geometry/GeometryContext.hpp"
#include "Acts/Geometry/GeometryIdentifier.hpp"
#include "Acts/Geometry/Layer.hpp"
#include "Acts/Geometry/SurfaceVisitorConcept.hpp"
#include "Acts/Geometry/Volume.hpp"
#include "Acts/Material/IVolumeMaterial.hpp"
#include "Acts/Surfaces/BoundaryCheck.hpp"
#include "Acts/Surfaces/Surface.hpp"
#include "Acts/Utilities/BinnedArray.hpp"
#include "Acts/Utilities/BoundingBox.hpp"
#include "Acts/Utilities/Concepts.hpp"
#include "Acts/Utilities/Frustum.hpp"
#include "Acts/Utilities/Logger.hpp"
#include "Acts/Utilities/Ray.hpp"
Expand Down Expand Up @@ -245,7 +247,7 @@ class TrackingVolume : public Volume {
///
/// If a context is needed for the vist, the vistitor has to provide this
/// e.g. as a private member
template <typename visitor_t>
template <ACTS_CONCEPT(SurfaceVisitor) visitor_t>
void visitSurfaces(visitor_t&& visitor) const {
if (!m_confinedVolumes) {
// no sub volumes => loop over the confined layers
Expand Down
21 changes: 21 additions & 0 deletions Core/include/Acts/Utilities/Concepts.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// This file is part of the Acts project.
//
// Copyright (C) 2022 CERN for the benefit of the Acts project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#pragma once

#if defined(ACTS_CONCEPTS_SUPPORTED)

#define ACTS_REQUIRES(x) requires(x)
#define ACTS_CONCEPT(x) x

#else

#define ACTS_REQUIRES(x)
#define ACTS_CONCEPT(x) typename

#endif
24 changes: 24 additions & 0 deletions cmake/ActsCompilerOptions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ set(ACTS_CXX_FLAGS_MINSIZEREL "")
set(ACTS_CXX_FLAGS_RELEASE "")
set(ACTS_CXX_FLAGS_RELWITHDEBINFO "")

set(ACTS_CXX_STANDARD 17)
set(ACTS_CXX_STANDARD_FEATURE cxx_std_17)
if(DEFINED CMAKE_CXX_STANDARD)
if(${CMAKE_CXX_STANDARD} GREATER_EQUAL 17)
set(ACTS_CXX_STANDARD ${CMAKE_CXX_STANDARD})
set(ACTS_CXX_STANDARD_FEATURE "cxx_std_${CMAKE_CXX_STANDARD}")
else()
message(ERROR "CMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}, but ACTS requires C++ >=17")
Expand Down Expand Up @@ -53,3 +55,25 @@ set(CMAKE_MACOSX_RPATH 1)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
# set relative library path for ACTS libraries
set(CMAKE_INSTALL_RPATH "\$ORIGIN/../${CMAKE_INSTALL_LIBDIR}")

if(${ACTS_CXX_STANDARD} GREATER_EQUAL 20)
file(WRITE
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/concepts.cpp"
"#include <concepts>\n"
"template<class T, class U>\n"
"concept Derived = std::is_base_of<U, T>::value;\n"
"struct A {}; struct B : public A {};"
"int main() { static_assert(Derived<B, A>, \"works\"); }\n" )

message(CHECK_START "Are C++20 concepts supported")
try_compile(ACTS_CONCEPTS_SUPPORTED "${CMAKE_BINARY_DIR}"
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/concepts.cpp"
CXX_STANDARD 20
OUTPUT_VARIABLE __OUTPUT)

if(ACTS_CONCEPTS_SUPPORTED)
message(CHECK_PASS "yes")
else()
message(CHECK_FAIL "no")
endif()
endif()