https://svn.lrde.epita.fr/svn/oln/trunk
Index: ChangeLog from Thomas Moulard thomas.moulard@lrde.epita.fr
Add stc::exact.
* static/tests/exact.cc: test suite of stc::exact (new file). * static/stc/exact.hh: implementation of stc::exact (new file). * static/stc/any.hh: adding a typedef exact_t in stc::any. * metalic/mlc/case.hh: fixing a bug in the protected defaults cases.
metalic/mlc/case.hh | 30 ++----- static/stc/any.hh | 6 + static/stc/exact.hh | 198 ++++++++++++++++++++++++++++++++++++++++++++++++++ static/tests/exact.cc | 161 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 373 insertions(+), 22 deletions(-)
Index: static/tests/exact.cc --- static/tests/exact.cc (revision 0) +++ static/tests/exact.cc (revision 0) @@ -0,0 +1,161 @@ +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 EPITA Research and +// Development Laboratory. +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +#include <iostream> +#include <exact.hh> // FIXME: was stc/exact.hh + +template <typename E> +struct abstraction : public stc::any<E> +{ +}; + + +template <typename E> +struct sub_abstraction : public abstraction<E> +{ +}; + +struct itself {}; + + +template <typename T = itself> +struct concrete_ : public sub_abstraction< concrete_<T> > +{ + void foo() const + { + std::cout << "foo() " << std::endl; + } +}; + +typedef concrete_<> concrete; + + +int main() +{ + //----------------------------------------- + + { + std::cout << stc::exact(42) << std::endl; + } + + { + int i = 42; + std::cout << stc::exact(i) << std::endl; + } + + { + const int i = 42; + std::cout << stc::exact(i) << std::endl; + } + + + { + int i = 42; + int * pi = &i; + std::cout << pi << " = " + << stc::exact(pi) << std::endl; + } + + { + int i = 42; + int * const pi = &i; + std::cout << pi << " = " + << stc::exact(pi) << std::endl; + } + + { + int i = 42; + const int * pi = &i; + std::cout << pi << " = " + << stc::exact(pi) << std::endl; + } + + { + int i = 42; + const int * const pi = &i; + std::cout << pi << " = " + << stc::exact(pi) << std::endl; + } + + // FIXME: Doesn't work! + +// { +// int i = 42; +// int * pi = &i; +// int ** ppi = π +// // stc::exact(ppi); + +// const int ci = 42; +// const int * cpi = &ci; +// const int ** cppi = &cpi; +// stc::exact(cppi); +// } + + //----------------------------------------- + { + concrete t; + const concrete::exact_t& tmp = stc::exact(t); + std::cout << &t << " = " + << &tmp << std::endl; + } + { + concrete *t = new concrete; + std::cout << t << " = " + << stc::exact(t) << std::endl; + } + + //----------------------------------------- + { + concrete t; + sub_abstraction<concrete>& st = t; + const sub_abstraction<concrete>::exact_t& tmp = stc::exact(st); + std::cout << &t << " = " + << &tmp << std::endl; + tmp.foo(); + } + { + sub_abstraction<concrete> *t = new concrete; + std::cout << t << " = " + << stc::exact(t) << std::endl; + } + + //----------------------------------------- + { + concrete t; + abstraction<concrete>& a = t; + const abstraction<concrete>::exact_t& tmp = stc::exact(a); + std::cout << &t << " = " + << &tmp << std::endl; + } + { + abstraction<concrete> *t = new concrete; + std::cout << t << " = " + << stc::exact(t) << std::endl; + } + +}
Property changes on: static/tests/exact.cc ___________________________________________________________________ Name: svn:executable + *
Index: static/stc/exact.hh --- static/stc/exact.hh (revision 0) +++ static/stc/exact.hh (revision 0) @@ -0,0 +1,198 @@ +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 EPITA Research and +// Development Laboratory. +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef STATIC_EXACT_HH +# define STATIC_EXACT_HH + +# include <stc/any.hh> + +# include <mlc/is_a.hh> +# include <mlc/case.hh> +# include <mlc/bexpr.hh> + + + + +# define stc_internal_is_any(T) \ +mlc::bexpr_< sizeof(internal::any_select(internal::makePtr< T >())) == sizeof(internal::yes_) > + + + +namespace stc +{ + + namespace internal + { + typedef char yes_; + struct no_ { char dummy[2]; }; + + template <typename E, typename P> + yes_ any_select(const stc::any<E,P>* arg); + + no_ any_select(...); + + template <typename T> + T* makePtr(); + + } + + template <typename T> + struct is_any_ + : public stc_internal_is_any(T) + { + }; + + template <typename T> + struct is_any_ < T* >; + + template <typename T> + struct is_any_ < const T >; + +} // end of namespace stc + + +mlc_case_equipment_for_namespace(stc); + + +namespace stc +{ + + + namespace tag + { + struct exact; + } + + + template <class T> + struct case_<tag::exact, T, 1> : public mlc::where_ < stc::is_any_<T> > + { + struct protected_ + { + typedef typename T::exact_t ret; + + static inline ret& impl(T& t) + { + return t.exact(); + } + }; + }; + + template <typename T> + struct default_case_<tag::exact, T> + { + struct protected_ + { + typedef T ret; + + static inline ret& impl(T& t) + { + return t; + } + }; + + }; + + + template <typename T> + struct to_exact_ + { + typedef typename switch_<tag::exact, T>::ret ret; + + static inline ret& impl(const T& t) + { + typedef typename case_<tag::exact, T>::ret case_t; + return case_t::impl(const_cast<T&>(t)); + } + }; + + + template <typename T> + struct to_exact_ < const T > + { + typedef const typename to_exact_<T>::ret ret; + + static inline ret& impl(const T& t) + { + return to_exact_<T>::impl(const_cast<T&>(t)); + } + }; + + + template <typename T> + struct to_exact_ < T* > + { + typedef typename to_exact_<T>::ret * ret; + + static inline ret impl(T* t) + { + return & to_exact_<T>::impl(*t); + } + }; + + + + template <typename T> + const typename to_exact_<const T>::ret& + exact(const T& t) + { + return to_exact_<const T>::impl(t); + } + + template <typename T> + typename to_exact_<T>::ret& + exact(T& t) + { + return to_exact_<T>::impl(t); + } + + template <typename T> + typename to_exact_<const T*>::ret + exact(const T* t) + { + return to_exact_<const T*>::impl(t); + } + + template <typename T> + typename to_exact_<T*>::ret + exact(T* t) + { + return to_exact_<T*>::impl(t); + } + + + template <typename T> + void exact(const T** t); + + template <typename T> + void exact(T** t); + + +} // end of namespace stc + +#endif // ! STATIC_EXACT_HH
Property changes on: static/stc/exact.hh ___________________________________________________________________ Name: svn:executable + *
Index: static/stc/any.hh --- static/stc/any.hh (revision 485) +++ static/stc/any.hh (working copy) @@ -67,6 +67,8 @@ struct any <E, dispatch_policy::best_speed> { + typedef E exact_t; + E& exact() { precondition(exact_ptr != 0); return *exact_ptr; @@ -129,6 +131,8 @@ struct any <E, dispatch_policy::best_memory> { + typedef E exact_t; + E& exact() { # if defined __GNUC__ && __GNUC__ >= 3 return static_cast<E&>(*this); @@ -185,6 +189,8 @@ struct any <E, dispatch_policy::simple> { + typedef E exact_t; + E& exact() { return *(E*)(void*)this; } Index: metalic/mlc/case.hh --- metalic/mlc/case.hh (revision 485) +++ metalic/mlc/case.hh (working copy) @@ -264,9 +264,15 @@ \ { \ typedef NAMESPACE::default_case_<context, data> case_t; \ + typedef typename protected_in_<case_t>::the protected_case_t; \ + \ + typedef typename mlc::if_< mlc::is_found_<protected_case_t>, \ + protected_case_t, \ + case_t >::ret eff_case_t; \ + \ typedef typename mlc::if_<mlc_is_a(case_t, mlc::undefined), \ mlc::none, \ - case_t>::ret ret; \ + eff_case_t>::ret ret; \ }; \ \ \ @@ -339,27 +345,7 @@ mlc::where_), \ mlc_is_a(mlc_comma_2(NAMESPACE::case_<context, data, i>), \ mlc::undefined) >, \ - mlc::ERROR::A_case_STATEMENT_SHOULD_DERIVE_FROM_mlc_where_ >, \ - \ - private mlc::assert_< mlc::implies_< mlc::and_< mlc::eq_<use, mlc::internal::a_switch_case>, \ - mlc::is_defined_< NAMESPACE::case_<context, data, i> > >, \ - mlc::or_< mlc::ret_found_in_< NAMESPACE::case_<context, data, i> >, \ - typename protected_in_< NAMESPACE::case_<context, data, i> >::is_found > >, \ - mlc::ERROR::A_case_STATEMENT_IN_A_switch_SHOULD_HAVE_EITHER_A_ret_OR_A_protected >, \ - \ - private mlc::assert_< mlc::implies_< mlc::and_list_< mlc::eq_<use, mlc::internal::a_switch_case>, \ - mlc::is_defined_< NAMESPACE::case_<context, data, i> >, \ - mlc::or_< mlc::ret_found_in_< NAMESPACE::case_<context, data, i> >, \ - typename protected_in_< NAMESPACE::case_<context, data, i> >::is_found > >, \ - mlc::xor_< mlc::ret_found_in_< NAMESPACE::case_<context, data, i> >, \ - typename protected_in_< NAMESPACE::case_<context, data, i> >::is_found > >, \ - mlc::ERROR::A_case_STATEMENT_IN_A_switch_SHOULD_NOT_HAVE_BOTH_A_ret_AND_A_protected >, \ - \ - private mlc::assert_< mlc::implies_< mlc::and_list_< mlc::eq_<use, mlc::internal::a_switch_case>, \ - mlc::is_defined_< NAMESPACE::case_<context, data, i> >, \ - typename protected_in_< NAMESPACE::case_<context, data, i> >::is_found >, \ - typename protected_in_< NAMESPACE::case_<context, data, i> >::is_found_with_ret >, \ - mlc::ERROR::THE_protected_PART_OF_A_case_STATEMENT_IN_A_switch_SHOULD_HAVE_A_ret > \ + mlc::ERROR::A_case_STATEMENT_SHOULD_DERIVE_FROM_mlc_where_ > \ { \ typedef mlc_is_a(mlc_comma_2(NAMESPACE::case_<context, data, i+1>), \ mlc::case_selected) next_case_is_selected; \
Thomas Moulard thomas.moulard@lrde.epita.fr writes:
https://svn.lrde.epita.fr/svn/oln/trunk
Index: ChangeLog from Thomas Moulard thomas.moulard@lrde.epita.fr
Add stc::exact.
- static/tests/exact.cc: test suite of stc::exact (new file).
- static/stc/exact.hh: implementation of stc::exact (new file).
- static/stc/any.hh: adding a typedef exact_t in stc::any.
- metalic/mlc/case.hh: fixing a bug in the protected defaults cases.
Nice work for a first patch!
However, there were some (small) mistakes; don't worry, this is normal in the first contributions to a project. (You won't need to send a correction, I've fixed them since).
First of all, the ChangeLog. All subprojects of Olena (Metalic, Static, Extended, Olena, Dynamic) have their own ChangeLog. You should write your changes in the one at the root of your subproject. When you make changes across several subprojects (e.g., moving a file form mlc/ to xtd/), document your changes in the top-level ChangeLog.
And don't forget to start your ChangeLog entries with a capital letter, and to use imperative (``Add a typedef'', not ``adding a typedef'').
Index: static/tests/exact.cc --- static/tests/exact.cc (revision 0) +++ static/tests/exact.cc (revision 0) @@ -0,0 +1,161 @@ +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 EPITA Research and +// Development Laboratory.
Take care when copying copyright headers; there are two recurring mistakes: - erroneous years; - using the old address of the FSF (59 Temple Place) instead of their current one (51 Franklin Street).
Here, you should have mentioned 2006 only, since you created this file a few days ago.
+#include <iostream> +#include <exact.hh> // FIXME: was stc/exact.hh
All header inclusions must be relative to the subproject root (in this case, static/).
Tests are run through the `check' rule by make. When you add a test case, don't forget to update the tests/Makefile.am of the corresponding project.
Property changes on: static/tests/exact.cc ___________________________________________________________________ Name: svn:executable
Source file shall not be executable. :)
Index: static/stc/exact.hh --- static/stc/exact.hh (revision 0) +++ static/stc/exact.hh (revision 0) @@ -0,0 +1,198 @@ +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 EPITA Research and +// Development Laboratory.
Likewise for dates.
+# define stc_internal_is_any(T) \ +mlc::bexpr_< sizeof(internal::any_select(internal::makePtr< T >())) +== sizeof(internal::yes_) >
If possible, avoid lines longer than 80 columns.
+namespace stc +{
- namespace internal
- {
- typedef char yes_;
- struct no_ { char dummy[2]; };
- template <typename E, typename P>
- yes_ any_select(const stc::any<E,P>* arg);
- no_ any_select(...);
- template <typename T>
- T* makePtr();
- }
- template <typename T>
- struct is_any_
- : public stc_internal_is_any(T)
- {
- };
- template <typename T>
- struct is_any_ < T* >;
- template <typename T>
- struct is_any_ < const T >;
+} // end of namespace stc
+mlc_case_equipment_for_namespace(stc);
+namespace stc +{
- namespace tag
- {
- struct exact;
- }
- template <class T>
- struct case_<tag::exact, T, 1> : public mlc::where_ < stc::is_any_<T> >
- {
- struct protected_
- {
typedef typename T::exact_t ret;
static inline ret& impl(T& t)
This `inline' is probably superfluous: IIRC, methods whose definition is given at the same time as their declaration (i.e., inside the class definition) are automatically qualified inline.
Property changes on: static/stc/exact.hh ___________________________________________________________________ Name: svn:executable
Same as above.
Index: static/stc/any.hh --- static/stc/any.hh (revision 485) +++ static/stc/any.hh (working copy) @@ -67,6 +67,8 @@ struct any <E, dispatch_policy::best_speed> {
- typedef E exact_t;
exact_type is preferred to exact_t; the Olena coding style says: ``xxx_t looks too close from the std::*_t reserved types '' (http://www.lrde.epita.fr/cgi-bin/twiki/view/Olena/CodingStyle).
Thanks for your patch!