void uninit_merge_level4(range<Value_t *> dest,
                         std::vector<range<Iter_t> > &v_input,
                         std::vector<range<Value_t *> > &v_output, Compare comp)
{
    typedef range<Value_t *> range1_t;
    typedef util::value_iter<Iter_t> type1;
    static_assert (std::is_same< type1, Value_t >::value,
                    "Incompatible iterators\n");

    v_output.clear();
    if (v_input.size() == 0) return;
    if (v_input.size() == 1)
    {
        v_output.emplace_back(move_construct(dest, v_input[0]));
        return;
    };

    uint32_t nrange = v_input.size();
    uint32_t pos_ini = 0;
    while (pos_ini < v_input.size())
    {
        uint32_t nmerge = (nrange + 3) >> 2;
        uint32_t nelem = (nrange + nmerge - 1) / nmerge;
        range1_t rz = uninit_full_merge4(dest, &v_input[pos_ini], nelem, comp);
        v_output.emplace_back(rz);
        dest.first = rz.last;
        pos_ini += nelem;
        nrange -= nelem;
    };
    return;
};
Exemple #2
0
 static inline D cast(U &&o) {
   D d;
   if (!o) return d;
   auto t = get_dtable(o);
   d.table_ = t;
   if (std::is_reference<U>::value) {
     auto c = get_table<concept_copy_construct::Table>(
         t->type_info, t, o.table());
     if (d.stored_in_heap()) {
       d.heap_data() = ::operator new(o.table()->size);
     }
     c->copy_construct(d.data(), o.data());
   } else {
     if (d.stored_in_heap()) {
       if (o.stored_in_heap()) {
         d.heap_data() = o.heap_data();
         ((S *)&o)->table_ = nullptr;
       } else {
         d.heap_data() = ::operator new(o.table()->size);
       }
     }
     if (o) {
       t->move_construct(d.data(), (void *)o.data());
     }
   }
   return d;
 }
Exemple #3
0
range<Value_t *> uninit_full_merge4(const range<Value_t *> &dest,
                                    range<Iter_t> vrange_input[4],
                                    uint32_t nrange_input, Compare comp)
{
    typedef util::value_iter<Iter_t> type1;
    static_assert (std::is_same< type1, Value_t >::value,
                    "Incompatible iterators\n");

    size_t ndest = 0;
    uint32_t i = 0;
    while (i < nrange_input)
    {
        if (vrange_input[i].size() != 0)
        {
            ndest += vrange_input[i++].size();
        }
        else
        {
            for (uint32_t k = i + 1; k < nrange_input; ++k)
            {
                vrange_input[k - 1] = vrange_input[k];
            };
            --nrange_input;
        };
    };
    if (nrange_input == 0) return range<Value_t *>(dest.first, dest.first);
    if (nrange_input == 1) return move_construct(dest, vrange_input[0]);
    if (nrange_input == 2)
    {
        return merge_construct(dest, vrange_input[0], vrange_input[1], comp);
    };

    //------------------------------------------------------------------------
    // Initial sort
    //------------------------------------------------------------------------
    uint32_t pos[4] = { 0, 1, 2, 3 }, npos = nrange_input;

    //-----------------------------------------------------------------------
    // thanks to Steven Ross by their suggestion about the optimal
    // sorting networks
    //-----------------------------------------------------------------------
    if (less_range(vrange_input[pos[1]].first, pos[1],
                    vrange_input[pos[0]].first, pos[0], comp))
    {
        std::swap(pos[0], pos[1]);
    };
    if (npos == 4  and less_range(vrange_input[pos[3]].first, pos[3],
                                  vrange_input[pos[2]].first, pos[2], comp))
    {
        std::swap(pos[3], pos[2]);
    };
    if (less_range(vrange_input[pos[2]].first, pos[2],
                    vrange_input[pos[0]].first, pos[0], comp))
    {
        std::swap(pos[0], pos[2]);
    };
    if (npos == 4 and less_range(vrange_input[pos[3]].first, pos[3],
                                 vrange_input[pos[1]].first, pos[1], comp))
    {
        std::swap(pos[1], pos[3]);
    };
    if (less_range(vrange_input[pos[2]].first, pos[2],
                    vrange_input[pos[1]].first, pos[1], comp))
    {
        std::swap(pos[1], pos[2]);
    };

    Value_t *it_dest = dest.first;
    while (npos > 2)
    {
        util::construct_object(&(*(it_dest++)),
                        std::move(*(vrange_input[pos[0]].first++)));
        if (vrange_input[pos[0]].size() == 0)
        {
            pos[0] = pos[1];
            pos[1] = pos[2];
            pos[2] = pos[3];
            --npos;
        }
        else
        {
            if (less_range (vrange_input[pos[1]].first, pos[1],
                            vrange_input[pos[0]].first, pos[0], comp))
            {
                std::swap(pos[0], pos[1]);
                if (less_range (vrange_input[pos[2]].first, pos[2],
                                vrange_input[pos[1]].first, pos[1], comp))
                {
                    std::swap(pos[1], pos[2]);
                    if (npos == 4 and less_range(vrange_input[pos[3]].first,
                                                 pos[3],
                                                 vrange_input[pos[2]].first,
                                                 pos[2], comp))
                    {
                        std::swap(pos[2], pos[3]);
                    };
                };
            };
        };
    }; // end while (npos > 2)

    range<Value_t *> raux1(dest.first, it_dest), raux2(it_dest, dest.last);
    if (pos[0] < pos[1])
    {
        return concat(raux1,
                      merge_construct(raux2, vrange_input[pos[0]],
                                      vrange_input[pos[1]], comp));
    }
    else
    {
        return concat(raux1,
                      merge_construct(raux2, vrange_input[pos[1]],
                                      vrange_input[pos[0]], comp));
    };
};