simplify implementation of no data case to make it work with non MSVC compilers

surprisingly tests are broken
This commit is contained in:
Sébastien Loriot 2024-02-13 16:51:54 +01:00
parent 009791f4f8
commit ae18495c56
3 changed files with 35 additions and 173 deletions

View File

@ -72,26 +72,26 @@ BOOST_MPL_HAS_XXX_TRAIT_DEF(Node_data)
*/
template <typename GeomTraits>
class Orthtree {
private:
template<class A, class T>
template<class A, bool b>
struct Node_data_selector {};
template<class A>
struct Node_data_selector<A, boost::mpl::bool_<true>> {
struct Node_data_selector<A, true> {
using type = typename A::Node_data;
};
template<class A>
struct Node_data_selector<A, boost::mpl::bool_<false>> {
struct Node_data_selector<A, false> {
using type = void;
};
static inline constexpr bool has_data = internal::has_Node_data<GeomTraits>::value;
public:
/// \name Template Types
/// @{
using Traits = GeomTraits; ///< Geometry traits
/// @}
using Has_data = boost::mpl::bool_<internal::has_Node_data<GeomTraits>::value>;
/// \name Traits Types
/// @{
@ -104,7 +104,7 @@ public:
using Adjacency = typename Traits::Adjacency; ///< Adjacency type.
using Node_index = typename Traits::Node_index; ///< Index of a given node in the tree; the root always has index 0.
using Node_data = typename Node_data_selector<Traits, Has_data>::type;
using Node_data = typename Node_data_selector<Traits, has_data>::type;
/// @}
@ -178,7 +178,7 @@ private: // data members :
Traits m_traits; /* the tree traits */
Node_property_container m_node_properties;
Property_array<Node_data> m_node_contents;
std::conditional_t<has_data,Property_array<Node_data>, void*> m_node_contents;
Property_array<std::uint8_t> m_node_depths;
Property_array<Global_coordinates> m_node_coordinates;
Property_array<std::optional<Node_index>> m_node_parents;
@ -190,17 +190,13 @@ private: // data members :
Cartesian_ranges cartesian_range; /* a helper to easily iterate over coordinates of points */
template<class T>
void init_data();
template<>
void init_data<boost::mpl::bool_<true>>() {
data(root()) = m_traits.construct_root_node_contents_object()();
template<typename Dummy = Property_array<Node_data>>
auto init_node_contents(std::true_type) -> std::enable_if_t<has_data, Dummy>
{
return Property_array<Node_data>(m_node_properties.template get_or_add_property<Node_data>("contents").first);
}
template<>
void init_data<boost::mpl::bool_<false>>() {
}
void* init_node_contents(std::false_type) { return nullptr; }
public:
@ -223,7 +219,7 @@ public:
*/
explicit Orthtree(Traits traits) :
m_traits(traits),
m_node_contents(m_node_properties.template get_or_add_property<Node_data>("contents").first),
m_node_contents(init_node_contents(std::bool_constant<has_data>())),
m_node_depths(m_node_properties.template get_or_add_property<std::uint8_t>("depths", 0).first),
m_node_coordinates(m_node_properties.template get_or_add_property<Global_coordinates>("coordinates").first),
m_node_parents(m_node_properties.template get_or_add_property<std::optional<Node_index>>("parents").first),
@ -244,7 +240,8 @@ public:
// save orthtree attributes
m_side_per_depth.push_back(size);
init_data<Has_data>();
if constexpr (has_data)
m_traits.construct_root_node_contents_object()();
}
/// @}
@ -253,7 +250,7 @@ public:
Orthtree(const Orthtree& other) :
m_traits(other.m_traits),
m_node_properties(other.m_node_properties),
m_node_contents(m_node_properties.template get_property<Node_data>("contents")),
m_node_contents(init_node_contents(std::bool_constant<has_data>())),
m_node_depths(m_node_properties.template get_property<std::uint8_t>("depths")),
m_node_coordinates(m_node_properties.template get_property<Global_coordinates>("coordinates")),
m_node_parents(m_node_properties.template get_property<std::optional<Node_index>>("parents")),
@ -264,7 +261,7 @@ public:
Orthtree(Orthtree&& other) :
m_traits(other.m_traits),
m_node_properties(std::move(other.m_node_properties)),
m_node_contents(m_node_properties.template get_property<Node_data>("contents")),
m_node_contents(init_node_contents(std::bool_constant<has_data>())),
m_node_depths(m_node_properties.template get_property<std::uint8_t>("depths")),
m_node_coordinates(m_node_properties.template get_property<Global_coordinates>("coordinates")),
m_node_parents(m_node_properties.template get_property<std::optional<Node_index>>("parents")),
@ -729,7 +726,7 @@ public:
\brief retrieves a reference to the Node_data associated with the node specified by `n`.
*/
template<typename Dummy = Node_data>
auto data(Node_index n) -> std::enable_if_t<internal::has_Node_data<GeomTraits>::value, Dummy&>{
auto data(Node_index n) -> std::enable_if_t<has_data, Dummy&>{
return m_node_contents[n];
}
@ -737,7 +734,7 @@ public:
\brief retrieves a const reference to the Node_data associated with the node specified by `n`.
*/
template<typename Dummy = Node_data>
auto data(Node_index n) const -> std::enable_if_t<internal::has_Node_data<GeomTraits>::value, const Dummy&> {
auto data(Node_index n) const -> std::enable_if_t<has_data, const Dummy&> {
return m_node_contents[n];
}
@ -965,7 +962,8 @@ public:
Point center = barycenter(n);
// Add the node's contents to its children
distribute_node_contents<Has_data>(n, center);
if constexpr (has_data)
m_traits.distribute_node_contents_object()(n, *this, center);
}
/*!
@ -1173,17 +1171,6 @@ private: // functions :
return output;
}
template<class T>
void distribute_node_contents(Node_index n, const Point& center);
template<>
void distribute_node_contents<boost::mpl::bool_<true>>(Node_index n, const Point& center) {
m_traits.distribute_node_contents_object()(n, *this, center);
}
template<>
void distribute_node_contents<boost::mpl::bool_<false>>(Node_index n, const Point& center) {}
public:
/// \cond SKIP_IN_MANUAL

View File

@ -48,7 +48,8 @@ int test(Tree &tree)
return EXIT_SUCCESS;
}
void main() {
int main()
{
std::size_t nb_pts = 100;
Point_set points;
CGAL::Random_points_in_cube_3<Point> generator;

View File

@ -191,43 +191,6 @@ public:
};
template <typename Index>
class Property_array<Index, void> : public Property_array_base<Index> {
public:
Property_array() {}
virtual std::shared_ptr<Property_array_base<Index>> empty_clone(const std::vector<bool>& active_indices) {
return std::make_shared<Property_array<Index, void>>();
}
virtual std::shared_ptr<Property_array_base<Index>> clone(const std::vector<bool>& active_indices) {
return std::make_shared<Property_array<Index, void>>();
}
virtual void copy(const Property_array_base<Index>& other) {}
// desactived as MSVC 2017 as an issue with that but it is not currently used.
#if 0
virtual void move(Property_array_base<Index>&& other) = 0;
#endif
virtual void append(const Property_array_base<Index>& other) {}
virtual void reserve(std::size_t n) {}
virtual void shrink_to_fit() {}
virtual void swap(Index a, Index b) {}
virtual void reset(Index i) {}
virtual const std::type_info& type() const {
return typeid(void);
}
virtual void transfer_from(const Property_array_base<Index>& other_base, Index other_index, Index this_index) {}
};
// todo: property maps/array handles should go in their own file
// todo: add const/read-only handle
@ -280,56 +243,6 @@ public:
};
// void specialization
template <typename Index>
class Property_array_handle<Index, void> {
std::reference_wrapper<Property_array<Index, void>> m_array;
std::vector<int> m_dummy;
public:
// Necessary for use as a boost::property_type
using key_type = Index;
using value_type = void;
using reference = void;
using const_reference = void;
using category = boost::lvalue_property_map_tag;
using iterator = typename std::vector<int>::iterator;
using const_iterator = typename std::vector<int>::const_iterator;
Property_array_handle(Property_array<Index, void>& array) : m_array(array) {}
[[nodiscard]] std::size_t size() const { return 0; }
[[nodiscard]] std::size_t capacity() const { return 0; }
Property_array<Index, void>& array() const { return m_array.get(); }
// todo: This might not be needed, if the other operator[] is made const
const_reference operator[](Index i) const { }
reference operator[](Index i) { }
// todo: maybe these can be const, in an lvalue property map?
iterator begin() { return m_dummy.begin(); }
iterator end() { return m_dummy.end(); }
const_iterator begin() const { return m_dummy.begin(); }
const_iterator end() const { return m_dummy.end(); }
bool operator==(const Property_array_handle<Index, void>& other) const { return true; }
bool operator!=(const Property_array_handle<Index, void>& other) const { return false; }
inline friend reference get(Property_array_handle<Index, void> p, const Index& i) {}
//inline friend void put(Property_array_handle<Index, void> p, const Index& i, const T& v) {}
};
template <typename Index = std::size_t>
class Property_container {
@ -405,46 +318,7 @@ public:
template <typename T>
std::pair<std::reference_wrapper<Property_array<Index, T>>, bool>
get_or_add_property(const std::string& name) {
auto range = m_properties.equal_range(name);
for (auto it = range.first; it != range.second; it++) {
Property_array<Index, T>* typed_array_ptr = dynamic_cast<Property_array<Index, T>*>(it->second.get());
if (typed_array_ptr != nullptr)
return { {*typed_array_ptr}, false };
}
auto it = m_properties.emplace(
name,
std::make_shared<Property_array<Index, T>>(
m_active_indices,
T()
)
);
return { {*dynamic_cast<Property_array<Index, T>*>(it->second.get())}, true };
}
template<>
std::pair<std::reference_wrapper<Property_array<Index, void>>, bool>
get_or_add_property(const std::string& name) {
auto range = m_properties.equal_range(name);
for (auto it = range.first; it != range.second; it++) {
Property_array<Index, void>* typed_array_ptr = dynamic_cast<Property_array<Index, void>*>(it->second.get());
if (typed_array_ptr != nullptr)
return { {*typed_array_ptr}, false };
}
auto it = m_properties.emplace(
name,
std::make_shared<Property_array<Index, void>>()
);
return { {*dynamic_cast<Property_array<Index, void>*>(it->second.get())}, true };
}
template <typename T>
std::pair<std::reference_wrapper<Property_array<Index, T>>, bool>
get_or_add_property(const std::string& name, const T default_value) {
get_or_add_property(const std::string& name, const T default_value = T()) {
auto range = m_properties.equal_range(name);
for (auto it = range.first; it != range.second; it++) {
Property_array<Index, T>* typed_array_ptr = dynamic_cast<Property_array<Index, T>*>(it->second.get());