
-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Rob Stewart From: "Jost, Andrew" <Andrew_Jost@mentor.com>
From: boost-bounces@lists.boost.org
<clip>
example code (BTW, others seem to prefer the spelling "adaptor," which is more consistent with other standardized names like "iterator," so I'll conform to that):
I took a look at "adapter" and "adaptor" at dictionary.com. Most dictionaries list "adapter" as the main entry and "adaptor" as a variant. WordNet at Princeton University makes the two synonymous only for this usage.
A quick Google search showed 18.2 million hits for "adapter" and 4.1 million for "adaptor."
I think "adapter" is the right spelling in this case.
I also checked dictionary.com and came to the same initial conclusion, but so many people used "adaptor" in their replies that it made me wonder whether that spelling was more appropriate. I prefer whichever spelling is intuitive for most users. <clip>
// METHOD #2a: define a custom predicate template< class T, class Pred, T Def = T() > class optPred : public std::binary_function<boost::optional<T>, boost::optional<T>, bool> { Pred f; T _eval( const boost::optional<T>& x ) const { return ( x ? x.get() : Def ); } public: optPred() : f( Pred() ) {} bool operator()( const first_argument_type& a, const second_argument_type& b ) const { return f( _eval(a), _eval(b) ); } }; opt_int opt_max; opt_max= *std::max_element( v.begin(), v.end(), optPred< int, std::less<int>, -1 >() );
That's a lot of work. You'd want to use something like Boost.Lambda to make this more reasonable.
Yes, way too much work. See below.
{ T Def;
// METHOD #2b: use an adaptor-like predicate template< class T > class adaptor_substitute : public std::unary_function< boost::optional<T>, T public: _adaptor_() : Def( T() ) {} _adaptor_(T def) : Def( def ) {} T operator()(const argument_type& x ) { return ( x ? x.get() : Def ); } }; max = *std::max_element( boost::make_transform_iterator( v.begin, adaptor_substitute<int>(-1) ), boost::make_transform_iterator( v.end, adaptor_substitute<int>(-1) ) );
This isn't really an adapter substitute. It is an adapter, adapted (pun intended) to be a predicate.
But a predicate must return bool, not T. Did I miss something?
// METHOD #3: use an adaptor max = *std::max_element( boost::make_transform_iterator( v.begin, boost::optional<int>::adaptor(-1) ), // NOTE: boost::optional<int>::adaptor does not currently exist boost::make_transform_iterator( v.end, boost::optional<int>::adaptor(-1) ) );
That is clearly the most straightforward of the bunch, but I'd like to see a proper Boost.Lambda or Boost.Function variant for comparison.
I would prefer to use Boost.Lambda, but I am currently stuck on VC6 for Win32 development. It is becoming a problem...
BTW, why have you shown the adapter as a nested type of boost::optional? Do you not think it is applicable to anything else? I can envision adapting pointers or even floating point types (where NaN is the "empty" value), to name just two more types adapter might support.
I guess I started with Boost.Optional in mind and never considered anything else. Also, depending on the implementation the adapter may need to interact with Boost.Optional. Can you provide examples of some ways you might use an adapted pointer or float? -Andy