https://svn.lrde.epita.fr/svn/oln/trunk
Index: ChangeLog
from Thomas Moulard <thomas.moulard(a)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; \