Travis Vitek wrote:
Martin Sebor wrote:
Travis Vitek wrote:
[...]
I can think of a couple of options that satisfy these. I'm not sure
how palatable I find them yet, but I might get over their (initial)
lack of appeal if the payoff is worth it. YMMV.
One is to drop the cv specializations of the __rw_is_xxx traits and
define the standard traits in terms of both remove_cv and the __rw
traits, like so:
template <class _TypeT>
struct is_void:
integral_constant<bool,
_RW::__rw_is_void<typename
_RW::__rw_remove_cv<_TypeT>::type>::value>
{ };
or more concisely:
template <class _TypeT>
struct is_void:
integral_constant<bool, _RWSTD_IS_VOID (_TypeT)::value>
{ };
with _RWSTD_IS_VOID() being #defined like so:
#define _RWSTD_IS_VOID(T) \
_RW::__rw_is_void<typename _RW::__rw_remove_cv<T>::type>
All internal code would always need to use _RWSTD_IS_VOID() and
never _RW::__rw_is_void directly.
I think there is a problem with _RWSTD_IS_VOID() being defined like this
because it can't be used outside a template (because of the typename
keyword being used in the macro definition).
I hadn't considered using the Unary Traits in non-template code.
I don't think it's likely but it certainly seems plausible (e.g.,
to insulate the implementation of an algorithm from changes to
some of the fundamental properties of an implementation-defined
class type such as whether it has a trivial default ctor, etc.)
That said, I'm not sure that this use case is one that we need
to concern ourselves with. To minimize footprint and insulate
user code from implementation details we make an effort to
confine as much non-generic code as possible into .cpp files
where using the public (std::) traits is fine and preferable
over relying on implementation details (i.e., all the __rw_xxx
traits that we use in library headers to reduce namespace
pollution).
Martin
$ cat u.cpp && g++ u.cpp
namespace __rw {
template <class T>
struct __rw_remove_cv { typedef T type; };
template <class T>
struct __rw_is_void { enum { value = 0 }; };
template <>
struct __rw_is_void<void> { enum { value = 1 }; };
}
#define _RW __rw
#define _RWSTD_IS_VOID(T) \
_RW::__rw_is_void<typename _RW::__rw_remove_cv<T>::type>
int main ()
{
const bool b = _RWSTD_IS_VOID(void)::value;
return b == 0;
}
u.cpp: In function 'int main()':
u.cpp:23: error: using 'typename' outside of template
Travis