
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; \