Help with (possibly MPL) pattern for a viewer that may contain a copy of statically allocated data
I am wondering what the best pattern/approach for a data structure that may contain either a reference or a copy of some data used in a constructor. I would love the opportunity to have the data structure capable of conditionally storing the data for the data copy on the stack. Are there any fancy generic tricks/patterns to do this using boost::mpl, etc.? So to put in some pseudocode notes for discussion to get the point across of what I think I want: boost::array< boost::array<double, M>, N> myaxis; //creates axis in a stack allocated data structure. regular_grid<M, N, COPYDATA> my_grid(axis_values); regular_grid<M, N, REFDATA> my_grid(axis_values); template<int M, int N, int ConstructionPolicy> class regular_grid { boost::array< boost::array<double, M>, N>& axis_ref_; //Reference to the axis, either static or actual reference. All code in the class would use this, not axis_ STATIC_IF(ConstructionPolicy == COPYDATA) { boost::array< boost::array<double, M>, N> axis_; regular_grid(const boost::array< boost::array<double, M>, N>& axis) : axis_(axis), axis_ref_(axis_) //constructor makes copy, sets ref to copy. { } } STATIC_ELSE(ConstructionPolicy == REFDATA) { regular_grid(const boost::array< boost::array<double, M>, N>& axis) : axis_ref_(axis) {} //constructor just uses the ref. } }; Is this possible? any ideas on code to look at to see how to do it?
AMDG Jesse Perla wrote:
I am wondering what the best pattern/approach for a data structure that may contain either a reference or a copy of some data used in a constructor. I would love the opportunity to have the data structure capable of conditionally storing the data for the data copy on the stack. Are there any fancy generic tricks/patterns to do this using boost::mpl, etc.?
So to put in some pseudocode notes for discussion to get the point across of what I think I want:
boost::array< boost::array<double, M>, N> myaxis; //creates axis in a stack allocated data structure. regular_grid<M, N, COPYDATA> my_grid(axis_values); regular_grid<M, N, REFDATA> my_grid(axis_values);
template<int M, int N, int ConstructionPolicy> class regular_grid { boost::array< boost::array<double, M>, N>& axis_ref_; //Reference to the axis, either static or actual reference. All code in the class would use this, not axis_
STATIC_IF(ConstructionPolicy == COPYDATA) { boost::array< boost::array<double, M>, N> axis_; regular_grid(const boost::array< boost::array<double, M>, N>& axis) : axis_(axis), axis_ref_(axis_) //constructor makes copy, sets ref to copy. { }
} STATIC_ELSE(ConstructionPolicy == REFDATA) { regular_grid(const boost::array< boost::array<double, M>, N>& axis) : axis_ref_(axis) {} //constructor just uses the ref. } };
Is this possible? any ideas on code to look at to see how to do it?
If you don't need to decide at runtime whether to store a copy or a reference, then you can avoid the reference when you have a copy using static polymorphism: template<int M, int N, class Storage = boost::mpl::identity<> > class regular_grid { typedef boost::array< boost::array<double, M>, N > array_type; typedef typename boost::mpl::apply<Storage, array_type>::type storage_type; storage_type axis_; // use axis }; typedef boost::add_reference<boost::add_const<boost::mpl::_1> > reference_policy; typedef boost::mpl::identity<> copy_policy; regular_grid<2, 3, reference_policy> g; In Christ, Steven Watanabe
Steven Watanabe <watanabesj <at> gmail.com> writes:
AMDG
Jesse Perla wrote:
I am wondering what the best pattern/approach for a data structure that may contain either a reference or a copy of some data used in a constructor.[...]
If you don't need to decide at runtime whether to store a copy or a reference, then you can avoid the reference when you have a copy using static polymorphism:
[beatiful solution snipped] When the OP's post got to my mailbox, I rapidly put myself to work in a solution with the hope that Steven was asleep or somehow away from his computer, but he's done it again --beating eveybody to providing an answer, and with style too! It's not fair! Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
Joaquin M Lopez Munoz wrote:
When the OP's post got to my mailbox, I rapidly put myself to work in a solution with the hope that Steven was asleep or somehow away from his computer, but he's done it again --beating eveybody to providing an answer, and with style too! It's not fair!
If I hadn't met Steven in person myself, I would wonder if he was real or some expert programmer collective that constantly monitors the boost lists and cranks out solutions. Thanks for all your contributions, Steven. -- Eric Niebler BoostPro Computing http://www.boostpro.com
As a basic user of boost, I would like to echo this. Thank you Steven for your answers, -----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Eric Niebler Sent: 24 January 2009 21:12 To: boost-users@lists.boost.org Subject: Re: [Boost-users] Help with (possibly MPL) pattern for a viewer that may contain a copy of statically allocated data Joaquin M Lopez Munoz wrote:
When the OP's post got to my mailbox, I rapidly put myself to work in a solution with the hope that Steven was asleep or somehow away from his computer, but he's done it again --beating eveybody to providing an answer, and with style too! It's not fair!
If I hadn't met Steven in person myself, I would wonder if he was real or some expert programmer collective that constantly monitors the boost lists and cranks out solutions. Thanks for all your contributions, Steven. -- Eric Niebler BoostPro Computing http://www.boostpro.com
template<int M, int N, class Storage = boost::mpl::identity<> > class regular_grid { typedef boost::array< boost::array<double, M>, N > array_type; typedef typename boost::mpl::apply<Storage, array_type>::type storage_type; storage_type axis_; // use axis };
typedef boost::add_reference<boost::add_const<boost::mpl::_1> > reference_policy; typedef boost::mpl::identity<> copy_policy;
regular_grid<2, 3, reference_policy> g;
In Christ, Steven Watanabe
Elegant solution I never began to imagine. Thank you, Steven. It's _generally_ useful. B/Rgds Max
On Jan 24, 3:19 pm, Steven Watanabe <watanab...@gmail.com> wrote:
template<int M, int N, class Storage = boost::mpl::identity<> > class regular_grid { typedef boost::array< boost::array<double, M>, N > array_type; typedef typename boost::mpl::apply<Storage, array_type>::type storage_type; storage_type axis_; // use axis
}; typedef boost::add_reference<boost::add_const<boost::mpl::_1> > reference_policy; typedef boost::mpl::identity<> copy_policy;
regular_grid<2, 3, reference_policy> g; In Christ, Steven Watanabe
A followup if anyone else is using this code: Steven: Your code worked beautifully, but it turned out that I also needed an assignment operator (which fails due to the const on the ref). For now, I did the following: typedef boost::add_reference<boost::add_const<boost::mpl::_1> > > const_reference_policy; typedef boost::add_reference<<boost::mpl::_1 > > reference_policy; Things *kind of* work now for the default assignment operator generated by the compiler. I can now create a new item and then use the copy assignment(if they have the same storage policy). Things like... regular_grid <2,3> interp( f_values); //The default is the new non- const reference_policy. regular_grid <2,3> interp3 = interp; //Works! Also works for the copy_policy interp3 = interp; //Fails! Also fails for the copy_policy Lower priority for me, but assignment will only work for 2 grids of type ref or 2 of type value. What is the best way to write the assignment operator to allow assignment between the different policy types? (combinations except assignment to a const_reference_policy of course) (my apologies for misspelling your name previously) Thanks, Jesse
AMDG jesseperla wrote:
A followup if anyone else is using this code:
Steven: Your code worked beautifully, but it turned out that I also needed an assignment operator (which fails due to the const on the ref). For now, I did the following: typedef boost::add_reference<boost::add_const<boost::mpl::_1> > > const_reference_policy; typedef boost::add_reference<<boost::mpl::_1 > > reference_policy;
Things *kind of* work now for the default assignment operator generated by the compiler. I can now create a new item and then use the copy assignment(if they have the same storage policy). Things like... regular_grid <2,3> interp( f_values); //The default is the new non- const reference_policy. regular_grid <2,3> interp3 = interp; //Works! Also works for the copy_policy interp3 = interp; //Fails! Also fails for the copy_policy
Lower priority for me, but assignment will only work for 2 grids of type ref or 2 of type value. What is the best way to write the assignment operator to allow assignment between the different policy types? (combinations except assignment to a const_reference_policy of course)
template<int M1, int N1, class S> friend class regular_grid; regular_grid& operator=(const regular_grid& other) { axis_ = other.axis_ }; template<class S> regular_grid& operator=(const regular_grid<M, N, S>& other) { axis_ = other.axis_ }; In Christ, Steven Watanabe
participants (7)
-
Eric Niebler
-
Hicham Mouline
-
Jesse Perla
-
jesseperla
-
Joaquin M Lopez Munoz
-
Max
-
Steven Watanabe