If you have used Boost's type_traits header (or what's in C++ standard now) you might have wondered as to how these could have been implemented. If you haven't, type traits are like a jacket to any type that provide meta information about them without actually modifying the type/class itself. I will dig into the type_traits header of Boost to see how its done.
To demonstrate how it's used, lets assume you are writing a generic algorithm that works on a range of iterators. But your assumption it that it is an iterator to a numeric type, because you do a lot of numeric operation on them. So, here is how you write it.
This should throw a compiler error if any non-arithmetic type is passed to total(). Let's look at how is_arithmetic is implemented so as to see how it identifies arithmetic types from others.
Let's go down to: /usr/include/boost/type_traits.cpp. It includes a lot of internal headers from /usr/include/boost/ which have the same name as the trait class they provide.
If you go down to /usr/include/boost/type_traits/is_arithmetic.hpp
You see a lot of arcane pre-processor stuff, but the key thing to observe is:
You might notice all internal details in Boost goes into an internal namespace.
So, is_arithmetic_impl<T> is another internal type trait class, which is wrapped around by the one we use.
It looks as follows:
This structure again wraps around more type traits is_integral, is_float and does a compile time logical OR of the results. They mean that an arithmetic type should be integral or one of the float types.
Let's explore is_integral.hpp. It provides a traits class that returns a type true when parametrized on intergal types and false for any other type. Basically, it tells whether a type is integral or not.
Again if you skim through all the pre-processor magic to come down to what they are implementing you see a set of declarations:
followed by:
and many more other integral types.
If you look for what BOOST_TT_AUX_BOOL_TRAIT_CV_SPEC1 macro expands to in boost/type_traits/detail/bool_trait_def.hpp, it looks as follows:
To explain this in simple terms, all what's being done here is explicit template specialization
You can think of is_integral to be implemented as follows in simple terms:
.... and so on for each integral type. So, the value is going to be true for each type they specialize on, but false for all other types..
To demonstrate how it's used, lets assume you are writing a generic algorithm that works on a range of iterators. But your assumption it that it is an iterator to a numeric type, because you do a lot of numeric operation on them. So, here is how you write it.
This should throw a compiler error if any non-arithmetic type is passed to total(). Let's look at how is_arithmetic is implemented so as to see how it identifies arithmetic types from others.
Let's go down to: /usr/include/boost/type_traits.cpp. It includes a lot of internal headers from /usr/include/boost/ which have the same name as the trait class they provide.
If you go down to /usr/include/boost/type_traits/is_arithmetic.hpp
You see a lot of arcane pre-processor stuff, but the key thing to observe is:
You might notice all internal details in Boost goes into an internal namespace.
So, is_arithmetic_impl<T> is another internal type trait class, which is wrapped around by the one we use.
It looks as follows:
This structure again wraps around more type traits is_integral, is_float and does a compile time logical OR of the results. They mean that an arithmetic type should be integral or one of the float types.
Let's explore is_integral.hpp. It provides a traits class that returns a type true when parametrized on intergal types and false for any other type. Basically, it tells whether a type is integral or not.
Again if you skim through all the pre-processor magic to come down to what they are implementing you see a set of declarations:
followed by:
and many more other integral types.
If you look for what BOOST_TT_AUX_BOOL_TRAIT_CV_SPEC1 macro expands to in boost/type_traits/detail/bool_trait_def.hpp, it looks as follows:
To explain this in simple terms, all what's being done here is explicit template specialization
You can think of is_integral to be implemented as follows in simple terms:
.... and so on for each integral type. So, the value is going to be true for each type they specialize on, but false for all other types..
No comments:
Post a Comment