lean cpp library
A lean C++ library providing efficient utility classes for high-performance C++ applications.
dereference.h
00001 /*****************************************************/
00002 /* lean Meta                    (c) Tobias Zirr 2011 */
00003 /*****************************************************/
00004 
00005 #ifndef LEAN_META_DEREFERENCE
00006 #define LEAN_META_DEREFERENCE
00007 
00008 #include "../lean.h"
00009 #include "strip.h"
00010 
00011 namespace lean
00012 {
00013 namespace meta
00014 {
00015 
00016 namespace impl
00017 {
00018 
00019 template <class StrippedValue, class Value>
00020 struct maybe_dereference_once
00021 {
00022 private:
00023     typedef typename strip_const<typename strip_reference<Value>::type>::type stripped_value_type;
00024 
00025 public:
00026     static const bool dereferenced = false;
00027     
00028     typedef Value value_type;
00029 
00030     typedef stripped_value_type& parameter_type;
00031     typedef value_type& return_type;
00032     static LEAN_INLINE return_type dereference(parameter_type value) { return value; }
00033 
00034     typedef const stripped_value_type& const_parameter_type;
00035     typedef const value_type& const_return_type;
00036     static LEAN_INLINE const_return_type dereference(const_parameter_type value) { return value; }
00037 };
00038 
00039 template <class StrippedValue, class Value>
00040 struct maybe_dereference_pointer
00041 {
00042 private:
00043     struct disable_type { };
00044 
00045 public:
00046     static const bool dereferenced = true;
00047 
00048     typedef Value value_type;
00049     
00050     typedef disable_type& parameter_type;
00051     typedef disable_type& return_type;
00052     static LEAN_INLINE return_type dereference(parameter_type parameter) { return parameter; }
00053 
00054     typedef Value* const_parameter_type;
00055     typedef value_type& const_return_type;
00056     static LEAN_INLINE const_return_type dereference(const_parameter_type pointer) { return *pointer; }
00057 };
00058 
00059 template <class ModifiedVoid>
00060 struct maybe_dereference_pointer<void, ModifiedVoid>
00061 {
00062     static const bool dereferenced = false;
00063 
00064     typedef ModifiedVoid* value_type;
00065     
00066     typedef value_type& parameter_type;
00067     typedef value_type& return_type;
00068     static LEAN_INLINE return_type dereference(parameter_type value) { return value; }
00069 
00070     typedef const value_type& const_parameter_type;
00071     typedef const value_type& const_return_type;
00072     static LEAN_INLINE const_return_type dereference(const_parameter_type value) { return value; }
00073 };
00074 
00075 template <class Value, class Pointer>
00076 struct maybe_dereference_once<Value*, Pointer>
00077     : public maybe_dereference_pointer<typename strip_modifiers<Value>::type, Value> { };
00078 
00079 } // namespace
00080 
00082 template <class Type>
00083 struct maybe_dereference_once
00084 {
00085 private:
00086     typedef  impl::maybe_dereference_once<
00087         typename strip_modifiers<typename strip_reference<Type>::type>::type,
00088         Type > internal_dereferencer;
00089 
00090 public:
00092     static const bool dereferenced = internal_dereferencer::dereferenced;
00093 
00095     typedef typename internal_dereferencer::value_type value_type;
00096 
00098     static LEAN_INLINE typename internal_dereferencer::return_type dereference(typename internal_dereferencer::parameter_type value)
00099     {
00100         return internal_dereferencer::dereference(value);
00101     }
00103     static LEAN_INLINE typename internal_dereferencer::const_return_type dereference(typename internal_dereferencer::const_parameter_type value)
00104     {
00105         return internal_dereferencer::dereference(value);
00106     }
00107 };
00108 
00109 } // namespace
00110 
00111 using meta::maybe_dereference_once;
00112 
00113 } // namespace
00114 
00115 #endif