mirror of https://github.com/CGAL/cgal
simplify implementation of no data case to make it work with non MSVC compilers
surprisingly tests are broken
This commit is contained in:
parent
009791f4f8
commit
ae18495c56
|
|
@ -72,26 +72,26 @@ BOOST_MPL_HAS_XXX_TRAIT_DEF(Node_data)
|
||||||
*/
|
*/
|
||||||
template <typename GeomTraits>
|
template <typename GeomTraits>
|
||||||
class Orthtree {
|
class Orthtree {
|
||||||
private:
|
template<class A, bool b>
|
||||||
template<class A, class T>
|
|
||||||
struct Node_data_selector {};
|
struct Node_data_selector {};
|
||||||
|
|
||||||
template<class A>
|
template<class A>
|
||||||
struct Node_data_selector<A, boost::mpl::bool_<true>> {
|
struct Node_data_selector<A, true> {
|
||||||
using type = typename A::Node_data;
|
using type = typename A::Node_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class A>
|
template<class A>
|
||||||
struct Node_data_selector<A, boost::mpl::bool_<false>> {
|
struct Node_data_selector<A, false> {
|
||||||
using type = void;
|
using type = void;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline constexpr bool has_data = internal::has_Node_data<GeomTraits>::value;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// \name Template Types
|
/// \name Template Types
|
||||||
/// @{
|
/// @{
|
||||||
using Traits = GeomTraits; ///< Geometry traits
|
using Traits = GeomTraits; ///< Geometry traits
|
||||||
/// @}
|
/// @}
|
||||||
using Has_data = boost::mpl::bool_<internal::has_Node_data<GeomTraits>::value>;
|
|
||||||
|
|
||||||
/// \name Traits Types
|
/// \name Traits Types
|
||||||
/// @{
|
/// @{
|
||||||
|
|
@ -104,7 +104,7 @@ public:
|
||||||
using Adjacency = typename Traits::Adjacency; ///< Adjacency type.
|
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_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 */
|
Traits m_traits; /* the tree traits */
|
||||||
|
|
||||||
Node_property_container m_node_properties;
|
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<std::uint8_t> m_node_depths;
|
||||||
Property_array<Global_coordinates> m_node_coordinates;
|
Property_array<Global_coordinates> m_node_coordinates;
|
||||||
Property_array<std::optional<Node_index>> m_node_parents;
|
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 */
|
Cartesian_ranges cartesian_range; /* a helper to easily iterate over coordinates of points */
|
||||||
|
|
||||||
template<class T>
|
template<typename Dummy = Property_array<Node_data>>
|
||||||
void init_data();
|
auto init_node_contents(std::true_type) -> std::enable_if_t<has_data, Dummy>
|
||||||
|
{
|
||||||
template<>
|
return Property_array<Node_data>(m_node_properties.template get_or_add_property<Node_data>("contents").first);
|
||||||
void init_data<boost::mpl::bool_<true>>() {
|
|
||||||
data(root()) = m_traits.construct_root_node_contents_object()();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
void* init_node_contents(std::false_type) { return nullptr; }
|
||||||
void init_data<boost::mpl::bool_<false>>() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
@ -223,7 +219,7 @@ public:
|
||||||
*/
|
*/
|
||||||
explicit Orthtree(Traits traits) :
|
explicit Orthtree(Traits traits) :
|
||||||
m_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_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_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),
|
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
|
// save orthtree attributes
|
||||||
m_side_per_depth.push_back(size);
|
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) :
|
Orthtree(const Orthtree& other) :
|
||||||
m_traits(other.m_traits),
|
m_traits(other.m_traits),
|
||||||
m_node_properties(other.m_node_properties),
|
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_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_coordinates(m_node_properties.template get_property<Global_coordinates>("coordinates")),
|
||||||
m_node_parents(m_node_properties.template get_property<std::optional<Node_index>>("parents")),
|
m_node_parents(m_node_properties.template get_property<std::optional<Node_index>>("parents")),
|
||||||
|
|
@ -264,7 +261,7 @@ public:
|
||||||
Orthtree(Orthtree&& other) :
|
Orthtree(Orthtree&& other) :
|
||||||
m_traits(other.m_traits),
|
m_traits(other.m_traits),
|
||||||
m_node_properties(std::move(other.m_node_properties)),
|
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_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_coordinates(m_node_properties.template get_property<Global_coordinates>("coordinates")),
|
||||||
m_node_parents(m_node_properties.template get_property<std::optional<Node_index>>("parents")),
|
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`.
|
\brief retrieves a reference to the Node_data associated with the node specified by `n`.
|
||||||
*/
|
*/
|
||||||
template<typename Dummy = Node_data>
|
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];
|
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`.
|
\brief retrieves a const reference to the Node_data associated with the node specified by `n`.
|
||||||
*/
|
*/
|
||||||
template<typename Dummy = Node_data>
|
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];
|
return m_node_contents[n];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -965,7 +962,8 @@ public:
|
||||||
Point center = barycenter(n);
|
Point center = barycenter(n);
|
||||||
|
|
||||||
// Add the node's contents to its children
|
// 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;
|
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:
|
public:
|
||||||
|
|
||||||
/// \cond SKIP_IN_MANUAL
|
/// \cond SKIP_IN_MANUAL
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,8 @@ int test(Tree &tree)
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
int main()
|
||||||
|
{
|
||||||
std::size_t nb_pts = 100;
|
std::size_t nb_pts = 100;
|
||||||
Point_set points;
|
Point_set points;
|
||||||
CGAL::Random_points_in_cube_3<Point> generator;
|
CGAL::Random_points_in_cube_3<Point> generator;
|
||||||
|
|
|
||||||
|
|
@ -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: property maps/array handles should go in their own file
|
||||||
|
|
||||||
// todo: add const/read-only handle
|
// 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>
|
template <typename Index = std::size_t>
|
||||||
class Property_container {
|
class Property_container {
|
||||||
|
|
||||||
|
|
@ -405,46 +318,7 @@ public:
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::pair<std::reference_wrapper<Property_array<Index, T>>, bool>
|
std::pair<std::reference_wrapper<Property_array<Index, T>>, bool>
|
||||||
get_or_add_property(const std::string& name) {
|
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());
|
|
||||||
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) {
|
|
||||||
auto range = m_properties.equal_range(name);
|
auto range = m_properties.equal_range(name);
|
||||||
for (auto it = range.first; it != range.second; it++) {
|
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());
|
Property_array<Index, T>* typed_array_ptr = dynamic_cast<Property_array<Index, T>*>(it->second.get());
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue