namespace mct { // Templated structure specifying how given type could be used by its container (in // broad sense), i.e. "externally". Default is no external use; it can be enabled by // specializing the structure. template struct external_use { }; template struct supports_external_use : impl::false_type { }; template struct supports_external_use ::type> : impl::true_type { }; template ::value && !impl::is_same ::value), bool recurse = supports_external_use ::value> struct extern_use_field; template struct extern_use_field { typedef Type type; typedef Value value_type; static const value_type& get (const type& structure) { return structure.*field; } static void set (type& structure, const value_type& value) { structure.*field = value; } }; template struct extern_use_field { typedef Type type; typedef typename external_use ::value_type value_type; static const value_type& get (const type& structure) { return external_use ::get (structure.*field); } static void set (type& structure, const value_type& value) { external_use ::set (structure.*field, value); } }; template struct external_use , typename impl::enable_if ::value>::type> : extern_use_field , First, &std::pair ::first> { }; template struct external_use , typename impl::enable_if ::value && !supports_external_use ::value>::type> : extern_use_field , Second, &std::pair ::second> { }; namespace impl { // By default the structure is empty. 'intrusive_storage' below makes sure to never // use it when it's empty, i.e. of size 1. template struct extern_use_wrapper { }; # if 0 // Ideally we'd want this, but see comment in the preprocessor-enabled branch. template struct extern_use_wrapper ::value>::type> : type // ... # else // We currently specialize 'extern_use_wrapper' very conservatively. At least GCC up // to 4.6 doesn't provide 'std::is_class', so there is no reliable way to determine if // 'type' is subclassable without requiring a recent compiler. The most important // case, especially for maps, is 'std::pair', so we limit ourselves to that for now. template struct extern_use_wrapper > : std::pair { typedef std::pair base_type; char _unused; extern_use_wrapper& operator= (const extern_use_wrapper& that) { return static_cast (base_type::operator= (that)); } # if MCT_CXX0X_SUPPORTED extern_use_wrapper& operator= (extern_use_wrapper&& that) { return static_cast (base_type::operator= (std::forward (that))); } # endif }; # endif } }