Rtree value_type must no longer have default ctor defined.

Added static_vector::assign(), added assertion in static_vector::resize().
Added test for value without default ctor..

[SVN r81940]
This commit is contained in:
Adam Wulkiewicz
2012-12-14 14:49:45 +00:00
parent 1ae333d9a6
commit d7cf32bcfa
6 changed files with 168 additions and 56 deletions

View File

@@ -60,19 +60,22 @@ public:
geometry::centroid(rtree::elements(*parent)[current_child_index].first, node_center);
// fill the container of centers' distances of children from current node's center
typename index::detail::rtree::container_from_elements_type<
typedef typename index::detail::rtree::container_from_elements_type<
elements_type,
std::pair<distance_type, element_type>
>::type sorted_elements;
>::type sorted_elements_type;
sorted_elements_type sorted_elements;
// If constructor is used instead of resize() MS implementation leaks here
sorted_elements.resize(elements_count); // MAY THROW, STRONG (V, E: alloc, copy)
sorted_elements.reserve(elements_count); // MAY THROW, STRONG (V, E: alloc, copy)
for ( size_t i = 0 ; i < elements_count ; ++i )
for ( typename elements_type::const_iterator it = elements.begin() ;
it != elements.end() ; ++it )
{
point_type element_center;
geometry::centroid( rtree::element_indexable(elements[i], translator), element_center);
sorted_elements[i].first = geometry::comparable_distance(node_center, element_center);
sorted_elements[i].second = elements[i]; // MAY THROW (V, E: copy)
geometry::centroid( rtree::element_indexable(*it, translator), element_center);
sorted_elements.push_back(std::make_pair(
geometry::comparable_distance(node_center, element_center),
*it)); // MAY THROW (V, E: copy)
}
// sort elements by distances from center
@@ -83,24 +86,34 @@ public:
distances_dsc<distance_type, element_type>); // MAY THROW, BASIC (V, E: copy)
// copy elements which will be reinserted
result_elements.resize(reinserted_elements_count); // MAY THROW, STRONG (V, E: alloc, copy)
for ( size_t i = 0 ; i < reinserted_elements_count ; ++i )
result_elements[i] = sorted_elements[i].second; // MAY THROW (V, E: copy)
result_elements.clear();
result_elements.reserve(reinserted_elements_count); // MAY THROW, STRONG (V, E: alloc, copy)
for ( typename sorted_elements_type::const_iterator it = sorted_elements.begin() ;
it != sorted_elements.begin() + reinserted_elements_count ; ++it )
{
result_elements.push_back(it->second); // MAY THROW (V, E: copy)
}
try
{
// copy remaining elements to the current node
size_t elements_new_count = elements_count - reinserted_elements_count;
elements.resize(elements_new_count); // SHOULDN'T THROW (new_size <= old size)
for ( size_t i = 0 ; i < elements_new_count ; ++i )
elements[i] = sorted_elements[i + reinserted_elements_count].second; // MAY THROW (V, E: copy)
elements.clear();
elements.reserve(elements_count - reinserted_elements_count); // SHOULDN'T THROW (new_size <= old size)
for ( typename sorted_elements_type::const_iterator it = sorted_elements.begin() + reinserted_elements_count;
it != sorted_elements.end() ; ++it )
{
elements.push_back(it->second); // MAY THROW (V, E: copy)
}
}
catch(...)
{
elements.clear();
for ( size_t i = 0 ; i < elements_count ; ++i )
destroy_element<Value, Options, Translator, Box, Allocators>::apply(sorted_elements[i].second, allocators);
for ( typename sorted_elements_type::iterator it = sorted_elements.begin() ;
it != sorted_elements.end() ; ++it )
{
destroy_element<Value, Options, Translator, Box, Allocators>::apply(it->second, allocators);
}
throw; // RETHROW
}

View File

@@ -382,10 +382,8 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, rstar_
try
{
// copy elements to nodes
elements1.resize(split_index); // SHOULDN'T THROW
std::copy(elements_copy.begin(), elements_copy.begin() + split_index, elements1.begin()); // MAY THROW, BASIC
elements2.resize(parameters.get_max_elements() + 1 - split_index); // MAY THROW, STRONG
std::copy(elements_copy.begin() + split_index, elements_copy.end(), elements2.begin()); // MAY THROW, BASIC
elements1.assign(elements_copy.begin(), elements_copy.begin() + split_index); // MAY THROW, BASIC
elements2.assign(elements_copy.begin() + split_index, elements_copy.end()); // MAY THROW, BASIC
// calculate boxes
box1 = rtree::elements_box<Box>(elements1.begin(), elements1.end(), translator);

View File

@@ -873,7 +873,7 @@ private:
point_type
> result_type;
result_type result;
result_type result(v);
detail::rtree::visitors::nearest_query<
value_type,
@@ -888,7 +888,8 @@ private:
detail::rtree::apply_visitor(nearest_v, *m_root);
return result.get(v);
//return result.get(v);
return result.is_comparable_distance_valid() ? 1 : 0;
}
/*!

View File

@@ -33,8 +33,9 @@ public:
typename translator::indexable_type<Translator>::type
>::type distance_type;
inline nearest_query_result_one()
: m_comp_dist((std::numeric_limits<distance_type>::max)())
inline nearest_query_result_one(Value & value)
: m_value(value)
, m_comp_dist((std::numeric_limits<distance_type>::max)())
{}
inline void store(Value const& val, distance_type const& curr_comp_dist)
@@ -63,7 +64,7 @@ public:
}
private:
Value m_value;
Value & m_value;
distance_type m_comp_dist;
};

View File

@@ -73,24 +73,7 @@ public:
{
//BOOST_ASSERT_MSG(other.m_size <= Capacity, "capacity too small");
if ( m_size <= other.m_size )
{
this->copy(other.ptr(0), other.ptr(m_size), this->ptr(0),
boost::has_trivial_assign<value_type>()); // may throw
this->uninitialized_copy(other.ptr(m_size), other.ptr(other.m_size), this->ptr(m_size),
boost::has_trivial_copy<value_type>()); // may throw
m_size = other.m_size;
}
else
{
this->copy(other.ptr(0), other.ptr(other.m_size), this->ptr(0),
boost::has_trivial_assign<value_type>()); // may throw
this->destroy(this->ptr(other.m_size), this->ptr(m_size),
boost::has_trivial_destructor<value_type>());
m_size = other.m_size;
}
this->assign(other->ptr(0), other->ptr(other.m_size));
return *this;
}
@@ -113,6 +96,7 @@ public:
}
else
{
BOOST_ASSERT_MSG(s <= Capacity, "size can't exceed the capacity");
this->uninitialized_fill(this->ptr(m_size), this->ptr(s), value); // may throw
m_size = s;
}
@@ -143,6 +127,31 @@ public:
this->destroy(this->ptr(m_size), boost::has_trivial_destructor<value_type>());
}
// basic
void assign(const value_type * first, const value_type * last)
{
size_type s = std::distance(first, last);
if ( m_size <= s )
{
this->copy(first, first + m_size, this->ptr(0),
boost::has_trivial_assign<value_type>()); // may throw
this->uninitialized_copy(first + m_size, last, this->ptr(m_size),
boost::has_trivial_copy<value_type>()); // may throw
m_size = s;
}
else
{
this->copy(first, last, this->ptr(0),
boost::has_trivial_assign<value_type>()); // may throw
this->destroy(this->ptr(s), this->ptr(m_size),
boost::has_trivial_destructor<value_type>());
m_size = s;
}
}
// nothrow
void clear()
{