Boost logo

Boost :

Subject: Re: [boost] [concept] forward declarations and `BOOST_CONCEPT_REQUIRES()`
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2010-08-13 02:45:43


On Wed, Aug 11, 2010 at 5:03 PM, David Abrahams <dave_at_[hidden]> wrote:
> At Wed, 11 Aug 2010 22:54:21 +0200,
> Stefan van Kessel wrote:
>>
>> On 8/11/2010 8:44 PM, Lorenzo Caminiti wrote:
>> > I have this error on _MSC_VER 1400 (MSVC8?) so I was thinking to use:
>> >
>> >      #if BOOST_WORKAROUND(BOOST_MSVC,>= 1400)
>> >      ... // Workaround wrapper for BOOST_CONCEPT_CHECK following your code below.
>> >      #else
>> >      ... // Original BOOST_CONCEPT_CHECK with no workaround.
>> >      #endif
>>
>> That is the general idea but I'd go with
>> #elif BOOST_WORKAROUND(BOOST_MSVC, <= 1600) &&
>> BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
>> since I'm still hopeful that in the upcoming MSVC release the workaround
>> won't be necessary.
>
> Normally in a case like this we use BOOST_TESTED_AT, so we can easily find
> and test workarounds that may no longer be needed.

On Wed, Aug 11, 2010 at 4:54 PM, Stefan van Kessel
<van_kessel_at_[hidden]> wrote:
> On 8/11/2010 8:44 PM, Lorenzo Caminiti wrote:
>>
>> I don't have `decltype()` (I think that is a C++0x feature...). What
>> shall I use instead? Boost.TypeOf somehow? Can you please sketch the
>> code without `decltype()`?
>
> Actually the decltype isn't required at all. It is just a remnant of a
> previous attempt where without accessing ::boost::_requires_<>::value the
> compiler didn't seem to instantiate the _requires_ template. I should have
> double checked.
>
> I do not have Visual Studio 2005 (MSVC8) installed right now but on Visual
> Studio 2008 (MSVC9) it compiles when simply leaving out the decltype and
> ::value.
>
> Here is a link to a patchfile:
> https://svn.boost.org/trac/boost/attachment/ticket/4526/pathfile2.patch

Thanks a lot, this fully solves my problem.

I have implemented this workaround in my library essentially using the
code from this patch (with a some renaming) and guarded it with
`BOOST_TESTED_AT()` -- code listed below. I think the use of
`BOOST_PP_SEQ_FOR_EACH_I()` in the patch is not necessary so I
replaced it with just `BOOST_PP_SEQ_FOR_EACH()`. I have tested it on
MSVC8 and it works fine.

#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))

namespace contract { namespace aux {

template<typename Concept, typename Result> struct requires_msvc_result
    { typedef typename Result::type type; };

}} // namespace

#define CONTRACT_AUX_CONCEPT_REQUIRES_MSVC_STRIP_PARENS_(x) x

#define CONTRACT_AUX_CONCEPT_REQUIRES_MSVC_CHECK_(concept) \
    ::boost::_requires_< void (*)(concept) >

#define CONTRACT_AUX_CONCEPT_REQUIRES_MSVC_OPEN_TEMPLATE_(r, data, concept) \
    ::contract::aux::requires_msvc_result< \
            CONTRACT_AUX_CONCEPT_REQUIRES_MSVC_CHECK_ concept,

#define CONTRACT_AUX_CONCEPT_REQUIRES_MSVC_CLOSE_TEMPLATE_(r, data, concept) >

#define CONTRACT_AUX_CONCEPT_REQUIRES(concepts, result) \
    typename BOOST_PP_SEQ_FOR_EACH( \
            CONTRACT_AUX_CONCEPT_REQUIRES_MSVC_OPEN_TEMPLATE_, ~, concepts) \
            ::boost::parameter::aux::unaryfunptr_arg_type<void (*) result> \
            BOOST_PP_SEQ_FOR_EACH( \
                    CONTRACT_AUX_CONCEPT_REQUIRES_MSVC_CLOSE_TEMPLATE_, ~, \
                    concepts) \
            ::type

// No workaround needed -- use Boost.Concept implementation.
#else // BOOST_WORKAROUND

#define CONTRACT_AUX_CONCEPT_REQUIRES(concepts, result) \
    BOOST_CONCEPT_REQUIRES(concepts, result)

#endif // BOOST_WORKAROUND

#endif // #include guard

-- 
Lorenzo

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk