Пример #1
0
    inline allocators()
        : node_allocator_type()
    {}

    template <typename Alloc>
    inline explicit allocators(Alloc const& alloc)
        : node_allocator_type(alloc)
    {}

    inline allocators(BOOST_FWD_REF(allocators) a)
        : node_allocator_type(boost::move(a.node_allocator()))
    {}

    inline allocators & operator=(BOOST_FWD_REF(allocators) a)
    {
        node_allocator() = boost::move(a.node_allocator());
        return *this;
    }

#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
    inline allocators & operator=(allocators const& a)
    {
        node_allocator() = a.node_allocator();
        return *this;
    }
#endif

    void swap(allocators & a)
    {
        boost::swap(node_allocator(), a.node_allocator());
    }
Пример #2
0
    inline allocators()
        : node_allocator_type()
    {}

    template <typename Alloc>
    inline explicit allocators(Alloc const& alloc)
        : node_allocator_type(alloc)
    {}

    inline allocators(BOOST_FWD_REF(allocators) a)
        : node_allocator_type(pdalboost::move(a.node_allocator()))
    {}

    inline allocators & operator=(BOOST_FWD_REF(allocators) a)
    {
        node_allocator() = pdalboost::move(a.node_allocator());
        return *this;
    }

#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
    inline allocators & operator=(allocators const& a)
    {
        node_allocator() = a.node_allocator();
        return *this;
    }
#endif

    void swap(allocators & a)
    {
        pdalboost::swap(node_allocator(), a.node_allocator());
    }
Пример #3
0
pow2_radix_patricia_trie_node<Dims, Coord, T, Traits>&
pow2_radix_patricia_trie_node<Dims, Coord, T, Traits>::insert(loc_type leaf_loc) {
  // invariant: this 'node' variable changes but is never nullptr.
  node_type* node_to_initialize;
  node_type*const node = &this->find_node(leaf_loc);
  if(node->size_exponent_in_each_dimension() == 0
      && node->min() == leaf_loc) {
    return *node;
  }
  if (node->is_empty()) {
    node_to_initialize = node;
    //LOG << "Type 1 " << std::hex << size_t(node_to_initialize) << std::dec << "\n";
  }
  else {
    // That child's location was too specific (wrong) for us.
    sub_nodes_type* intermediate_nodes = node_allocator().allocate(1);
    if (!intermediate_nodes) {
      throw std::bad_alloc();
    }
    try {
      // nothrow except monoids
      new (intermediate_nodes) sub_nodes_type();
      for (node_type& intermediate_node : *intermediate_nodes) {
        intermediate_node.set_parent(node);
        assert(intermediate_node.size_exponent_in_each_dimension() == 0);
      }
    }
    catch(...) {
      node_allocator().deallocate(intermediate_nodes, 1);
      throw;
    }

    num_bits_type shared_size_exponent;
    node_type* new_location_for_node_original_contents;
    node_type* new_leaf_ptr_node;
    try {
      // loop is nothrow
      shared_size_exponent = 0;
      for (num_coordinates_type dim = 0; dim != dimensions; ++dim) {
        const num_bits_type dim_shared_size_exponent =
                num_bits_in_integer_that_are_not_leading_zeroes(
                  to_unsigned_type(node->min()[dim] ^ leaf_loc[dim]));
        if(shared_size_exponent < dim_shared_size_exponent) {
          shared_size_exponent = dim_shared_size_exponent;
        }
      }

      // assert is typically nothrow, and it's also okay
      // if it throws here.
      assert(shared_size_exponent > 0);
      //LOG << "~~" << shared_size_exponent << std::endl;

      // move node's contents to its new location
      new_location_for_node_original_contents =    // nothrow
          &child_matching(*intermediate_nodes, shared_size_exponent, node->min());
      new_leaf_ptr_node =    // nothrow
          &child_matching(*intermediate_nodes, shared_size_exponent, leaf_loc);

      assert(new_location_for_node_original_contents != new_leaf_ptr_node);

      // Monoid ops may throw. Do the copy before anything else so that if
      // it throws, we won't be in a partial state and have destructors
      // mess things up.
      new_location_for_node_original_contents->set_monoid(node->monoid());
      new_location_for_node_original_contents->set_min(node->min());
      new_location_for_node_original_contents->set_size_exponent_in_each_dimension(node->size_exponent_in_each_dimension());
      new_location_for_node_original_contents->set_stable_node_reference_keeper(node->stable_node_reference_keeper());

      // Compute shared coords here in case some Coord ops can throw.
      loc_type shared_loc_min;
      const Coord mask = safer_n_low_zero_bits<Coord>(shared_size_exponent);
      for (num_coordinates_type dim = 0; dim != dimensions; ++dim) {
        shared_loc_min[dim] = node->min()[dim] & mask;
      }
      // If Coord move throws, we're in trouble, because we're moving
      // an array of them so some of node's coords could be overwritten
      // already and we have no reliable way to restore them without
      // nothrow move.  This is why we require nothrow Coord move.
      //
      // Nevertheless do this inside the try/catch so we at least
      // don't leak memory if it throws.
      node->set_min(::move(shared_loc_min));
    }
    catch(...) {
      intermediate_nodes->~sub_nodes_type();
      node_allocator().deallocate(intermediate_nodes, 1);
      throw;
    }

    // continue moving node's contents to its new location
    // nothrow
    new_location_for_node_original_contents->set_sub_nodes(node->sub_nodes());
    new_location_for_node_original_contents->set_leaf(node->move_leaf());
    if(sub_nodes_type* original_sub_nodes = new_location_for_node_original_contents->sub_nodes()) {
      for (node_type& sub_node : *original_sub_nodes) {
        sub_node.set_parent(new_location_for_node_original_contents);
      }
    }
    node->set_size_exponent_in_each_dimension(shared_size_exponent);
    node->set_leaf();
    node->set_sub_nodes(intermediate_nodes);
    node->set_stable_node_reference_keeper();
    //node->parent remains the same
    //node->monoid remains the same (it will be updated later as one of the parents)

    // nothrow
    node_to_initialize = new_leaf_ptr_node;
    //LOG << "Type 2 " << std::hex << size_t(node_to_initialize) << std::dec << "\n";
  }

  assert(!node_to_initialize->sub_nodes());
  node_to_initialize->set_min(::move(leaf_loc));
  return *node_to_initialize;
}