#ifndef SPROUT_FIXED_CONTAINER_TRAITS_HPP #define SPROUT_FIXED_CONTAINER_TRAITS_HPP #include #include #include #include #include namespace sprout { namespace detail { template struct fixed_container_traits_base { public: typedef typename Container::value_type value_type; typedef typename Container::iterator iterator; typedef typename Container::const_iterator const_iterator; typedef typename Container::reference reference; typedef typename Container::const_reference const_reference; typedef typename Container::size_type size_type; typedef typename Container::difference_type difference_type; typedef typename Container::pointer pointer; typedef typename Container::const_pointer const_pointer; }; template struct fixed_container_traits_base { public: typedef T value_type; typedef T* iterator; typedef T const* const_iterator; typedef T& reference; typedef T const& const_reference; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; typedef T* pointer; typedef T const* const_pointer; }; } // namespace detail // // fixed_container_traits // template struct fixed_container_traits : public sprout::detail::fixed_container_traits_base { public: typedef Container fixed_container_type; typedef Container internal_type; typedef Container clone_type; public: SPROUT_STATIC_CONSTEXPR typename sprout::detail::fixed_container_traits_base::size_type fixed_size = std::tuple_size::type>::value ; }; template struct fixed_container_traits : public sprout::fixed_container_traits { public: typedef typename sprout::fixed_container_traits::const_iterator iterator; typedef typename sprout::fixed_container_traits::const_reference reference; typedef typename sprout::fixed_container_traits::const_pointer pointer; }; template struct fixed_container_traits : public sprout::detail::fixed_container_traits_base { public: typedef T fixed_container_type[N]; typedef T internal_type[N]; typedef T clone_type[N]; public: SPROUT_STATIC_CONSTEXPR typename sprout::detail::fixed_container_traits_base::size_type fixed_size = N; }; template struct fixed_container_traits : public sprout::fixed_container_traits { public: typedef typename sprout::fixed_container_traits::const_iterator iterator; typedef typename sprout::fixed_container_traits::const_reference reference; typedef typename sprout::fixed_container_traits::const_pointer pointer; }; // // rebind_fixed_size // template struct rebind_fixed_size { public: template::size_type S> struct apply; }; template struct rebind_fixed_size { public: template::size_type S> struct apply { public: typedef T type[S]; }; }; // // get_fixed_functor // template struct get_fixed_functor { public: typename sprout::fixed_container_traits::fixed_container_type& operator()(Container& cont) const { return cont; } SPROUT_CONSTEXPR typename sprout::fixed_container_traits::fixed_container_type const& operator()(Container const& cont) const { return cont; } }; template struct get_fixed_functor : public sprout::get_fixed_functor {}; // // clone_functor // template struct clone_functor { public: template SPROUT_CONSTEXPR typename sprout::fixed_container_traits::clone_type operator()(Other&& cont) const { return typename sprout::fixed_container_traits::clone_type(sprout::forward(cont)); } }; template struct clone_functor : public sprout::clone_functor {}; // // make_clone_functor // template struct make_clone_functor { public: template SPROUT_CONSTEXPR typename sprout::fixed_container_traits::clone_type operator()(Args&&... args) const { return typename sprout::fixed_container_traits::clone_type{{sprout::forward(args)...}}; } }; template struct make_clone_functor : public sprout::make_clone_functor {}; // // remake_clone_functor // template struct remake_clone_functor { public: template SPROUT_CONSTEXPR typename sprout::fixed_container_traits::clone_type operator()( Other&& other, typename sprout::fixed_container_traits::difference_type size, Args&&... args ) const { return sprout::make_clone_functor().template operator()(sprout::forward(args)...); } }; template struct remake_clone_functor : public sprout::remake_clone_functor {}; } // namespace sprout #endif // #ifndef SPROUT_FIXED_CONTAINER_TRAITS_HPP