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
7 changes: 4 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ FetchContent_Declare(
)
# ... and Microsoft's C++ Guideline Support Library
FetchContent_Declare(
GSL
Microsoft.GSL
GIT_REPOSITORY https://github.com/microsoft/GSL
GIT_TAG v4.2.0
GIT_SHALLOW ON
EXCLUDE_FROM_ALL # Do not install
FIND_PACKAGE_ARGS NAMES Microsoft.GSL
FIND_PACKAGE_ARGS
)
# ... and the Mimic C++ mocking framework
FetchContent_Declare(
Expand Down Expand Up @@ -90,7 +90,7 @@ set(DART_TESTING_TIMEOUT 90 CACHE STRING "Timeout (s) for Dart/CTest runs")
set(CTEST_TEST_TIMEOUT 90 CACHE STRING "Per-test timeout (s) for CTest")

# Make tools available
FetchContent_MakeAvailable(Catch2 GSL mimicpp)
FetchContent_MakeAvailable(Catch2 Microsoft.GSL mimicpp)
# Avoid use of __COUNTER__ to prevent -pedantic warnings in Catch2's TEST_CASE macro
set(CATCH_CONFIG_COUNTER OFF)

Expand Down Expand Up @@ -163,6 +163,7 @@ find_package(Boost REQUIRED COMPONENTS json EXPORT)
find_package(TBB REQUIRED EXPORT)
find_package(fmt REQUIRED EXPORT)
find_package(spdlog REQUIRED EXPORT)
find_package(Microsoft.GSL REQUIRED EXPORT)
Comment thread
coderabbitai[bot] marked this conversation as resolved.

# Dependencies required by internal implementation
find_package(Boost REQUIRED COMPONENTS program_options)
Expand Down
13 changes: 7 additions & 6 deletions phlex/driver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
#include "boost/mp11/algorithm.hpp"
#include "fmt/format.h"

#include <cassert>
#include <gsl/pointers>

#include <concepts>
#include <cstddef>
#include <functional>
Expand All @@ -35,21 +36,21 @@ namespace phlex::detail {
using driver_shim_t = void(driver_proxy const&, configuration const&, driver_bundle*);

template <typename SourceType>
std::remove_cvref_t<SourceType> const& as_driver_source(source const* src, std::size_t index)
std::remove_cvref_t<SourceType> const& as_driver_source(gsl::not_null<source const*> src,
std::size_t index)
{
assert(src != nullptr);

using expected_source_t = std::remove_cvref_t<SourceType>;

if (auto const* casted = dynamic_cast<expected_source_t const*>(src)) {
auto const* src_ptr = src.get();
if (auto const* casted = dynamic_cast<expected_source_t const*>(src_ptr)) {
return *casted;
}

throw std::runtime_error(
fmt::format("Driver source type mismatch at source index {}: expected '{}' but got '{}'.",
index,
boost::core::demangle(typeid(expected_source_t).name()),
boost::core::demangle(typeid(*src).name())));
boost::core::demangle(typeid(*src_ptr).name())));
}

template <typename SourceParameters, typename F, typename FirstArg>
Expand Down
1 change: 1 addition & 0 deletions phlex/model/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ cet_make_library(
Boost::boost
spdlog::spdlog
fmt::fmt
Microsoft.GSL::GSL
PRIVATE
phlex::utilities
TBB::tbb
Expand Down
6 changes: 4 additions & 2 deletions phlex/model/fixed_hierarchy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include "phlex/model/fwd.hpp"
#include "phlex/model/layer_path.hpp"

#include <gsl/pointers>

#include <cstddef>
#include <initializer_list>
#include <string>
Expand Down Expand Up @@ -37,8 +39,8 @@ namespace phlex {
data_cell_index_ptr index_;
// Non-owning pointers to the enclosing hierarchy and driver; data_cell_cursor is a
// short-lived, freely copyable view and does not manage their lifetimes.
fixed_hierarchy const* hierarchy_;
detail::framework_driver* driver_;
gsl::not_null<fixed_hierarchy const*> hierarchy_;
gsl::not_null<detail::framework_driver*> driver_;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
};

/// @brief Callable object that yields data cells to the framework driver.
Expand Down
10 changes: 7 additions & 3 deletions phlex/model/handle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include "phlex/model/fwd.hpp"
#include "phlex/model/product_specification.hpp"

#include <gsl/pointers>

#include <optional>
#include <type_traits>
#include <utility>
Expand Down Expand Up @@ -83,7 +85,7 @@ namespace phlex {
handle(handle&&) noexcept = default;
handle& operator=(handle&&) noexcept = default;

const_pointer operator->() const noexcept { return product_; }
const_pointer operator->() const noexcept { return product_.get(); }
[[nodiscard]] const_reference operator*() const noexcept { return *operator->(); }
// NOLINTBEGIN(google-explicit-constructor) - Implicit conversion is intentional
operator const_reference() const noexcept { return operator*(); }
Expand Down Expand Up @@ -116,8 +118,10 @@ namespace phlex {
}

private:
const_pointer product_; // Non-null, by construction
class data_cell_index const* id_; // Non-null, by construction
// Non-owning pointers to the product and its data-cell index; both are non-null by
// construction, as enforced by gsl::not_null.
gsl::not_null<const_pointer> product_;
gsl::not_null<class data_cell_index const*> id_;
experimental::identifier creator_plugin_;
experimental::identifier creator_algorithm_;
experimental::identifier suffix_;
Expand Down
2 changes: 1 addition & 1 deletion phlex/model/products.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace phlex::detail {
products::size_type products::size() const noexcept { return products_.size(); }
bool products::empty() const noexcept { return products_.empty(); }

product_base const* products::find_product(product_specification const& spec) const
gsl::not_null<product_base const*> products::find_product(product_specification const& spec) const
{
auto it =
std::ranges::find(products_, spec, [](auto const& p) -> auto const& { return p.first; });
Expand Down
16 changes: 12 additions & 4 deletions phlex/model/products.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@

#include "phlex/model/product_specification.hpp"

#include <gsl/pointers>

#include <cassert>
#include <concepts>
#include <memory>
#include <stdexcept>
#include <string>
#include <typeinfo>
#include <utility>
Expand Down Expand Up @@ -46,7 +49,10 @@ namespace phlex::detail {
product_ptr product_for(T&& t)
{
if constexpr (std::convertible_to<T, product_ptr>) {
return std::forward<T>(t);
if (auto product = product_ptr{std::forward<T>(t)}) {
return product;
}
throw std::runtime_error("Cannot store a null product pointer.");
} else {
return std::make_unique<product<std::remove_cvref_t<T>>>(std::forward<T>(t));
}
Expand Down Expand Up @@ -87,9 +93,9 @@ namespace phlex::detail {
template <typename T>
T const& get(product_specification const& spec) const
{
auto const* available_product = find_product(spec);
auto const available_product = find_product(spec);

if (auto const* desired_product = dynamic_cast<product<T> const*>(available_product)) {
if (auto const* desired_product = dynamic_cast<product<T> const*>(available_product.get())) {
return desired_product->obj;
}

Expand All @@ -102,7 +108,9 @@ namespace phlex::detail {
bool empty() const noexcept;

private:
product_base const* find_product(product_specification const& spec) const;
// Throws if no product matches the specification; the returned pointer is therefore
// never null.
gsl::not_null<product_base const*> find_product(product_specification const& spec) const;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
static void throw_mismatched_type [[noreturn]] (product_specification const& spec,
char const* requested_type,
char const* available_type);
Expand Down
3 changes: 3 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,9 @@ cet_test(product_handle USE_CATCH2_MAIN SOURCE product_handle_test.cpp LIBRARIES
cet_test(product_store USE_CATCH2_MAIN SOURCE product_store_test.cpp LIBRARIES
phlex::core_internal
)
cet_test(products USE_CATCH2_MAIN SOURCE products_test.cpp LIBRARIES
phlex::model_internal
)
cet_test(
fold
USE_CATCH2_MAIN
Expand Down
11 changes: 11 additions & 0 deletions test/products_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include "phlex/model/products.hpp"

#include "catch2/catch_test_macros.hpp"
#include "catch2/matchers/catch_matchers.hpp"

TEST_CASE("Reject null product pointers", "[data model]")
{
using namespace phlex::detail;
CHECK_THROWS_WITH(product_for(product_ptr{}), "Cannot store a null product pointer.");
CHECK_THROWS_WITH(product_for(nullptr), "Cannot store a null product pointer.");
}
Loading