[boost] [container] container_detail::pair piecewise constructor

13 views
Skip to first unread message

László Szécsi

unread,
Nov 14, 2012, 12:53:04 PM11/14/12
to Bo...@lists.boost.org
Hi everyone,

boost::container::container_detail::pair's piecewise constructor is
missing, as acknowledged in a comment. This makes
container::flat_map::emplace less useful (perhaps useless) as the
following will not work:

boost::container::flat_multimap<TestKey, TestValue> testMap;

testMap.emplace(boost::container::container_detail::piecewise_construct,
boost::make_tuple(30),
boost::make_tuple(50));

where both TestKey and TestValue are non-copyable, moveable classes
with a constructor taking an int.

The compilation error message will correctly say that
boost::container::container_detail::pair does not have a constructor
with three arguments.

I tried to implement the missing piecewise constructor based on
std::pair's in the g++ standard libraries. I failed at it, so I would
like to request some assistance and education. This is where I got:

// from the standard lib
template<std::size_t _Num>
struct _Build_index_tuple
{ typedef typename _Build_index_tuple<_Num-1>::__type::__next __type; };

// from the standard lib
template<>
struct _Build_index_tuple<0>
{ typedef _Index_tuple<> __type; };

template <class... Args1, class... Args2>
pair(piecewise_construct_t, ::boost::tuple<Args1...> first_args,
::boost::tuple<Args2...> second_args)
: pair(::boost::move(first_args), ::boost::move(second_args),
typename _Build_index_tuple<sizeof...(Args1)>::__type(),
typename _Build_index_tuple<sizeof...(Args2)>::__type())
{}

template<typename... Args1, std::size_t... Indices1, typename...
Args2, std::size_t... Indices2>
explicit pair(tuple<Args1...> tuple1, tuple<Args2...> tuple2,
_Index_tuple<Indices1...>, _Index_tuple<Indices2...>)
: first(::boost::forward<Args1>(std::get<Indices1>(tuple1))...),
second(::boost::forward<Args2>(std::get<Indices2>(tuple2))...)
{ }

This gets me a recursive error message far too long to quote, starting with:
error C2664: 'boost::container::container_detail::pair<Key,T>::pair(std::pair<Key,T>
&&)' : cannot convert parameter 3 from
'boost::tuples::tuple<int,boost::tuples::null_type // lot of
null_types omitted
to 'boost::tuples::tuple<boost::tuples::null_type, // lot of null_types omitted

I used the VS2012 Nov CTP compiler.

I understand that variadic templates have not been very portable and
boost::unordered, which has a piecewise constructor implementation,
does it completely differently and much more painfully. But is there a
reason for the approach I tried not to work with boost at all?

Could you please help me fix this code?

Thank you very much,
Laszlo Szecsi

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

László Szécsi

unread,
Nov 15, 2012, 4:47:31 AM11/15/12
to Bo...@lists.boost.org
I did some more research and it turns out std-style piecewise
construction fails with VS2012 Nov CTP compiler, just like my attempt
at adding piecewise construction to boost::container_detail::pair. In
particular, the following dummy code compiles under g++ 4.7.1 but not
under VS2012 Nov CTP.

class Foo {
public:
template <class... Args1, class... Args2>
Foo( const ::std::piecewise_construct_t,
::std::tuple<Args1...> first_args,
::std::tuple<Args2...> second_args)
{ }
};

int main(){
Foo s(
std::piecewise_construct,
std::move( std::make_tuple(30) ),
std::move( std::make_tuple(50) ));
}

I guess the time is not ripe for the container implementation to use
true variadic templates yet.

Is there ongoing effort to implement container_detail::pair's
piecewise constructor in the same way as it was implemented in
boost::unordered?

Best regards,

Daniel James

unread,
Nov 15, 2012, 6:45:43 AM11/15/12
to bo...@lists.boost.org
On 14 November 2012 17:53, László Szécsi <sze...@iit.bme.hu> wrote:
>
> I understand that variadic templates have not been very portable and
> boost::unordered, which has a piecewise constructor implementation,
> does it completely differently and much more painfully.

Much of the complexity was from supporting the old variadic
constructors for pairs, which were pretty problematic. Since that's
been deprecated for some time (you need to define a macro to use it) I
could probably remove it and that might lead to a simpler
implementation. I suspect I'm the only person who ever used it anyway.

Also, I didn't use the trick for constructing objects from tuples on
compilers with variadic templates because I wasn't aware of it at the
time. At some point I'll use it instead, but I'll still need the
macros for compilers without full variadic support.

László Szécsi

unread,
Nov 15, 2012, 8:12:11 AM11/15/12
to bo...@lists.boost.org
On Thu, Nov 15, 2012 at 12:45 PM, Daniel James <dnl...@gmail.com> wrote:
> On 14 November 2012 17:53, László Szécsi <sze...@iit.bme.hu> wrote:
>> boost::unordered, which has a piecewise constructor implementation,
>
> Much of the complexity was from supporting the old variadic
> constructors for pairs, which were pretty problematic.
...
> but I'll still need the
> macros for compilers without full variadic support.
Absolutely. Great work, well done! If only someone did the same for flat_map.

Ion Gaztañaga

unread,
Nov 17, 2012, 4:29:33 AM11/17/12
to bo...@lists.boost.org
El 15/11/2012 14:12, László Szécsi escribió:
> On Thu, Nov 15, 2012 at 12:45 PM, Daniel James <dnl...@gmail.com> wrote:
>> On 14 November 2012 17:53, László Szécsi <sze...@iit.bme.hu> wrote:
>>> boost::unordered, which has a piecewise constructor implementation,
>>
>> Much of the complexity was from supporting the old variadic
>> constructors for pairs, which were pretty problematic.
> ...
>> but I'll still need the
>> macros for compilers without full variadic support.
> Absolutely. Great work, well done! If only someone did the same for flat_map.

Can you please fill a ticket for this? The main problem is with
compilers without variadic templates. Implementing piecewise construct
for C++03 required a lot of job due to the internal C++11 pair
emulation, so I decided to implement it later than some other neede
features. I'll take a look to Unordered implementation to get some
inspiration.

However I'm afraid I won't have time to implement it shortly. We can
maybe start with compilers supporting variadic templates and support
other compilers in a future release.

Best,

Ion
Reply all
Reply to author
Forward
0 new messages