Информация об изменениях

Сообщение подскажите как пофиксить код от 21.09.2014 12:51

Изменено 21.09.2014 13:05 niXman

снова драсте.

в продолжение темы
Автор: niXman
Дата: 21.09.14
, решил использовать найденный костыль. но загвоздка в том, что он не умеет инициализировать non-copyable и non-movable типы.
компилябельный пример:

#include <iostream>
#include <memory>
#include <utility>
#include <tuple>
#include <functional>

#include <boost/noncopyable.hpp>

/***************************************************************************/

namespace detail {
template<int ... N>
struct index {
    typedef index<N..., sizeof...(N)> next;
};
template<int N>
struct build_index {
    typedef typename build_index<N - 1>::type::next type;
};

template<>
struct build_index<0> {
    typedef index<> type;
};

template<typename T>
struct tuple_index {
    typedef typename build_index<
            std::tuple_size<typename std::remove_reference<T>::type>::value>::type type;

};
} // ns detail

template<typename ... Elements>
class piecewise_tuple: public std::tuple<Elements...> {
    typedef std::tuple<Elements...> base_type;

    template<int Index, typename ... Args, int ... N>
    static typename std::tuple_element<Index, base_type>::type
    construct(std::tuple<Args...>&& args, detail::index<N...>)
    {
        typedef typename std::tuple_element<Index, base_type>::type result_type;
        return result_type(std::get<N>(std::move(args))...);
    }

    template<int ...N, typename ArgTuple>
    piecewise_tuple(detail::index<N...>, ArgTuple&& element_args)
    : base_type( construct<N>( std::get<N>(std::forward<ArgTuple>(element_args)),
                 typename detail::tuple_index< typename std::tuple_element<N, typename std::remove_reference<ArgTuple>::type >::type >::type() )...)
    {

    }

public:

    piecewise_tuple() = default;

    // For non-piecewise constructors, forward them
    template<typename... Args>
    piecewise_tuple(Args&&... args) : base_type(std::forward<Args>(args)...) {}


    template<typename... T>
    piecewise_tuple(std::piecewise_construct_t, T&&... args) :
    piecewise_tuple(typename detail::tuple_index<base_type>::type(),
                    std::forward_as_tuple(std::forward<T>(args)...))
    {

    }
};

/***************************************************************************/

struct noncopyable: boost::noncopyable {};

struct type: boost::noncopyable {
    type(int &i, const char *s, noncopyable &n)
        :i(i)
        ,s(s)
        ,n(n)
    {}

    int &i;
    const char *s;
    noncopyable &n;
};

/***************************************************************************/

int main() {
    int i = 5;
    const char *s = "string";
    noncopyable n;

    std::unique_ptr<int> up(new int(0));

    piecewise_tuple<std::pair<int, int>, double, std::unique_ptr<int>, int&/*, type*/> p(
         std::piecewise_construct
        ,std::forward_as_tuple(1,2)
        ,std::forward_as_tuple(4.3)
        ,std::forward_as_tuple(std::move(up))
        ,std::forward_as_tuple(i)
        //,std::forward_as_tuple(i, s, n)
    );
}

/***************************************************************************/

тут, если расскоментить два фрагмента в main() — код перестанет компилиться. ошибка в том, что:
error: use of deleted function 'type::type(const type&)'

copy и move конструкторы для type на самом деле не нужны.

к тому же, std::pair(std::piecewise_construct, ...) — умеет что нужно.
пример конструктора std::pair() тут. но сам не могу понять, что нужно сделать.

спасибо.
снова драсте.

в продолжение темы
Автор: niXman
Дата: 21.09.14
, решил использовать найденный костыль. но загвоздка в том, что он не умеет инициализировать non-copyable и non-movable типы.
компилябельный пример:

#include <iostream>
#include <memory>
#include <utility>
#include <tuple>
#include <functional>

#include <boost/noncopyable.hpp>

/***************************************************************************/

namespace detail {
    template<int ... N>
    struct index {
        typedef index<N..., sizeof...(N)> next;
    };
    template<int N>
    struct build_index {
        typedef typename build_index<N - 1>::type::next type;
    };

    template<>
    struct build_index<0> {
        typedef index<> type;
    };

    template<typename T>
    struct tuple_index {
        typedef typename build_index<
        std::tuple_size<
        typename std::remove_reference<T>::type
        >::value
        >::type type;
    };
} // ns detail

template<typename... Elements>
class piecewise_tuple: public std::tuple<Elements...> {
    typedef std::tuple<Elements...> base_type;

    template<int Index, typename... Args, int ... N>
    static typename std::tuple_element<Index, base_type>::type
    construct(std::tuple<Args...>&& args, detail::index<N...>) {
        typedef typename std::tuple_element<Index, base_type>::type result_type;
        return result_type(std::get<N>(std::move(args))...);
    }

    template<int ...N, typename ArgTuple>
    piecewise_tuple(detail::index<N...>, ArgTuple&& element_args)
        :base_type(
            construct<N>(
                std::get<N>(std::forward<ArgTuple>(element_args))
                ,typename detail::tuple_index<
                typename std::tuple_element<
                N
                ,typename std::remove_reference<ArgTuple>::type
                >::type
                >::type()
            )...
        )
    {}

public:
    piecewise_tuple() = default;

    // For non-piecewise constructors, forward them
    template<typename... Args>
    piecewise_tuple(Args&&... args)
        :base_type(std::forward<Args>(args)...)
    {}


    template<typename... T>
    piecewise_tuple(std::piecewise_construct_t, T&&... args)
        :piecewise_tuple(
             typename detail::tuple_index<base_type>::type()
            ,std::forward_as_tuple(std::forward<T>(args)...)
        )
    {}
};

/***************************************************************************/

struct noncopyable: boost::noncopyable {};

struct type: boost::noncopyable {
    type(int &i, const char *s, noncopyable &n)
        :i(i)
        ,s(s)
        ,n(n)
    {}

    int &i;
    const char *s;
    noncopyable &n;
};

/***************************************************************************/

int main() {
   int i = 5;
    const char *s = "string";
    noncopyable n;

   std::unique_ptr<int> up(new int(0));

    piecewise_tuple<std::pair<int, int>, double, std::unique_ptr<int>, int&/*, type*/> p(
         std::piecewise_construct
        ,std::forward_as_tuple(1,2)
        ,std::forward_as_tuple(4.3)
        ,std::forward_as_tuple(std::move(up))
        ,std::forward_as_tuple(i)
        //,std::forward_as_tuple(i, s, n)
    );
}

/***************************************************************************/

тут, если расскоментить два фрагмента в main() — код перестанет компилиться. ошибка в том, что:
error: use of deleted function 'type::type(const type&)'

copy и move конструкторы для type на самом деле не нужны.

к тому же, std::pair(std::piecewise_construct, ...) — умеет что нужно.
пример конструктора std::pair() тут. но сам не могу понять, что нужно сделать.

спасибо.