https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
Index: ChangeLog
from Thierry Géraud <thierry.geraud(a)lrde.epita.fr>
Huge summer cleanup.
Part 0: New metal stuff for use in proxy-related meta-programs.
----------------------------------------------------------------
* mln/metal/unqualif.hh (todo): New.
* mln/metal/const.hh (const_): New overloads for pointers.
* mln/metal/is_a.hh (is_a): New overload to handle & and const&.
(make_): Likewise.
* mln/metal/is.hh (is): New overload to handle constness.
* mln/metal/unref.hh (unref): New overload to handle const&.
* mln/metal/is_not_ref.hh: New.
* mln/metal/is_ref.hh: New.
* mln/metal/ref.hh: New.
Part I: Cleanup traits.
------------------------
Reduce dependencies between trait structures and the solving
meta-programs. Forward declarations of the latter are included
before the definition of trait structures and meta-programs are
eventually included at EOF.
* mln/trait/op/decl.hh: New. Forward declare the couple of
solving meta-programs.
* mln/trait/op/leq.hh,
* mln/trait/op/times.hh,
* mln/trait/op/div.hh,
* mln/trait/op/plus.hh,
* mln/trait/op/neq.hh,
* mln/trait/op/greater.hh,
* mln/trait/op/minus.hh,
* mln/trait/op/not.hh,
* mln/trait/op/postdec.hh,
* mln/trait/op/predec.hh,
* mln/trait/op/and.hh,
* mln/trait/op/eq.hh,
* mln/trait/op/less.hh,
* mln/trait/op/xor.hh,
* mln/trait/op/uplus.hh,
* mln/trait/op/geq.hh,
* mln/trait/op/mod.hh,
* mln/trait/op/postinc.hh,
* mln/trait/op/preinc.hh,
* mln/trait/op/uminus.hh,
* mln/trait/op/or.hh: Update.
Group category materials in the same file.
* mln/trait/solve.hh (super_category_): Move...
* mln/category.hh: ...here.
Consequently mln::trait::internal::super_category_ is now
mln::internal::super_category_.
Allow the category associated type to hold extra information. In
particular we need for proxy to carry the super category
information. For that, in meta-programs, it is now used as a
'regular' type (no more as a meta-type), e.g., we propagate
'Image<void>' as a parameter in meta-programs instead of 'Image'.
In the case of multiple possible super categories, for instance
for builtin types, we have 'Category<Super_Category>'.
* mln/trait/solve_unary.hh (trait_set_unary_): New. This
structure removes the parameter of the category to access the
definition of trait::set_unary_.
(Category_T): Replace in meta-code this meta-class parameter by...
(Category): ...this class parameter.
* mln/trait/solve_binary.hh: Likewise.
* tests/trait/super.cc,
* mln/value/builtin/symbolics.hh,
* mln/value/builtin/floatings.hh,
* mln/value/builtin/integers.hh: Update.
PART II. Make the default coordinate type easily changeable.
-------------------------------------------------------------
Introduce a one-place definition of the default coordinate used in
point2d and related classes. This definition is changed from
"int" to "short int" to save memory when containers of coordinates
are involved.
* mln/core/def: New directory for definitions.
* mln/core/def/coord.hh: New.
* mln/core/dpoint.hh,
* mln/core/point.hh: Include this new file.
* mln/core/dpoint2d.hh,
* mln/core/point1d.hh,
* mln/core/point2d.hh,
* mln/core/point3d.hh,
* mln/make/box3d.hh,
* mln/make/dpoint1d.hh,
* mln/make/dpoint2d.hh,
* mln/make/dpoint3d.hh,
* mln/make/box1d.hh,
* mln/make/box2d.hh,
* mln/make/box3d.hh,
* mln/make/point1d.hh,
* mln/make/point2d.hh,
* mln/make/point3d.hh,
* mln/trait/image/props.hh (int): Replace by...
(def::coord): ...this.
PART III. Make the proxy mechanism more powerful.
--------------------------------------------------
The proxy mechanism can now handle the several cases in the nature
of the subject:
- with type "T", the subject is a temporary object or an object
copy;
- with type "T&", the subject is modifiable through a non-const
proxy;
- with type "const T&", the subject is handle by reference (not
copied) yet it is never modifiable.
The "unproxy()" method is split into:
- unproxy_() [const]
These methods are automatically inherited thru internal::proxy_impl.
The '_' suffix emphasizes their technical-detail (non-user) nature.
- subj_()
This method has to be defined in proxy concrete classes. It
shall return the immediate subject of the proxy. This not-const
method is unique. A proper "unproxy_() const" method is defined
from it.
The "subject" typedef is replaced by "q_subject" which is
qualified (so that the proxy mechanism can handle different cases
described above). This typedef is no more defined explicitly by
the client, it is automatically set thanks to inheritance with the
first parameter of the internal::proxy_impl class.
* mln/core/concept/proxy.hh (unproxy): Replace this const method
by...
(subj_): ...this mutable one.
(subject): Remove this typedef.
(FIXME): Fix'n remove.
(subject, unproxy_rec): New external material to access the actual
subject type and object. If we have a proxy to a proxy, that is, a
recursive construction, the subject at end is returned.
* mln/core/macros.hh (mln_q_subject): New.
(mln_subject): Deactivate for safety purpose. The user should not
have to access the actual subject type.
Recap:
- P::q_subject is the qualified immediate subject
(that may be itself a proxy type)
v.
- subject<P> is the subject type at end
(it cannot be a proxy type)
- p.subject_() gives the immediate subject object
(which may be a proxy object)
v.
- unproxy_rec(p) gives the subject object at end
(it cannot be a proxy object).
* mln/core/concept/proxy.hh
(Proxy): Update ctor to perform the proper checks.
(unproxy_couple): Rename as...
(helper_unproxy_binop): ...this.
(mln_def_binop_proxy, operator, set_unary_, set_binary_): Update.
(internal): Move material into...
* mln/core/concept/proxy.hxx: ...this new file.
(helper_subject_of, helper_unproxy_rec, helper_get_proxy_impl):
New helpers to handle the different cases.
Proxies are automatically equipped with some new material:
* mln/core/concept/proxy.hxx:
(q_subject, unproxy_): New in proxy_impl.
(HOT_actual_subject, get_subject): New in helper_get_proxy_impl
when recursion ends, that is, when the subject is no more a proxy.
(subject_impl): New structure to be specialized (see below).
IMPORTANT:
For a proxy to look like an actual subject, it shall have the
interface of the later. For that, the "subject_impl"
parameterized structure has to be specialized. See
mln/core/point2d.hh for an example.
Consequently to the modifications of the proxy mechanism, some
pieces of code are now obsolete:
* mln/accu/internal/base.hh (q_subject, subject, unproxy): Remove.
(subj_): New.
(base_): Pass the qualified R type as parameter to proxy_impl.
* mln/core/concept/site_proxy.hh (internal): Remove. We can now
use the default material for all proxies.
* mln/core/internal/pseudo_site_base.hh (is_mutable): Remove this
parameter. It is now obsolete since the immediate subject type is
qualified, namely the parameter P.
(subject, q_subject): Remove.
(site): Update. It now relies on proxy material.
(to_site): New method. It is now final thanks to get_subject().
* mln/core/internal/site_relative_iterator_base.hh
(unproxy): Replace by...
(subj_): ...this.
* mln/core/internal/site_iterator_base.hh: Likewise.
(site_impl): Remove this obsolete inheritance. Now the
implementation is offered by the proxy mechanism.
(operator site, to_site): Update; use get_subject.
* mln/core/point2d.hh (site_const_impl, site_impl): Replace by...
(subject_impl): ...these.
Last.
* doc/tutorial/examples/proxy.cc: New.
PART IV. Add some utility code.
--------------------------------
The main idea is to provide iterators for util::set and
util::array so that such structures can be involved in some site
set types with a common interface. In particular, they can be
used by the new material of mln/core/p_double.hh
Finalize the util::set class. It is now fully functional. A
major improvement is that the method ".has()" does no more require
that the data are unfrozen.
* mln/util/set.hh (set_fwd_iter, set_bkd_iter): New classes.
(fwd_iter, bkd_iter, iter): New typedefs.
(first_element, last_element, memory_size): New.
(is_frozen_): New. Hum... we should think of adding a public
freeze method.
(has): Now work when the set is frozen thanks to...
(v_has_, dicho_): ...these new private methods.
(insert): New overload with a set as argument.
(remove): New method.
(todo): Remove; done.
(todo): New.
(documentation): Layout.
(vect): Rename this method as...
(std_vector): ...this more explicit name.
(operator<<): Change the output.
A new class, util::array, is introduce. It is nearly a regular
dynamic array expect that it will provide a remove-element method
with O(1) complexity. This feature is not yet implemented (see
the todo).
* mln/util/array.hh: New.
Misc.
* mln/core/contract.hh (mln_implies): Replace this macro by...
(implies): ...this routine. Nota: the macro did not work!
* mln/core/macros.hh
(mln_bkd_iter, mln_fwd_iter, mln_iter): New.
(mln_element): New.
* mln/fun/v2v/inc.hh: New.
* mln/fun/v2v/dec.hh: New.
* mln/util/index.hh (operator++, operator--): New.
(todo): New.
* mln/util/timer.hh: New.
* mln/util/yes.hh (operator==, operator!=): New overloads.
* mln/util/less.hh (op_less, op_less_or_equal): New.
* mln/value/viter.hh (change_target, index_): New.
(fwd_viter_, bkd_viter_): New overload ctor without argument.
PART V. Cleanup site set definitions.
--------------------------------------
A lot of work here has been done to FACTOR (!) code and make it
safer.
First add a re-target feature to pseudo sites.
* mln/core/concept/pseudo_site.hh (target_t): Rename this typedef
as...
(target): ...this.
(target_, change_target): New methods expected in concrete
classes.
(has_target): New final method.
(if_possible::change_target): Update.
* mln/core/macros.hh (mln_target_): New.
Add some methods in the site set interface.
* mln/core/concept/site_set.hh (is_valid): New method. Some site
set types are always valid, some others can sometimes be
invalid (think of an initialized box!)
(memory_size): New.
(i_element, insert): New methods expected by site sets with
"dynamic contents".
(r_element, remove): New methods expected by site sets with "free
contents". Nota bene: having a "growing contents" means that no
removal is possible.
(q_box): New typedef expected by site sets knowing their bounding
box.
(bbox): Turn this method into optional.
(internal): New material to check the presence of methods that
some site sets feature.
(Site_Set): Use this material to check the presence of the nsites,
bbox, insert, and remove methods.
(todo): Remove; done.
* mln/accu/bbox.hh (box_): Update to...
(box): ...the new class name.
(take): Rely on is_valid instead of nsites.
* mln/core/box.hh,
* mln/core/p_queue_fast.hh,
* mln/core/p_priority_queue.hh,
* mln/core/p_set.hh,
* mln/core/line2d.hh,
* mln/core/p_run.hh,
* mln/core/p_run_piter.hh,
* mln/core/p_array.hh,
* mln/core/p_runs.hh: Update.
* mln/core/concept/box.hh (q_box): New typedef.
(nsites): Handle the case of a non-initialized box.
* doc/tutorial/examples/cpp_issue.cc: New. It illustrates the
impossibility of having a "typedef box" (and thus a method having
for signature "box bbox() const") due to the type "box<P>".
Some site set types are indexed (featuring an operator[]). The
triplet of psite, fwd_piter, and bkd_piter is factored for such
types. It is the case for:
- p_array<P>
- p_set<P>
- line2d.
* mln/core/p_array.hh (p_array_psite): Rename as...
(p_indexed_psite): ...this and update.
(p_indexed_fwd_piter, p_indexed_bkd_piter): New iterators.
(psite, fwd_piter, bkd_piter): Update.
(trait): Update.
(element, piter, i_element): New typedefs.
(has_index): Remove; replace by...
(has): ...this overload with util::index.
(operator[]): New overload with util::index.
(vect): Rename as...
(std_vector): ...this.
(memory_size, hook_std_vector_): New.
* mln/core/p_set.hh: Likewise.
(p_set): Change inheritance (remove dependency on set_of_) into
delegation with...
(s_): ...this new attribute whose type is util::set.
(remove): Re-activate and make it work.
(bb_, bbox): Remove because it is too costly to maintain.
* mln/core/p_array_piter.hh: Obsolete changes.
* mln/core/line2d.hh
(vect_): Change this attribute to...
(arr_): ...this new one with type being a p_array.
(beg_, end_): Remove those useless attributes.
(begin, end, bbox): New methods.
(line2d): Update like previous site set types.
* doc/tutorial/examples/line2d.cc: New.
Re-vamp the p_queue_fast so that it completely relies on p_array.
* mln/core/p_queue_fast.hh (include): Remove about all
includes (useless!). Add p_array.hh.
(trait): Update.
(element, psite, piter): New typedefs.
(fwd_piter, bkd_piter): Now use the indexed iterators.
(has): Replace by...
(compute_has): ...this re-written method.
(has): Now take a psite (!)
(npoints, vect): Rename as...
(nsites, std_vector): ...these.
(bbox, push_force, is_empty): Remove.
(i_element, insert, purge, memory_size): New.
(bb_, vect_needs_update_): Remove. They are useless since:
(q_): Change type from std::vector to p_array.
(begin_, end_): Change type from std::size_t to unsigned.
(operator[]): New.
(p_queue_fast, reserve, clear, pop, push): Re-write.
(pop_front): Fix missing precondition.
Completely re-write the priority queue class so that this class is
unique. Put differently we had three classes:
- p_priority_queue
- p_priority_queue_fast
- p_priority_queue_fast_with_array
and now we have one factored class:
- p_priority!
Yet this class does not handle a bounding box (to be implemented).
* mln/core/p_priority_queue.hh (p_priority_queue): Rename as...
(p_priority): ...this.
Re-write completely and update; noticeable changes are:
(T): Replace this element-type parameter by...
(Q): ...this new parameter; it is the queue-type.
(bbox, operator[], push_force): Remove these methods.
(insert): New method.
(exists_priority, operator()): New methods.
(lowest_priority, highest_priority): New methods.
* doc/tutorial/examples/p_queue.cc: New. Illustrate what can be
done with both p_queue_fast and p_priority_queue.
About site sets based on runs, cleanup and speedup code.
A couple of important remarks:
- p_run<P> does not rely on p_indexed stuff because the dedicated
code is more efficient; just think of calling .next() and
computing the i-th point (slow) instead of just
inc/dec-rementing the last coordinate (fast).
- p_runs<P> is a transition class between has-been code and
will-be code; it will be automatically replaced by composite
site set types s.a. p_array_of< p_run<P> >.
* mln/core/p_run.hh: Update like previous site set types.
(set_run): Rename this method as...
(init): ...this. It is now consistent with other lib types.
(p_): Rename this attribute as...
(start_): ...this more explicit name.
(first): Rename this method as...
(start): ...this.
(end): New method.
(bb_): Remove this attribute since it is easily and efficiently
computable.
(is_valid_): Likewise.
(bbox): Update; now return by copy.
(std::size_t): Change this type of length into...
(unsigned short): ...this sufficient type.
(util::less): New specialization.
(psite, piter): New typedefs.
(p_run_psite): New. There was no psite for p_run! Instead a type
of point was used so there was no very efficient ".has(p)"
method...
(has): Overload for psite. It is quick :-)
* mln/core/p_run_piter.hh: Update.
(assign_run, to_point, operator[], ind, operator P): Remove; now
obsolete because factored in super classes.
(i_, p_, run_, is_valid_): Likewise for these attributes.
* mln/core/p_runs.hh (p_runs): Rename as...
(p_run_set): ...this.
(fwd_piter, bkd_piter): Use p_double stuff; see below.
Update the full class file. Nota bene: this class will be soon
obsolete! Yet to bench the difference after changes we keep track
of an up-to-date version:
* sandbox/geraud/p_runs__with_dedicated_piter.hh: Copy of previous
code to bench purpose.
* doc/benchmark/p_runs.cc: New.
* doc/tutorial/examples/p_run_set.cc: New.
* mln/convert/to_p_run_set.hh: New.
Add composite site set types, meaning types for "composites of
site sets". For instance, a dynamic array of site sets or a
mathematical set of site sets.
* mln/core/p_double.hh: New.
* mln/core/p_mutable_array_of.hh: New.
* mln/core/p_set_of.hh: New.
* doc/tutorial/examples/p_mutable_array_of.cc: New.
New site set types that are value-oriented.
* mln/core/p_vaccess.hh: New.
* mln/core/obsolete_p_vaccess.hh: New.
* mln/core/p_key.hh: New.
* doc/tutorial/examples/p_vaccess.cc: New.
* doc/tutorial/examples/p_key.cc: New.
* doc/tutorial/examples/p_key.2.cc: New.
Misc.
* mln/core/p_queue.hh (npoints): Rename as...
(nsites): ...this.
(is_empty): Remove; obsolete.
* mln/core/internal/site_set_base.hh
(is_empty): New method; it dispatches to is_empty_.
(is_empty_): New default implementation based on the nsites
method. This method has to be overridden by sub-classes that can
test their emptiness though they do not feature the nsites method.
* mln/core/concept/site_set.hh (insert_all): Replace this method by...
(operator+=): ...this external operator and add static checks.
* doc/tutorial/examples/image2d.cc,
* doc/tutorial/examples/window.cc: Update.
* mln/trait/site_set/props.hh (todo): New.
(contents::free): Fix typo in return of the name() method.
Last.
* mln/trait/site_set/status.txt: Layout and update. That is THE
reference file to know the work done v. remaining to be done on
site sets.
PART VI. Some work on image types.
-----------------------------------
Cleanup the internal classes.
* mln/core/internal/data.hh (todo): New.
* mln/core/internal/image_base.hh (morpher_lvalue_): Move into...
* mln/core/internal/morpher_lvalue.hh: ...this new file.
* mln/core/internal/check/image_all.hh: Typo.
* mln/core/internal/check/image_fastest.hh (ctor): Fix a missing
static check.
* mln/core/internal/image_identity.hh
(image_identity_impl__fastest, image_identity_impl): New.
Actually this new code should be located elsewhere.
Bench image2d and compare iterations with different
implementations.
* mln/core/point.hh (operator[]): Change return from "C" to "const
C&".
(last_coord): New.
(plus_infty, minus_infty): New.
(cut_): New.
* mln/core/internal/coord_impl.hh
(ind, row, col, sli): Change return from "C" to "const C&".
* mln/core/window.hh: Update.
* mln/core/box_piter.hh (next_): Speedup a bit.
* mln/core/image2d.hh (alt): New temporary method to bench purpose.
* doc/benchmark/image2d.cc: New.
First attempt to deal with temporary mutable morphers.
* mln/core/image: New directory.
* mln/core/image/all.hh,
* mln/core/image/instant.hh: New files.
* mln/core/sub_image.hh (operator|): New overload for instant
images.
* mln/level/fill_with_value.hh (fill_with_value): Likewsie.
* doc/tutorial/examples/sub_image.cc: Use fill_with_value to show
that instant morphers can be mutable.
Start to update p_run-based image types.
* mln/core/sparse_image.hh: Update using p_run_set<P>.
Misc.
* mln/core/plain.hh (include): Remove useless dependence on
algebra::vec.
* mln/pw/image.hh (speed): Fix wrong property.
PART VII. What is not in previous parts.
-----------------------------------------
* doc/tutorial/examples/p_array.cc: Replace some dynamic
assertions by static checks.
* mln/core/concept/gdpoint.hh (todo): New.
* mln/core/internal/piter_adaptor.hh
(pi_change_target_): New default implementation.
(pi_set_from_): Remove this method expected in subclasses.
(change_target): Call pi_change_target_.
* mln/core/pset_if_piter.hh: Update.
* mln/debug/put_word.hh: New.
* mln/debug/println.hh (todo): New.
* mln/debug/println.spe.hh (todo): New.
(println): Revamp 2D version so it can work on a wider set of
images. It no longer relies on the "at(row,col)" method.
(println): Overload for image2d<char>.
* mln/geom/bbox.hh (bbox_): Fix signature.
* mln/labeling/blobs.hh (unsigned): Replace its use by...
(L): ...this parameter. That is a feature bug fix!
* mln/morpho/internal: New.
* mln/morpho/internal/elementary.hh: New.
* mln/morpho/gradient_elementary.hh: Use new stuff.
* mln/morpho/dilation_elementary.hh: Add temporary code.
doc/benchmark/image2d.cc | 152 ++++
doc/benchmark/p_runs.cc | 54 +
doc/tutorial/examples/accu.cc | 1
doc/tutorial/examples/cpp_issue.cc | 29
doc/tutorial/examples/image2d.cc | 2
doc/tutorial/examples/line2d.cc | 46 +
doc/tutorial/examples/p_array.cc | 9
doc/tutorial/examples/p_key.2.cc | 34
doc/tutorial/examples/p_key.cc | 94 ++
doc/tutorial/examples/p_mutable_array_of.cc | 80 ++
doc/tutorial/examples/p_queue.cc | 70 ++
doc/tutorial/examples/p_run_set.cc | 45 +
doc/tutorial/examples/p_vaccess.cc | 90 ++
doc/tutorial/examples/proxy.cc | 107 +++
doc/tutorial/examples/sub_image.cc | 11
doc/tutorial/examples/window.cc | 2
mln/accu/bbox.hh | 30
mln/accu/internal/base.hh | 16
mln/convert/to_p_run_set.hh | 138 +++
mln/core/box.hh | 26
mln/core/box_piter.hh | 23
mln/core/category.hh | 44 +
mln/core/concept/accumulator.hh | 1
mln/core/concept/box.hh | 15
mln/core/concept/gdpoint.hh | 2
mln/core/concept/proxy.hh | 221 +-----
mln/core/concept/proxy.hxx | 453 ++++++++++++
mln/core/concept/pseudo_site.hh | 55 -
mln/core/concept/site_proxy.hh | 111 ---
mln/core/concept/site_set.hh | 130 +++
mln/core/contract.hh | 20
mln/core/def/coord.hh | 53 +
mln/core/dpoint.hh | 1
mln/core/dpoint2d.hh | 3
mln/core/image/all.hh | 43 +
mln/core/image/instant.hh | 155 ++++
mln/core/image2d.hh | 22
mln/core/internal/check/image_all.hh | 5
mln/core/internal/check/image_fastest.hh | 3
mln/core/internal/coord_impl.hh | 50 -
mln/core/internal/data.hh | 2
mln/core/internal/image_base.hh | 26
mln/core/internal/image_identity.hh | 84 ++
mln/core/internal/morpher_lvalue.hh | 64 +
mln/core/internal/piter_adaptor.hh | 13
mln/core/internal/pseudo_site_base.hh | 34
mln/core/internal/site_iterator_base.hh | 29
mln/core/internal/site_relative_iterator_base.hh | 4
mln/core/internal/site_set_base.hh | 38 -
mln/core/line2d.hh | 222 ++++--
mln/core/macros.hh | 46 +
mln/core/obsolete_p_vaccess.hh | 803 +++++++++++++++++++++++
mln/core/p_array.hh | 591 ++++++++++++----
mln/core/p_array_piter.hh | 31
mln/core/p_double.hh | 309 ++++++++
mln/core/p_key.hh | 652 ++++++++++++++++++
mln/core/p_mutable_array_of.hh | 251 +++++++
mln/core/p_priority_queue.hh | 477 +++++++------
mln/core/p_queue.hh | 25
mln/core/p_queue_fast.hh | 247 +++----
mln/core/p_run.hh | 424 ++++++++++--
mln/core/p_run_piter.hh | 229 +-----
mln/core/p_runs.hh | 619 ++++++-----------
mln/core/p_set.hh | 199 ++++-
mln/core/p_set_of.hh | 237 ++++++
mln/core/p_vaccess.hh | 412 +++++++++++
mln/core/plain.hh | 5
mln/core/point.hh | 83 ++
mln/core/point1d.hh | 4
mln/core/point2d.hh | 90 +-
mln/core/point3d.hh | 4
mln/core/pset_if_piter.hh | 10
mln/core/sparse_image.hh | 169 ++--
mln/core/sub_image.hh | 37 -
mln/core/window.hh | 2
mln/debug/println.hh | 2
mln/debug/println.spe.hh | 60 +
mln/debug/put_word.hh | 84 ++
mln/fun/v2v/dec.hh | 78 ++
mln/fun/v2v/inc.hh | 78 ++
mln/geom/bbox.hh | 2
mln/labeling/blobs.hh | 33
mln/level/fill_with_value.hh | 14
mln/make/box1d.hh | 12
mln/make/box2d.hh | 10
mln/make/box3d.hh | 30
mln/make/dpoint1d.hh | 6
mln/make/dpoint2d.hh | 6
mln/make/dpoint3d.hh | 6
mln/make/point1d.hh | 6
mln/make/point2d.hh | 6
mln/make/point3d.hh | 6
mln/metal/const.hh | 21
mln/metal/is.hh | 6
mln/metal/is_a.hh | 16
mln/metal/is_not_ref.hh | 66 +
mln/metal/is_ref.hh | 66 +
mln/metal/ref.hh | 64 +
mln/metal/unqualif.hh | 2
mln/metal/unref.hh | 9
mln/morpho/dilation_elementary.hh | 133 +++
mln/morpho/gradient_elementary.hh | 23
mln/morpho/internal/elementary.hh | 117 +++
mln/pw/image.hh | 2
mln/trait/ch_value.hh | 8
mln/trait/image/props.hh | 10
mln/trait/image/status.txt | 76 +-
mln/trait/op/and.hh | 8
mln/trait/op/decl.hh | 62 +
mln/trait/op/div.hh | 7
mln/trait/op/eq.hh | 7
mln/trait/op/geq.hh | 7
mln/trait/op/greater.hh | 7
mln/trait/op/leq.hh | 7
mln/trait/op/less.hh | 7
mln/trait/op/minus.hh | 7
mln/trait/op/mod.hh | 7
mln/trait/op/neq.hh | 7
mln/trait/op/not.hh | 7
mln/trait/op/or.hh | 7
mln/trait/op/plus.hh | 7
mln/trait/op/postdec.hh | 7
mln/trait/op/postinc.hh | 7
mln/trait/op/predec.hh | 7
mln/trait/op/preinc.hh | 7
mln/trait/op/times.hh | 7
mln/trait/op/uminus.hh | 8
mln/trait/op/uplus.hh | 7
mln/trait/op/xor.hh | 7
mln/trait/site_set/props.hh | 5
mln/trait/site_set/status.txt | 58 +
mln/trait/solve.hh | 38 -
mln/trait/solve_binary.hh | 113 +--
mln/trait/solve_unary.hh | 91 +-
mln/util/array.hh | 559 ++++++++++++++++
mln/util/index.hh | 29
mln/util/less.hh | 37 +
mln/util/set.hh | 431 +++++++++++-
mln/util/timer.hh | 181 +++++
mln/util/yes.hh | 20
mln/value/builtin/floatings.hh | 8
mln/value/builtin/integers.hh | 18
mln/value/builtin/symbolics.hh | 5
mln/value/viter.hh | 112 ++-
sandbox/geraud/p_runs__with_dedicated_piter.hh | 748 +++++++++++++++++++++
tests/trait/super.cc | 6
146 files changed, 10376 insertions(+), 2270 deletions(-)
Index: tests/trait/super.cc
--- tests/trait/super.cc (revision 2153)
+++ tests/trait/super.cc (working copy)
@@ -112,15 +112,13 @@
template <>
struct category< my::test >
{
- typedef my::Built_In<void> ret;
- typedef my::Integer<void> super;
+ typedef my::Built_In< my::Integer<void> > ret;
};
// template <>
// struct category< int >
// {
-// typedef my::Built_In<void> ret;
-// typedef my::Integer<void> super;
+// typedef my::Built_In< my::Integer<void> > ret;
// };
namespace trait
Index: doc/tutorial/examples/sub_image.cc
--- doc/tutorial/examples/sub_image.cc (revision 2153)
+++ doc/tutorial/examples/sub_image.cc (working copy)
@@ -6,6 +6,7 @@
# include <mln/debug/println.hh>
# include <mln/morpho/gradient_elementary.hh>
+# include <mln/level/fill_with_value.hh>
int main()
@@ -17,9 +18,17 @@
debug::iota(ima);
debug::println(ima);
- sub_image<I, box2d> sub(ima, box2d(2,3));
+ sub_image<I, box2d> sub = ima | box2d(2,3);
debug::println(sub);
debug::println(morpho::gradient_elementary(sub, c4()));
+ level::fill_with_value(ima | box2d(2,3), 0);
+ debug::println(ima);
+
trait::image::print(sub);
+
+
+ {
+ instant_<I> tmp(ima);
+ }
}
Index: doc/tutorial/examples/p_array.cc
--- doc/tutorial/examples/p_array.cc (revision 2153)
+++ doc/tutorial/examples/p_array.cc (working copy)
@@ -29,11 +29,12 @@
typedef p_array<point2d> Arr1;
typedef p_array<mln_psite_(Arr1)> Arr2;
+
{
- mln_assertion(mln_psite_(Arr1)::proxy_level == 1);
- mln_assertion(mln_piter_(Arr1)::proxy_level == 2);
- mln_assertion(mln_psite_(Arr2)::proxy_level == 2);
- mln_assertion(mln_piter_(Arr2)::proxy_level == 3);
+ mlc_bool(mln_psite_(Arr1)::proxy_level == 1)::check();
+ mlc_bool(mln_piter_(Arr1)::proxy_level == 2)::check();
+ mlc_bool(mln_psite_(Arr2)::proxy_level == 2)::check();
+ mlc_bool(mln_piter_(Arr2)::proxy_level == 3)::check();
}
Arr1 arr1;
Index: doc/tutorial/examples/p_run_set.cc
--- doc/tutorial/examples/p_run_set.cc (revision 0)
+++ doc/tutorial/examples/p_run_set.cc (revision 0)
@@ -0,0 +1,45 @@
+# include <mln/core/image2d.hh>
+# include <mln/debug/println.hh>
+# include <mln/convert/to_p_run_set.hh>
+
+# include <mln/core/sparse_image.hh>
+
+
+template <typename I>
+void display(I& ima)
+{
+ mln_fwd_piter(I) p(ima.domain());
+ unsigned i = 0;
+ for_all(p)
+ ima(p) = i++;
+ mln::debug::println(ima);
+}
+
+
+int main()
+{
+ using namespace mln;
+
+ typedef p_run_set<point2d> Runs;
+
+ bool vals[6][5] = {
+ {1, 1, 1, 1, 1},
+ {0, 0, 0, 0, 0},
+ {1, 0, 1, 0, 1},
+ {0, 1, 0, 1, 0},
+ {0, 0, 1, 1, 1},
+ {1, 1, 1, 0, 0}
+ };
+ image2d<bool> ima = make::image2d(vals);
+ debug::println(ima);
+
+ Runs rs = convert::to_p_run_set(ima);
+ std::cout << rs << std::endl;
+
+ mln_assertion(rs.nruns() == 8);
+ mln_assertion(rs.nsites() == 16);
+ mln_assertion(rs.zratio() < 1);
+
+ sparse_image<point2d,int> ima_(rs);
+ display(ima_);
+}
Index: doc/tutorial/examples/p_queue.cc
--- doc/tutorial/examples/p_queue.cc (revision 0)
+++ doc/tutorial/examples/p_queue.cc (revision 0)
@@ -0,0 +1,70 @@
+# include <mln/core/image2d.hh>
+# include <mln/core/p_queue_fast.hh>
+# include <mln/debug/println.hh>
+# include <mln/level/fill.hh>
+
+# include <mln/core/p_priority_queue.hh>
+
+
+
+template <typename S>
+void picture(const S& s)
+{
+ using namespace mln;
+
+ image2d<char> ima(5, 5);
+ level::fill(ima, '-');
+
+ unsigned i = 0;
+ mln_piter(S) p(s);
+ for_all(p)
+ ima(p) = '0' + i++;
+
+ debug::println(ima);
+}
+
+
+
+int main()
+{
+ using namespace mln;
+
+ typedef p_queue_fast<point2d> Q;
+ Q q;
+
+ {
+ point2d p(1,1);
+ q.push(p);
+ dpoint2d dp[] = { right, right, down, down, left, left, up };
+ for (unsigned i = 0; i < 7; ++i)
+ p += dp[i], q.push(p);
+ }
+
+ picture(q);
+ q.pop();
+ picture(q);
+
+ {
+ Q::psite p(q, 0);
+ mln_assertion(q.has(p));
+ p.change_index(6);
+ mln_assertion(q.has(p));
+
+ p.change_index(7);
+ mln_assertion(! q.has(p));
+ }
+
+ std::cout << "purge!" << std::endl;
+ q.purge();
+ picture(q);
+
+ {
+ typedef p_priority<unsigned, Q> PQ;
+ PQ pq;
+ Q::piter p(q);
+ for_all(p)
+ pq.push(p.row() + p.col(), p);
+ std::cout << pq << std::endl;
+ }
+
+}
Index: doc/tutorial/examples/p_vaccess.cc
--- doc/tutorial/examples/p_vaccess.cc (revision 0)
+++ doc/tutorial/examples/p_vaccess.cc (revision 0)
@@ -0,0 +1,90 @@
+# include <mln/core/image2d.hh>
+# include <mln/core/neighb2d.hh>
+# include <mln/value/int_u8.hh>
+
+# include <mln/level/fill.hh>
+# include <mln/debug/println.hh>
+# include <mln/util/timer.hh>
+# include <mln/labeling/blobs.hh>
+
+# include <mln/core/p_vaccess.hh>
+# include <mln/convert/to_p_run_set.hh>
+
+
+template <typename I, typename S>
+void fill(S& s, const I& ima)
+{
+ mln_piter(I) p(ima.domain());
+ for_all(p)
+ s.insert(ima(p), p);
+ mln_postcondition(s.nsites() == ima.nsites());
+}
+
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+ bool vals[4][4] = {
+ {1, 1, 0, 1},
+ {1, 0, 1, 0},
+ {0, 1, 1, 0},
+ {1, 1, 0, 1}
+ };
+ image2d<bool> ima = make::image2d(vals);
+ debug::println(ima);
+
+ unsigned n;
+
+ {
+ typedef p_vaccess< value::set<bool>, p_array<point2d> > Arr;
+ mlc_equal(Arr::element, point2d)::check();
+ Arr arr;
+ fill(arr, ima);
+ n = arr(true).nsites();
+ mln_assertion(arr(true).nsites() + arr(false).nsites() == ima.nsites());
+
+ std::cout << "{-} = " << arr(false) << std::endl
+ << "{|} = " << arr(true) << std::endl
+ << std::endl;
+ }
+
+ int_u8 nlabels;
+ image2d<int_u8> lab = labeling::blobs(ima, c4(), nlabels);
+ debug::println(lab);
+
+ {
+ typedef p_vaccess< value::set<int_u8>, p_run_set<point2d> > Arr;
+ mlc_equal(Arr::element, p_run<point2d>)::check();
+ Arr arr;
+
+ convert::impl::fill_p_run_set_(arr, lab);
+ mln_assertion(arr.nsites() == n);
+
+ for (unsigned l = 1; l <= nlabels; ++l)
+ {
+ mln_assertion(! arr(l).is_empty());
+ std::cout << l << ": #"
+ << arr(l).nsites() << " in "
+ << arr(l).bbox() << std::endl;
+ }
+ }
+
+// p_run_set<point2d> rs = convert::to_p_run_set(ima);
+// std::cout << rs.zratio() << std::endl;
+// std::cout << rs.bbox() << std::endl;
+
+
+// image2d<value::int_u8> ima_(ima.domain());
+// level::fill(ima_, 0);
+// for (unsigned r = 0; r < rs.nruns(); ++r)
+// {
+// mln_piter_(p_run<point2d>) p(rs.run(r));
+// for_all(p)
+// ima_(p) = r + 1;
+// }
+// debug::println(ima_);
+// io::pgm::save(ima_, "tmp.pgm");
+}
Index: doc/tutorial/examples/p_key.cc
--- doc/tutorial/examples/p_key.cc (revision 0)
+++ doc/tutorial/examples/p_key.cc (revision 0)
@@ -0,0 +1,94 @@
+# include <mln/core/image2d.hh>
+# include <mln/core/p_key.hh>
+# include <mln/debug/println.hh>
+# include <mln/level/fill.hh>
+
+# include <mln/fun/v2v/inc.hh>
+# include <mln/fun/v2v/dec.hh>
+
+
+template <typename S>
+void picture(const S& s)
+{
+ using namespace mln;
+
+ image2d<char> ima(5, 5);
+ level::fill(ima, '-');
+
+ mln_piter(S) p(s);
+ for_all(p)
+ ima(p) = '0' + s.key(p);
+
+ debug::println(ima);
+}
+
+
+
+int main()
+{
+ using namespace mln;
+
+ // FIXME: Do not work with 'char' as a key!
+ typedef p_key<unsigned, point2d> S;
+ S s;
+
+ {
+ point2d p(1,1);
+ s.insert(p.row(), p);
+ mln_assertion(s.has(p));
+
+ dpoint2d dp[] = { right, right, down, down, left, left, up };
+ for (unsigned i = 0; i < 7; ++i)
+ p += dp[i], s.insert(p.row(), p);
+
+ std::cout << s.keys() << std::endl;
+ std::cout << s << std::endl;
+ }
+
+
+ std::cout << "insert(2, (1,1))" << std::endl;
+ s.insert(2, point2d(1,1));
+ std::cout << s << std::endl;
+
+ std::cout << "insert(5, (1,1))" << std::endl;
+ s.insert(5, point2d(1,1));
+ std::cout << s << std::endl;
+
+ std::cout << "inc keys" << std::endl;
+ s.change_keys(fun::v2v::inc<unsigned>());
+ std::cout << s << std::endl;
+
+ std::cout << "dec keys" << std::endl;
+ s.change_keys(fun::v2v::dec<unsigned>());
+ std::cout << s << std::endl;
+
+ std::cout << "remove (0,0)" << std::endl;
+ s.remove(point2d(0,0));
+ std::cout << s << std::endl;
+
+ std::cout << "remove (1,2)" << std::endl;
+ s.remove(point2d(1,2));
+ std::cout << s << std::endl;
+
+ std::cout << "remove (1,3)" << std::endl;
+ s.remove(point2d(1,3));
+ std::cout << s << std::endl;
+
+ std::cout << "remove key 0" << std::endl;
+ s.remove_key(0);
+ std::cout << s << std::endl;
+
+ std::cout << "change key 2 -> 4" << std::endl;
+ s.change_key(2, 4);
+ std::cout << s << std::endl;
+
+ std::cout << "remove key 3" << std::endl;
+ s.remove_key(3);
+ std::cout << s << std::endl;
+
+ picture(s);
+
+ std::cout << "clear" << std::endl;
+ s.clear();
+ std::cout << s << std::endl;
+}
Index: doc/tutorial/examples/p_key.2.cc
--- doc/tutorial/examples/p_key.2.cc (revision 0)
+++ doc/tutorial/examples/p_key.2.cc (revision 0)
@@ -0,0 +1,34 @@
+# include <mln/core/image2d.hh>
+# include <mln/core/p_key.hh>
+# include <mln/value/int_u8.hh>
+# include <mln/io/pgm/load.hh>
+# include <mln/io/pgm/save.hh>
+
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+ typedef image2d<int_u8> I;
+ I lena;
+ io::pgm::load(lena, "../../../img/lena.pgm");
+
+ typedef p_key<unsigned, point2d> S;
+ S s;
+ mln_piter_(I) p(lena.domain());
+ for_all(p)
+ s.insert(lena(p), p);
+
+ mln_assertion(lena.nsites() == s.nsites());
+
+ {
+ I out(lena.domain());
+ mln_piter_(I) p(lena.domain());
+ mln_piter_(S) q(s);
+ for_all_2(p, q)
+ out(p) = lena(q);
+ io::pgm::save(out, "out.pgm");
+ }
+}
Index: doc/tutorial/examples/window.cc
--- doc/tutorial/examples/window.cc (revision 2153)
+++ doc/tutorial/examples/window.cc (working copy)
@@ -72,7 +72,7 @@
{
typedef p_array<point2d> A;
A arr;
- arr.insert_all(ima.domain());
+ arr += ima.domain();
mln_fwd_piter_(A) p(arr);
for_all(p)
picture(ima, win, p);
Index: doc/tutorial/examples/image2d.cc
--- doc/tutorial/examples/image2d.cc (revision 2153)
+++ doc/tutorial/examples/image2d.cc (working copy)
@@ -61,7 +61,7 @@
{
typedef p_array<point2d> A;
A arr;
- arr.insert_all(ima.domain());
+ arr += ima.domain();
mln_fwd_piter_(A) p(arr);
for_all(p)
picture(ima, win, p);
Index: doc/tutorial/examples/accu.cc
--- doc/tutorial/examples/accu.cc (revision 2153)
+++ doc/tutorial/examples/accu.cc (working copy)
@@ -1,7 +1,6 @@
# include <mln/accu/mean.hh>
-
int main()
{
using namespace mln;
Index: doc/tutorial/examples/line2d.cc
--- doc/tutorial/examples/line2d.cc (revision 0)
+++ doc/tutorial/examples/line2d.cc (revision 0)
@@ -0,0 +1,46 @@
+# include <mln/core/image2d.hh>
+# include <mln/pw/all.hh>
+
+# include <mln/core/line2d.hh>
+# include <mln/core/p_set.hh>
+
+# include <mln/core/alias.hh>
+# include <mln/core/sub_image.hh>
+# include <mln/level/fill.hh>
+# include <mln/debug/println.hh>
+
+
+
+# include <mln/core/image/instant.hh>
+
+
+
+int main()
+{
+ using namespace mln;
+
+ image2d<char> ima(6, 11);
+ level::fill(ima, '.');
+
+ p_line2d line(make::point2d(4,10),
+ make::point2d(1,1));
+ std::cout << line << std::endl;
+
+ level::fill(inplace(ima | line), 'x');
+ debug::println(ima);
+
+ p_set<point2d> s;
+ s += line;
+ mln_assertion(s.has(line.begin()) && s.has(line.end()));
+ std::cout << s << std::endl;
+
+ debug::println(pw::cst('o') | line);
+ // ...
+
+
+ {
+ typedef image2d<char> I;
+ instant_<I> ima_(ima);
+ debug::println(ima_);
+ }
+}
Index: doc/tutorial/examples/proxy.cc
--- doc/tutorial/examples/proxy.cc (revision 0)
+++ doc/tutorial/examples/proxy.cc (revision 0)
@@ -0,0 +1,107 @@
+# include <mln/core/image2d.hh>
+# include <mln/core/p_array.hh>
+# include <mln/debug/println.hh>
+# include <mln/level/fill.hh>
+
+
+template <typename A>
+void picture(const A& arr)
+{
+ using namespace mln;
+
+ image2d<char> ima(5, 5);
+ level::fill(ima, '-');
+
+ unsigned i = 0;
+ mln_piter(A) p(arr);
+ for_all(p)
+ ima(p) = '0' + i++;
+
+ debug::println(ima);
+}
+
+
+
+int main()
+{
+ using namespace mln;
+
+ typedef p_array<point2d> Arr1;
+ Arr1 arr1;
+
+ {
+ point2d p(1,1);
+ arr1.append(p);
+ p = unproxy_rec(p);
+ }
+
+ {
+ mln_psite_(Arr1) p(arr1, 0);
+ std::cout << p << ' ' << arr1[0] << std::endl;
+ point2d& v = unproxy_rec(p);
+ std::cout << &(arr1[0]) << ' ' << &(unproxy_rec(p))
<< std::endl;
+ unproxy_rec(p).row() = 12;
+ mln_assertion(arr1[0].row() != 12); // FIXME: that's normal!
+
+ std::cout << p.get_subject() << std::endl;
+ std::cout << p.to_site() << std::endl;
+ }
+
+// {
+// mln_piter_(Arr1) p(arr1);
+// p.start();
+// std::cout << p.get_subject() << std::endl;
+// std::cout << p.to_site() << std::endl;
+// }
+
+// {
+// mln_psite_(Arr1) p(arr1, 0);
+// typedef typeof(mln_psite_(Arr1)::q_subject) TT;
+// TT var;
+// }
+
+
+ typedef p_array<mln_psite_(Arr1)> Arr2;
+
+// {
+
+// Arr2 arr2;
+
+// // Fill arr2 from arr1 contents.
+// {
+// mln_piter_(Arr1) p(arr1);
+// for_all(p)
+// if (p.row() % 2 && p.col() % 2)
+// arr2.append(p);
+// }
+
+// std::cout << "arr2 = " << arr2 << std::endl;
+// picture(arr2);
+
+// // Display indices.
+// {
+// mln_piter_(Arr2) p(arr2);
+// for_all(p)
+// {
+// mln_assertion(make::point2d(p.row(), p.col()) == p);
+// std::cout << "point " << p << ": #"
+// << index_of_in(p, arr2) << " in arr2, #"
+// << index_of_in(p, arr1) << " in arr1" <<
std::endl;
+// }
+// }
+
+// mln_invariant(arr2 < arr1);
+
+// {
+// mln_piter_(Arr1) p1(arr1);
+// mln_piter_(Arr2) p2(arr2);
+// for_all_2(p1, p2)
+// {
+// mln_assertion(p2 == p1); // same as: p2.to_site() == p1.to_site()
+// p1.next(); // p1 goes twice fast as p2.
+// }
+// }
+
+// }
+
+}
Index: doc/tutorial/examples/cpp_issue.cc
--- doc/tutorial/examples/cpp_issue.cc (revision 0)
+++ doc/tutorial/examples/cpp_issue.cc (revision 0)
@@ -0,0 +1,29 @@
+
+template <typename E>
+struct base
+{
+ typedef const E& box;
+ typedef const E& box_;
+ box bbox() const { return *(E*)(void*)(this); }
+};
+
+
+struct box : base<box>
+{
+ box() {}
+};
+
+
+template <typename S>
+void foo(const S&)
+{
+ typename S::box b;
+// void* v = b;
+ typename S::box_ b_;
+}
+
+int main()
+{
+ box b;
+ foo(b);
+}
Index: doc/tutorial/examples/p_mutable_array_of.cc
--- doc/tutorial/examples/p_mutable_array_of.cc (revision 0)
+++ doc/tutorial/examples/p_mutable_array_of.cc (revision 0)
@@ -0,0 +1,80 @@
+# include <mln/core/image2d.hh>
+# include <mln/debug/println.hh>
+# include <mln/core/p_mutable_array_of.hh>
+# include <mln/core/p_run.hh>
+
+
+
+namespace mln
+{
+
+
+ template <typename I, typename S>
+ void
+ convert_to_runs(const Image<I>& input_, Site_Set<S>& s_)
+ {
+ typedef mln_site(I) P;
+ mlc_is(mln_element(S), p_run<P>)::check();
+
+ const I& input = exact(input_);
+ S& s = exact(s_);
+ mln_precondition(input.has_data());
+
+ mln_fwd_piter(I) p(input.domain());
+ p.start();
+ for (;;)
+ {
+ // Skip background.
+ while (p.is_valid() && input(p) == false)
+ p.next();
+ if (! p.is_valid()) // The end.
+ break;
+ mln_invariant(input(p) == true);
+ P start = p, q;
+ // Go to run end.
+ do
+ {
+ q = p;
+ p.next();
+ }
+ while (p.is_valid() && input(p) == true && p == q + right);
+ s.insert(p_run<P>(start, q));
+ }
+ }
+
+} // mln
+
+
+
+template <typename S>
+void display(const S& s)
+{
+ mln_fwd_piter(S) p(s);
+ for_all(p)
+ std::cout << p << ' ';
+ std::cout << std::endl;
+}
+
+
+int main()
+{
+ using namespace mln;
+
+ bool vals[6][5] = {
+ {1, 1, 1, 1, 1},
+ {0, 0, 0, 0, 0},
+ {1, 0, 1, 0, 1},
+ {0, 1, 0, 1, 0},
+ {0, 0, 1, 1, 1},
+ {1, 1, 1, 0, 0}
+ };
+ image2d<bool> ima = make::image2d(vals);
+ debug::println(ima);
+
+ typedef p_mutable_array_of< p_run<point2d> > Runs;
+ Runs rs;
+ convert_to_runs(ima, rs);
+ std::cout << rs << std::endl;
+
+ display(rs);
+}
Index: doc/benchmark/p_runs.cc
--- doc/benchmark/p_runs.cc (revision 0)
+++ doc/benchmark/p_runs.cc (revision 0)
@@ -0,0 +1,54 @@
+# include <mln/io/pbm/load.hh>
+# include <mln/core/image2d.hh>
+# include <mln/convert/to_p_runs.hh>
+# include <mln/util/timer.hh>
+
+const unsigned n_times = 32;
+
+
+template <typename I>
+float browse_ima(const I& ima, unsigned& c)
+{
+ mln::util::timer t;
+ t.start();
+ for (unsigned i = 0; i < n_times; ++i)
+ {
+ c = 0;
+ mln_piter(I) p(ima.domain());
+ for_all(p)
+ if (ima(p))
+ ++c;
+ }
+ return t.read();
+}
+
+template <typename R>
+float browse_runs(const R& runs, unsigned& c)
+{
+ mln::util::timer t;
+ t.start();
+ for (unsigned i = 0; i < n_times; ++i)
+ {
+ c = 0;
+ mln_fwd_piter(R) p(runs);
+ for_all(p)
+ ++c;
+ }
+ return t.read();
+}
+
+
+int main()
+{
+ using namespace mln;
+ image2d<bool> ima;
+ io::pbm::load(ima, "../../img/lena.pbm");
+
+ p_runs<point2d> rs = convert::to_p_runs(ima);
+ mln_assertion(rs.zratio() < 1);
+
+ unsigned c1, c2;
+ std::cout << browse_ima(ima, c1) << std::endl;
+ std::cout << browse_runs(rs, c2) << std::endl;
+ mln_assertion(c2 == c1);
+}
Index: doc/benchmark/image2d.cc
--- doc/benchmark/image2d.cc (revision 0)
+++ doc/benchmark/image2d.cc (revision 0)
@@ -0,0 +1,152 @@
+# include <mln/core/image2d.hh>
+# include <mln/util/timer.hh>
+
+# include <mln/core/pixter2d.hh>
+
+
+int size;
+
+
+float a_la_C()
+{
+ unsigned len = size * size;
+ int* buf = new int[len];
+
+ mln::util::timer t;
+ t.start();
+ int* p = buf;
+ for (unsigned i = 0; i < len; ++i)
+ *p++ = 0;
+ return t.read();
+}
+
+
+float loops()
+{
+ typedef mln::image2d<int> I;
+ mln::internal::data<I> data(mln::make::box2d(size, size), 1);
+
+ mln::util::timer t;
+ t.start();
+ int** array = data.array_;
+ for (int row = 0; row < size; ++row)
+ for (int col = 0; col < size; ++col)
+ array[row][col] = 0;
+ return t.read();
+}
+
+
+float for_at()
+{
+ typedef mln::image2d<int> I;
+ I ima(size, size);
+
+ mln::util::timer t;
+ t.start();
+ for (int row = 0; row < size; ++row)
+ for (int col = 0; col < size; ++col)
+ ima.at(row, col) = 0;
+ return t.read();
+}
+
+
+float loops_ref()
+{
+ typedef mln::image2d<int> I;
+ mln::internal::data<I> data(mln::make::box2d(size, size), 1);
+
+ mln::util::timer t;
+ t.start();
+
+ int** array = data.array_;
+ mln::point2d p;
+ int & row = p.row(), & col = p.col();
+ for (row = 0; row < size; ++row)
+ for (col = 0; col < size; ++col)
+ array[row][col] = 0;
+
+ return t.read();
+}
+
+
+float hybrid_1()
+{
+ typedef mln::image2d<int> I;
+ I ima(size, size);
+
+ mln::util::timer t;
+ t.start();
+ mln::point2d p;
+ int & row = p.row(), & col = p.col();
+ for (row = 0; row < size; ++row)
+ for (col = 0; col < size; ++col)
+ ima.at(row, col) = 0;
+ return t.read();
+}
+
+
+
+float milena()
+{
+ typedef mln::image2d<int> I;
+ I ima(size, size);
+
+ mln::util::timer t;
+ t.start();
+ mln_piter_(I) p(ima.domain());
+ for_all(p)
+ ima(p) = 0;
+ return t.read();
+}
+
+
+float optim()
+{
+ typedef mln::image2d<int> I;
+ I ima(size, size);
+
+ mln::util::timer t;
+ t.start();
+ mln_piter_(I) p(ima.domain());
+ for (p.start(); p.is_valid(); p.next())
+ ima.alt(p) = 0;
+ return t.read();
+}
+
+
+float fast()
+{
+ typedef mln::image2d<int> I;
+ I ima(size, size);
+
+ mln::util::timer t;
+ t.start();
+ mln_pixter_(I) p(ima);
+ for_all(p)
+ p.val() = 0;
+ return t.read();
+}
+
+
+void usage(char* argv[])
+{
+ std::cerr << "usage: " << argv[0] << " size"
<< std::endl;
+ abort();
+}
+
+
+int main(int argc, char* argv[])
+{
+ if (argc != 2)
+ usage(argv);
+ size = std::atoi(argv[1]);
+
+ std::cout << "*p++ " << a_la_C() << std::endl;
+ std::cout << "for (r,c) " << loops() << std::endl;
+ std::cout << "for at(r,c) " << for_at() << std::endl;
+ std::cout << "for &(r,c) " << loops_ref() <<
std::endl;
+ std::cout << "hybrid_1 " << hybrid_1() << std::endl;
+ std::cout << "for_all(p) " << milena() << std::endl;
+ std::cout << "optim " << optim() << std::endl;
+ std::cout << "for_all(pix) " << fast() << std::endl;
+}
Index: mln/trait/site_set/props.hh
--- mln/trait/site_set/props.hh (revision 2153)
+++ mln/trait/site_set/props.hh (working copy)
@@ -31,6 +31,9 @@
/*! \file mln/trait/site_set/props.hh
*
* \brief Properties of site set classes.
+ *
+ * \todo Precise the differences (?) between dynamic, growing, and
+ * free...
*/
# include <string>
@@ -141,7 +144,7 @@
struct fixed : any { std::string name() const { return "contents::fixed"; }
};
struct dynamic : any { protected: dynamic() {} };
struct growing : dynamic { std::string name() const { return
"contents::growing"; } };
- struct free : dynamic { std::string name() const { return
"contents::dynamic"; } };
+ struct free : dynamic { std::string name() const { return "contents::free";
} };
};
/// Site set property about the unicity or multiplicity of its
Index: mln/trait/site_set/status.txt
--- mln/trait/site_set/status.txt (revision 2153)
+++ mln/trait/site_set/status.txt (working copy)
@@ -1,17 +1,49 @@
-ok box_
-KO line2d
+ -*- outline -*-
+
+* primary
+
+ok box
ok p_array
-KO p_array_bb
+ok p_run
+ok p_set
+
+KO p_image2d
+
+* utility
+
+ok p_double
+
+* derived
+
+ok p_runs -> rename as p_run_set
+ => better factored as p_set_of<S>
+
+new p_set_of
+new p_mutable_array_of
+todo p_array_of
+
+* queue-based
+
+ok p_queue_fast
+ok p_priority_queue -> rename as p_priority
+
+rm p_priority_queue_fast
+rm p_priority_queue_fast_with_array
+
+KO p_queue
+
+* graph-based
+
KO p_bgraph
KO p_graph
-KO p_image2d
KO p_line_graph
-KO p_priority_queue
-KO p_priority_queue_fast
-KO p_priority_queue_fast_with_array
-KO p_queue
-KO p_queue_fast
-KO p_run
-KO p_runs
-KO p_set
-KO pset_if
+
+* adapters
+
+ok p_vaccess
+ok line2d
+
+?? pset_if
+
+KO p_array_bb
+KO pset_array.hh
Index: mln/trait/image/props.hh
--- mln/trait/image/props.hh (revision 2153)
+++ mln/trait/image/props.hh (working copy)
@@ -39,6 +39,8 @@
# include <mln/trait/undef.hh>
# include <mln/trait/value/kind.hh>
+# include <mln/core/def/coord.hh> // Move along with space_from_point...
+
// Properties of images.
@@ -559,10 +561,10 @@
}
template <typename M, typename C> struct point;
- typedef point<grid::tick, int> point1d;
- typedef point<grid::square, int> point2d;
- typedef point<grid::hexa, int> point2d_h;
- typedef point<grid::cube, int> point3d;
+ typedef point<grid::tick, def::coord> point1d;
+ typedef point<grid::square, def::coord> point2d;
+ typedef point<grid::hexa, def::coord> point2d_h;
+ typedef point<grid::cube, def::coord> point3d;
namespace trait
{
Index: mln/trait/image/status.txt
--- mln/trait/image/status.txt (revision 2153)
+++ mln/trait/image/status.txt (working copy)
@@ -1,27 +1,71 @@
-KO bgraph_image
-KO cast_image
-KO decorated_image
-KO fi_adaptor
-KO graph_image
-KO hexa
-KO image1d
+ -*- outline -*-
+
+* to be removed
+
+mln/core/internal/run_image.hh
+
+
+* internal
+
+... image_identity (see todo)
+
+
+* primary
+
+** basic
+
ok image2d
+ok pw::image
+
+KO image1d
KO image3d
- ok image_if
- rm image_if_interval
- rm image_if_value
-KO interpolated
-KO line_graph_image
+
+** run-based
+
KO mono_obased_rle_image
KO mono_rle_image
KO obased_rle_image
-KO plain
- ok pw::image
KO rle_image
-KO safe
KO sparse_image
- ok sub_image
+
+** graph-based
+
+KO bgraph_image
+KO graph_image
+KO line_graph_image
+
+
+* morpher
+
+** value morpher
+
+KO cast_image
+
+** domain morpher
+
+ok image_if
+... sub_image = 1st attempt to use the 'instant' mechanism...
+
+rm image_if_interval
+rm image_if_value
+
KO t_image
KO tr_image
KO translate_image
+
+** identity morpher
+
+new instant
+
+KO decorated_image
+KO interpolated
+KO plain
+KO safe
+
+
+
+* unknown!!!
+
+KO fi_adaptor
+KO hexa
KO value_enc_image
Index: mln/trait/ch_value.hh
--- mln/trait/ch_value.hh (revision 2153)
+++ mln/trait/ch_value.hh (working copy)
@@ -61,9 +61,15 @@
namespace impl
{
- // Decl.
+ // Declaration.
template <typename I, typename V> struct ch_value_;
+ template <typename I, typename V>
+ struct ch_value_< tag::image_<I>, V >
+ {
+ typedef mln_ch_value(I, V) ret;
+ };
+
template < template <class> class M, typename T,
typename V >
struct ch_value_< M< tag::value_<T> >, V >
Index: mln/trait/solve.hh
--- mln/trait/solve.hh (revision 2153)
+++ mln/trait/solve.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006 EPITA Research and Development Laboratory
+// Copyright (C) 2006, 2008 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
@@ -73,42 +73,6 @@
- // Utility meta-function: from a category (meta) and a type, get the super category.
-
- namespace internal
- {
-
- template < template <class> class Category, typename T,
- typename Super_Category >
- struct helper_super_category_;
-
- template < template <class> class Category, typename T,
- template <class> class Super_Category >
- struct helper_super_category_< Category, T,
- Super_Category<void> >
- {
- typedef Super_Category<void> ret; // One super category: keep it.
- };
-
- template < template <class> class Category, typename T >
- struct helper_super_category_< Category, T,
- void* > // Meaning: several super categories exist, depending on T.
- {
- typedef typename mln::category< T >::super ret; // Specific call depending on T.
- };
-
-
- template < template <class> class Category, typename T >
- struct super_category_ // Entry.
- {
- typedef typename helper_super_category_< Category, T,
- typename Category<void>::super >::ret ret;
- };
-
- } // end of namespace mln::trait::internal
-
-
-
// Unary case.
Index: mln/trait/solve_binary.hh
--- mln/trait/solve_binary.hh (revision 2153)
+++ mln/trait/solve_binary.hh (working copy)
@@ -59,6 +59,25 @@
namespace internal
{
+
+ template < template <class, class> class Name,
+ typename Category_L, typename L,
+ typename Category_R, typename R >
+ struct trait_set_binary_;
+
+ template < template <class, class> class Name,
+ template <class> class Category_L, typename _l, typename L,
+ template <class> class Category_R, typename _r, typename R >
+ struct trait_set_binary_< Name,
+ Category_L<_l>, L,
+ Category_R<_r>, R >
+ {
+ typedef typename mln::trait::set_binary_<Name,
+ Category_L, L,
+ Category_R, R>::ret ret;
+ };
+
+
// triplet_ret_
template < unsigned i_L_, unsigned i_R_, typename ret_ >
@@ -159,23 +178,23 @@
// Fwd decl.
template < template <class, class> class Name,
- unsigned i_L, template <class> class Category_L, typename L,
- unsigned i_R, template <class> class Category_R, typename R >
+ unsigned i_L, typename Category_L, typename L,
+ unsigned i_R, typename Category_R, typename R >
struct get_binary_;
template < typename user_ret, /* != not_found and != undefined */
template <class, class> class Name,
- unsigned i_L, template <class> class Category_L, typename L,
- unsigned i_R, template <class> class Category_R, typename R >
+ unsigned i_L, typename Category_L, typename L,
+ unsigned i_R, typename Category_R, typename R >
struct helper_get_binary_
{
typedef triplet_< i_L, i_R, user_ret > ret; // The user has defined 'ret'
so we return it.
};
template < template <class, class> class Name,
- unsigned i_L, template <class> class Category_L, typename L,
- unsigned i_R, template <class> class Category_R, typename R >
+ unsigned i_L, typename Category_L, typename L,
+ unsigned i_R, typename Category_R, typename R >
struct helper_get_binary_< /* user_ret == */ not_found,
Name, i_L, Category_L, L, i_R, Category_R, R >
{
@@ -183,23 +202,9 @@
};
- template < template <class, class> class Name, // Nota bene: Seq means
"super or equal".
- unsigned i_L, typename Seq_Category_L, typename L,
- unsigned i_R, typename Seq_Category_R, typename R >
- struct helper_get_binary_rec_;
-
template < template <class, class> class Name,
- unsigned i_L, template <class> class Seq_Category_L, typename L,
- unsigned i_R, template <class> class Seq_Category_R, typename R >
- struct helper_get_binary_rec_< Name, i_L, Seq_Category_L<void>, L, i_R,
Seq_Category_R<void>, R >
- {
- typedef typename get_binary_<Name, i_L, Seq_Category_L, L, i_R, Seq_Category_R,
R>::ret ret;
- };
-
-
- template < template <class, class> class Name,
- unsigned i_L, template <class> class Category_L, typename L,
- unsigned i_R, template <class> class Category_R, typename R >
+ unsigned i_L, typename Category_L, typename L,
+ unsigned i_R, typename Category_R, typename R >
struct helper_get_binary_< /* user_ret == */ undefined,
Name, i_L,Category_L, L, i_R,Category_R, R >
{
@@ -208,16 +213,16 @@
// FIXME: We *do* need to handle this search with a priority!
// FIXME: for a result can be found in both branches...
- typedef typename super_category_< Category_L, L >::ret Super_Category_L;
- typedef typename super_category_< Category_R, R >::ret Super_Category_R;
+ typedef typename mln::internal::super_category_< Category_L, L >::ret
Super_Category_L;
+ typedef typename mln::internal::super_category_< Category_R, R >::ret
Super_Category_R;
- typedef helper_get_binary_rec_< Name,
+ typedef get_binary_< Name,
i_L + 1, Super_Category_L, L,
- i_R, Category_R<void>, R > L_branch;
+ i_R, Category_R, R > L_branch;
typedef mlc_ret(L_branch) L_trp;
- typedef helper_get_binary_rec_< Name,
- i_L, Category_L<void>, L,
+ typedef get_binary_< Name,
+ i_L, Category_L, L,
i_R + 1, Super_Category_R, R > R_branch;
typedef mlc_ret(R_branch) R_trp;
@@ -226,11 +231,11 @@
template < template <class, class> class Name,
- unsigned i_L, template <class> class Category_L, typename L,
- unsigned i_R, template <class> class Category_R, typename R >
+ unsigned i_L, typename Category_L, typename L,
+ unsigned i_R, typename Category_R, typename R >
struct get_binary_
{
- typedef typename mln::trait::set_binary_<Name, Category_L,L,
+ typedef typename trait_set_binary_<Name, Category_L,L,
Category_R,R>::ret user_ret; // First get 'user_ret'
typedef helper_get_binary_<user_ret, Name, i_L,Category_L,L,
i_R,Category_R,R> helper; // Set the helper to make a
decision.
@@ -240,16 +245,16 @@
template < typename precise_ret,
template <class, class> class Name,
- template <class> class Category_L, typename L,
- template <class> class Category_R, typename R >
+ typename Category_L, typename L,
+ typename Category_R, typename R >
struct helper_choose_binary_wrt_ /* precise_ret != undefined */
{
typedef precise_ret ret; // -> A
precise ret has been defined so it is it.
};
template < template <class, class> class Name,
- template <class> class Category_L, typename L,
- template <class> class Category_R, typename R >
+ typename Category_L, typename L,
+ typename Category_R, typename R >
struct helper_choose_binary_wrt_< /* precise_ret == */ undefined,
Name, Category_L, L, Category_R, R >
{
@@ -261,47 +266,29 @@
template < template <class, class> class Name,
- template <class> class Category_L, typename L,
- template <class> class Category_R, typename R >
- struct helper_choose_binary_
+ typename Category_L, typename L,
+ typename Category_R, typename R >
+ struct helper_solve_binary_
{
typedef typename set_precise_binary_<Name, L, R>::ret precise_ret; /* undefined or
not (?) */
typedef helper_choose_binary_wrt_<precise_ret, Name, Category_L,L, Category_R,R>
helper;
typedef mlc_ret(helper) ret;
};
-
- template < template <class, class> class Name,
- typename Category_L_void, typename L,
- typename Category_R_void, typename R >
- struct helper_solve_binary_;
-
- template < template <class, class> class Name,
- template <class> class Category_L, typename void_L, typename L,
- template <class> class Category_R, typename void_R, typename R >
- struct helper_solve_binary_< Name,
- Category_L<void_L>, L,
- Category_R<void_R>, R > : helper_choose_binary_< Name,
- Category_L, L,
- Category_R, R >
- {
- // FIXME: Check that void_L and void_R are 'void' or 'void*'.
- };
-
} // end of namespace mln::trait::internal
// FIXME: Postfix solve_binary with a '-'(?)
template < template <class, class> class Name,
- typename L,
- typename R >
+ typename L_,
+ typename R_ >
struct solve_binary
{
- typedef mln_exact(L) L_;
- typedef mln_exact(R) R_;
- typedef typename mln::category<L_>::ret CatL;
- typedef typename mln::category<R_>::ret CatR;
- typedef internal::helper_solve_binary_< Name, CatL, L, CatR, R > meta_code;
+ typedef mln_exact(L_) L;
+ typedef mln_exact(R_) R;
+ typedef typename mln::category<L>::ret Category_L;
+ typedef typename mln::category<R>::ret Category_R;
+ typedef internal::helper_solve_binary_< Name, Category_L, L, Category_R, R >
meta_code;
typedef typename meta_code::ret ret;
};
Index: mln/trait/solve_unary.hh
--- mln/trait/solve_unary.hh (revision 2153)
+++ mln/trait/solve_unary.hh (working copy)
@@ -59,15 +59,30 @@
namespace internal
{
+
+ template < template <class> class Name,
+ typename Category,
+ typename T >
+ struct trait_set_unary_;
+
+ template < template <class> class Name,
+ template <class> class Category, typename _,
+ typename T >
+ struct trait_set_unary_< Name, Category<_>, T >
+ {
+ typedef typename mln::trait::set_unary_<Name, Category, T>::ret ret;
+ };
+
+
// Fwd decls.
template < template <class> class Name,
- template <class> class Category_T, typename T >
+ typename Category, typename T >
struct get_unary_;
template < typename user_ret, /* != not_found and != undefined */
template <class> class Name,
- template <class> class Category_T, typename T >
+ typename Category, typename T >
struct helper_get_unary_
{
typedef user_ret ret; // The user has defined 'ret' so we return it.
@@ -75,103 +90,71 @@
template < template <class> class Name,
- template <class> class Category_T, typename T >
+ typename Category, typename T >
struct helper_get_unary_< /* user_ret == */ not_found,
- Name, Category_T, T >
+ Name, Category, T >
{
typedef not_found ret; // End of search due to a blocker; 'ret' is not found.
};
- template < template <class> class Name, typename Super_Category, typename
T >
- struct helper_get_unary_rec_;
-
- template < template <class> class Name, template <class> class
Super_Category_T, typename T >
- struct helper_get_unary_rec_< Name, Super_Category_T<void>, T > {
- typedef typename get_unary_<Name, Super_Category_T, T>::ret ret;
- };
-
template < template <class> class Name,
- template <class> class Category_T, typename T >
+ typename Category, typename T >
struct helper_get_unary_< /* user_ret == */ undefined,
- Name, Category_T, T >
+ Name, Category, T >
{
- typedef typename internal::super_category_< Category_T, T >::ret super;
- typedef typename helper_get_unary_rec_<Name, super, T>::ret ret; // No user ret
definition => Recursion.
+ typedef typename mln::internal::super_category_< Category, T >::ret
Super_Category;
+ typedef typename get_unary_<Name, Super_Category, T>::ret ret; // No user ret
definition => Recursion.
};
template < template <class> class Name,
- template <class> class Category_T, typename T >
+ typename Category, typename T >
struct get_unary_
{
- typedef typename mln::trait::set_unary_<Name, Category_T, T>::ret user_ret; //
First get 'user_ret'
- typedef helper_get_unary_<user_ret, Name, Category_T, T> helper; // Set
the helper to make a decision.
+ typedef typename trait_set_unary_<Name, Category, T>::ret user_ret; // First get
'user_ret'
+ typedef helper_get_unary_<user_ret, Name, Category, T> helper; // Set the
helper to make a decision.
typedef mlc_ret(helper) ret; // Return.
};
template < typename precise_ret,
template <class> class Name,
- template <class> class Category_T, typename T >
+ typename Category, typename T >
struct helper_choose_unary_wrt_ /* precise_ret != undefined */
{
typedef precise_ret ret; // -> A precise ret has
been defined so it is it.
};
template < template <class> class Name,
- template <class> class Category_T, typename T >
+ typename Category, typename T >
struct helper_choose_unary_wrt_< /* precise_ret == */ undefined,
- Name, Category_T, T >
+ Name, Category, T >
{
- typedef typename get_unary_<Name, Category_T, T>::ret ret; // -> Go up into the
category inheritance
+ typedef typename get_unary_<Name, Category, T>::ret ret; // -> Go up into the
category inheritance
// to fetch a ret from
'set_unary_'s.
};
template < template <class> class Name,
- template <class> class Category_T, typename T >
- struct helper_choose_unary_
+ typename Category, typename T >
+ struct helper_solve_unary_
{
typedef typename set_precise_unary_<Name, T>::ret precise_ret;
typedef helper_choose_unary_wrt_< precise_ret, /* undefined or not (?) */
- Name, Category_T, T> helper;
+ Name, Category, T> helper;
typedef mlc_ret(helper) ret;
};
-
- template < template <class> class Name,
- typename Category_T_void, typename T >
- struct helper_solve_unary_; // This helper changes the category plain type into the
category meta type.
-
- template < template <class> class Name,
- template <class> class Category_T, typename void_T, typename T >
- struct helper_solve_unary_< Name, Category_T<void_T>, T >
- :
- helper_choose_unary_< Name, Category_T, T > // FIXME: typedef!
- {
- // FIXME: Check that void_T is 'void' or 'void*'.
- };
-
- // FIXME: Remove below.
-
-// template < template <class> class Name,
-// template <class> class Category_T, typename T >
-// struct helper_solve_unary_< Name, Category_T<void*>, T >
-// :
-// helper_choose_unary_< Name, Category_T, T > // FIXME: typedef!
-// {};
-
} // end of namespace mln::trait::internal
- // FIXME: Postfix solve_unary with a '-'(?)
template < template <class> class Name,
- typename T >
+ typename T_ >
struct solve_unary
{
- typedef mln_exact(T) E;
- typedef typename mln::category<E>::ret Cat;
- typedef internal::helper_solve_unary_< Name, Cat, E > meta_code;
+ typedef mln_exact(T_) T;
+ typedef typename mln::category<T>::ret Category;
+ typedef internal::helper_solve_unary_< Name, Category, T > meta_code;
typedef typename meta_code::ret ret;
};
Index: mln/trait/op/leq.hh
--- mln/trait/op/leq.hh (revision 2153)
+++ mln/trait/op/leq.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006 EPITA Research and Development Laboratory
+// Copyright (C) 2006, 2008 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
@@ -33,7 +33,7 @@
* \brief Declaration of the "binary less-or-equal" operator trait.
*/
-# include <mln/trait/solve.hh>
+# include <mln/trait/op/decl.hh>
# define mln_trait_op_leq(L, R) typename mln::trait::op::leq< L , R >::ret
@@ -62,4 +62,7 @@
} // end of namespace mln
+# include <mln/trait/solve.hh>
+
+
#endif // ! MLN_TRAIT_OP_LEQ_HH
Index: mln/trait/op/times.hh
--- mln/trait/op/times.hh (revision 2153)
+++ mln/trait/op/times.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006 EPITA Research and Development Laboratory
+// Copyright (C) 2006, 2008 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
@@ -33,7 +33,7 @@
* \brief Declaration of the "binary multiplication" operator trait.
*/
-# include <mln/trait/promote.hh>
+# include <mln/trait/op/decl.hh>
# define mln_trait_op_times(L, R) typename mln::trait::op::times< L , R >::ret
@@ -73,4 +73,7 @@
} // end of namespace mln
+# include <mln/trait/solve.hh>
+
+
#endif // ! MLN_TRAIT_OP_TIMES_HH
Index: mln/trait/op/div.hh
--- mln/trait/op/div.hh (revision 2153)
+++ mln/trait/op/div.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006 EPITA Research and Development Laboratory
+// Copyright (C) 2006, 2008 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
@@ -33,7 +33,7 @@
* \brief Declaration of the "binary division" operator trait.
*/
-# include <mln/trait/promote.hh>
+# include <mln/trait/op/decl.hh>
# define mln_trait_op_div(L, R) typename mln::trait::op::div< L , R >::ret
@@ -62,4 +62,7 @@
} // end of namespace mln
+# include <mln/trait/promote.hh>
+
+
#endif // ! MLN_TRAIT_OP_DIV_HH
Index: mln/trait/op/plus.hh
--- mln/trait/op/plus.hh (revision 2153)
+++ mln/trait/op/plus.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006 EPITA Research and Development Laboratory
+// Copyright (C) 2006, 2008 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
@@ -33,7 +33,7 @@
* \brief Declaration of the "binary plus" operator trait.
*/
-# include <mln/trait/promote.hh>
+# include <mln/trait/op/decl.hh>
# define mln_trait_op_plus(L, R) typename mln::trait::op::plus< L , R >::ret
@@ -62,4 +62,7 @@
} // end of namespace mln
+# include <mln/trait/promote.hh>
+
+
#endif // ! MLN_TRAIT_OP_PLUS_HH
Index: mln/trait/op/neq.hh
--- mln/trait/op/neq.hh (revision 2153)
+++ mln/trait/op/neq.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006 EPITA Research and Development Laboratory
+// Copyright (C) 2006, 2008 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
@@ -33,7 +33,7 @@
* \brief Declaration of the "binary un-equality" operator trait.
*/
-# include <mln/trait/solve.hh>
+# include <mln/trait/op/decl.hh>
# define mln_trait_op_neq(L, R) typename mln::trait::op::neq< L , R >::ret
@@ -62,4 +62,7 @@
} // end of namespace mln
+# include <mln/trait/solve.hh>
+
+
#endif // ! MLN_TRAIT_OP_NEQ_HH
Index: mln/trait/op/greater.hh
--- mln/trait/op/greater.hh (revision 2153)
+++ mln/trait/op/greater.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006 EPITA Research and Development Laboratory
+// Copyright (C) 2006, 2008 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
@@ -33,7 +33,7 @@
* \brief Declaration of the "binary greater" operator trait.
*/
-# include <mln/trait/solve.hh>
+# include <mln/trait/op/decl.hh>
# define mln_trait_op_greater(L, R) typename mln::trait::op::greater< L , R
>::ret
@@ -62,4 +62,7 @@
} // end of namespace mln
+# include <mln/trait/solve.hh>
+
+
#endif // ! MLN_TRAIT_OP_GREATER_HH
Index: mln/trait/op/minus.hh
--- mln/trait/op/minus.hh (revision 2153)
+++ mln/trait/op/minus.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006 EPITA Research and Development Laboratory
+// Copyright (C) 2006, 2008 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
@@ -33,7 +33,7 @@
* \brief Declaration of the "binary minus" operator trait.
*/
-# include <mln/trait/promote.hh>
+# include <mln/trait/op/decl.hh>
# define mln_trait_op_minus(L, R) typename mln::trait::op::minus< L , R >::ret
@@ -63,4 +63,7 @@
} // end of namespace mln
+# include <mln/trait/promote.hh>
+
+
#endif // ! MLN_TRAIT_OP_MINUS_HH
Index: mln/trait/op/not.hh
--- mln/trait/op/not.hh (revision 2153)
+++ mln/trait/op/not.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006 EPITA Research and Development Laboratory
+// Copyright (C) 2006, 2008 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
@@ -33,7 +33,7 @@
* \brief Declaration of the "unary negation" operator trait.
*/
-# include <mln/trait/solve.hh>
+# include <mln/trait/op/decl.hh>
# define mln_trait_op_not(T) typename mln::trait::op::not_< T >::ret
@@ -62,4 +62,7 @@
} // end of namespace mln
+# include <mln/trait/solve.hh>
+
+
#endif // ! MLN_TRAIT_OP_NOT_HH
Index: mln/trait/op/postdec.hh
--- mln/trait/op/postdec.hh (revision 2153)
+++ mln/trait/op/postdec.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006 EPITA Research and Development Laboratory
+// Copyright (C) 2006, 2008 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
@@ -33,7 +33,7 @@
* \brief Declaration of the "unary post-decrementation" operator trait.
*/
-# include <mln/trait/solve.hh>
+# include <mln/trait/op/decl.hh>
# define mln_trait_op_postdec(T) typename mln::trait::op::postdec< T >::ret
@@ -62,4 +62,7 @@
} // end of namespace mln
+# include <mln/trait/solve.hh>
+
+
#endif // ! MLN_TRAIT_OP_POSTDEC_HH
Index: mln/trait/op/predec.hh
--- mln/trait/op/predec.hh (revision 2153)
+++ mln/trait/op/predec.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006 EPITA Research and Development Laboratory
+// Copyright (C) 2006, 2008 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
@@ -33,7 +33,7 @@
* \brief Declaration of the "unary pre-decrementation" operator trait.
*/
-# include <mln/trait/solve.hh>
+# include <mln/trait/op/decl.hh>
# define mln_trait_op_predec(T) typename mln::trait::op::predec< T >::ret
@@ -62,4 +62,7 @@
} // end of namespace mln
+# include <mln/trait/solve.hh>
+
+
#endif // ! MLN_TRAIT_OP_PREDEC_HH
Index: mln/trait/op/and.hh
--- mln/trait/op/and.hh (revision 2153)
+++ mln/trait/op/and.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006 EPITA Research and Development Laboratory
+// Copyright (C) 2006, 2008 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
@@ -33,14 +33,13 @@
* \brief Declaration of the "binary and" operator trait.
*/
-# include <mln/trait/solve.hh>
+# include <mln/trait/op/decl.hh>
# define mln_trait_op_and(L, R) typename mln::trait::op::and_< L , R >::ret
# define mln_trait_op_and_(L, R) mln::trait::op::and_< L , R >::ret
-
namespace mln
{
@@ -62,4 +61,7 @@
} // end of namespace mln
+# include <mln/trait/solve.hh>
+
+
#endif // ! MLN_TRAIT_OP_AND_HH
Index: mln/trait/op/eq.hh
--- mln/trait/op/eq.hh (revision 2153)
+++ mln/trait/op/eq.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006 EPITA Research and Development Laboratory
+// Copyright (C) 2006, 2008 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
@@ -33,7 +33,7 @@
* \brief Declaration of the "binary equality" operator trait.
*/
-# include <mln/trait/solve.hh>
+# include <mln/trait/op/decl.hh>
# define mln_trait_op_eq(L, R) typename mln::trait::op::eq< L , R >::ret
@@ -62,4 +62,7 @@
} // end of namespace mln
+# include <mln/trait/solve.hh>
+
+
#endif // ! MLN_TRAIT_OP_EQ_HH
Index: mln/trait/op/less.hh
--- mln/trait/op/less.hh (revision 2153)
+++ mln/trait/op/less.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006 EPITA Research and Development Laboratory
+// Copyright (C) 2006, 2008 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
@@ -33,7 +33,7 @@
* \brief Declaration of the "binary less" operator trait.
*/
-# include <mln/trait/solve.hh>
+# include <mln/trait/op/decl.hh>
# define mln_trait_op_less(L, R) typename mln::trait::op::less< L , R >::ret
@@ -62,4 +62,7 @@
} // end of namespace mln
+# include <mln/trait/solve.hh>
+
+
#endif // ! MLN_TRAIT_OP_LESS_HH
Index: mln/trait/op/decl.hh
--- mln/trait/op/decl.hh (revision 0)
+++ mln/trait/op/decl.hh (revision 0)
@@ -0,0 +1,62 @@
+// Copyright (C) 2008 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 MLN_TRAIT_OP_DECL_HH
+# define MLN_TRAIT_OP_DECL_HH
+
+/*! \file mln/trait/op/decl.hh
+ *
+ * \brief Forward declaration of the couple of trait solving
+ * structures: mln::trait::solve_unary and mln::trait::solve_binary.
+ */
+
+
+
+namespace mln
+{
+
+ namespace trait
+ {
+
+
+ template < template <class> class Name,
+ typename T >
+ struct solve_unary;
+
+
+ template < template <class, class> class Name,
+ typename L,
+ typename R >
+ struct solve_binary;
+
+
+ } // end of namespace mln::trait
+
+} // end of namespace mln
+
+
+#endif // ! MLN_TRAIT_OP_DECL_HH
Index: mln/trait/op/xor.hh
--- mln/trait/op/xor.hh (revision 2153)
+++ mln/trait/op/xor.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006 EPITA Research and Development Laboratory
+// Copyright (C) 2006, 2008 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
@@ -33,7 +33,7 @@
* \brief Declaration of the "binary xor" operator trait.
*/
-# include <mln/trait/solve.hh>
+# include <mln/trait/op/decl.hh>
# define mln_trait_op_xor(L, R) typename mln::trait::op::xor_< L , R >::ret
@@ -62,4 +62,7 @@
} // end of namespace mln
+# include <mln/trait/solve.hh>
+
+
#endif // ! MLN_TRAIT_OP_XOR_HH
Index: mln/trait/op/uplus.hh
--- mln/trait/op/uplus.hh (revision 2153)
+++ mln/trait/op/uplus.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006 EPITA Research and Development Laboratory
+// Copyright (C) 2006, 2008 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
@@ -33,7 +33,7 @@
* \brief Declaration of the "unary plus" operator trait.
*/
-# include <mln/trait/solve.hh>
+# include <mln/trait/op/decl.hh>
# define mln_trait_op_uplus(T) typename mln::trait::op::uplus< T >::ret
@@ -62,4 +62,7 @@
} // end of namespace mln
+# include <mln/trait/solve.hh>
+
+
#endif // ! MLN_TRAIT_OP_UPLUS_HH
Index: mln/trait/op/geq.hh
--- mln/trait/op/geq.hh (revision 2153)
+++ mln/trait/op/geq.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006 EPITA Research and Development Laboratory
+// Copyright (C) 2006, 2008 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
@@ -33,7 +33,7 @@
* \brief Declaration of the "binary greater-or-equal" operator trait.
*/
-# include <mln/trait/solve.hh>
+# include <mln/trait/op/decl.hh>
# define mln_trait_op_geq(L, R) typename mln::trait::op::geq< L , R >::ret
@@ -62,4 +62,7 @@
} // end of namespace mln
+# include <mln/trait/solve.hh>
+
+
#endif // ! MLN_TRAIT_OP_GEQ_HH
Index: mln/trait/op/mod.hh
--- mln/trait/op/mod.hh (revision 2153)
+++ mln/trait/op/mod.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006 EPITA Research and Development Laboratory
+// Copyright (C) 2006, 2008 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
@@ -33,7 +33,7 @@
* \brief Declaration of the "binary modulus" operator trait.
*/
-# include <mln/trait/promote.hh>
+# include <mln/trait/op/decl.hh>
# define mln_trait_op_mod(L, R) typename mln::trait::op::mod< L , R >::ret
@@ -62,4 +62,7 @@
} // end of namespace mln
+# include <mln/trait/promote.hh>
+
+
#endif // ! MLN_TRAIT_OP_MOD_HH
Index: mln/trait/op/postinc.hh
--- mln/trait/op/postinc.hh (revision 2153)
+++ mln/trait/op/postinc.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006 EPITA Research and Development Laboratory
+// Copyright (C) 2006, 2008 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
@@ -33,7 +33,7 @@
* \brief Declaration of the "unary post-incrementation" operator trait.
*/
-# include <mln/trait/solve.hh>
+# include <mln/trait/op/decl.hh>
# define mln_trait_op_postinc(T) typename mln::trait::op::postinc< T >::ret
@@ -62,4 +62,7 @@
} // end of namespace mln
+# include <mln/trait/solve.hh>
+
+
#endif // ! MLN_TRAIT_OP_POSTINC_HH
Index: mln/trait/op/preinc.hh
--- mln/trait/op/preinc.hh (revision 2153)
+++ mln/trait/op/preinc.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006 EPITA Research and Development Laboratory
+// Copyright (C) 2006, 2008 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
@@ -33,7 +33,7 @@
* \brief Declaration of the "unary pre-decrementation" operator trait.
*/
-# include <mln/trait/solve.hh>
+# include <mln/trait/op/decl.hh>
# define mln_trait_op_preinc(T) typename mln::trait::op::preinc< T >::ret
@@ -62,4 +62,7 @@
} // end of namespace mln
+# include <mln/trait/solve.hh>
+
+
#endif // ! MLN_TRAIT_OP_PREINC_HH
Index: mln/trait/op/uminus.hh
--- mln/trait/op/uminus.hh (revision 2153)
+++ mln/trait/op/uminus.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006 EPITA Research and Development Laboratory
+// Copyright (C) 2006, 2008 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
@@ -33,14 +33,13 @@
* \brief Declaration of the "unary minus" operator trait.
*/
-# include <mln/trait/solve.hh>
+# include <mln/trait/op/decl.hh>
# define mln_trait_op_uminus(T) typename mln::trait::op::uminus< T >::ret
# define mln_trait_op_uminus_(T) mln::trait::op::uminus< T >::ret
-
namespace mln
{
@@ -62,4 +61,7 @@
} // end of namespace mln
+# include <mln/trait/solve.hh>
+
+
#endif // ! MLN_TRAIT_OP_UMINUS_HH
Index: mln/trait/op/or.hh
--- mln/trait/op/or.hh (revision 2153)
+++ mln/trait/op/or.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006 EPITA Research and Development Laboratory
+// Copyright (C) 2006, 2008 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
@@ -33,7 +33,7 @@
* \brief Declaration of the "binary or" operator trait.
*/
-# include <mln/trait/solve.hh>
+# include <mln/trait/op/decl.hh>
# define mln_trait_op_or(L, R) typename mln::trait::op::or_< L , R >::ret
@@ -62,4 +62,7 @@
} // end of namespace mln
+# include <mln/trait/solve.hh>
+
+
#endif // ! MLN_TRAIT_OP_OR_HH
Index: mln/debug/put_word.hh
--- mln/debug/put_word.hh (revision 0)
+++ mln/debug/put_word.hh (revision 0)
@@ -0,0 +1,84 @@
+// Copyright (C) 2008 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 MLN_DEBUG_PUT_WORD_HH
+# define MLN_DEBUG_PUT_WORD_HH
+
+/*! \file mln/debug/put_word.hh
+ *
+ * \brief Write a word in a 2D image of characters.
+ */
+
+# include <string>
+# include <mln/core/image2d.hh>
+
+
+namespace mln
+{
+
+ namespace debug
+ {
+
+ /// Put the \p word starting at location \p word_start in the
+ /// image \p inout.
+ inline
+ void
+ put_word(image2d<char>& inout, const point2d& word_start,
+ const std::string& word);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ inline
+ void
+ put_word(image2d<char>& inout, const point2d& word_start,
+ const std::string& word)
+ {
+ mln_precondition(word.length() != 0);
+ mln_precondition(inout.has(word_start));
+
+ point2d word_end = word_start;
+ word_end.last_coord() += word.length() - 1;
+ mln_precondition(inout.has(word_end));
+
+ const unsigned n = word.length();
+ point2d p = word_start;
+ for (unsigned i = 0; i < n; ++i)
+ {
+ inout(p) = word[i];
+ p += right;
+ }
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::debug
+
+} // end of namespace mln
+
+
+#endif // ! MLN_DEBUG_PUT_WORD_HH
Index: mln/debug/println.hh
--- mln/debug/println.hh (revision 2153)
+++ mln/debug/println.hh (working copy)
@@ -31,6 +31,8 @@
/*! \file mln/debug/println.hh
*
* \brief Print an image on the standard output.
+ *
+ * \todo Revamp.
*/
# include <mln/core/concept/image.hh>
Index: mln/debug/println.spe.hh
--- mln/debug/println.spe.hh (revision 2153)
+++ mln/debug/println.spe.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -31,15 +31,21 @@
/*! \file mln/debug/println.spe.hh
*
* \brief Specializations for mln::debug::println.
+ *
+ * \todo Clean-up code.
*/
# ifndef MLN_DEBUG_PRINTLN_HH
# error "Forbidden inclusion of *.spe.hh"
# endif // ! MLN_DEBUG_PRINTLN_HH
+# include <sstream>
# include <mln/core/concept/image.hh>
# include <mln/core/concept/window.hh>
# include <mln/debug/format.hh>
+# include <mln/debug/put_word.hh>
+# include <mln/level/fill.hh>
+# include <mln/accu/max.hh>
namespace mln
@@ -55,26 +61,52 @@
# ifdef MLN_CORE_BOX2D_HH
- // 2D version.
+ // 2D versions.
+
+ inline
+ void
+ println(const box2d& b, const image2d<char>& input)
+ {
+ for (int row = b.min_row(); row <= b.max_row(); ++row)
+ {
+ for (int col = b.min_col(); col <= b.max_col(); ++col)
+ std::cout << input.at(row, col) << ' ';
+ std::cout << std::endl;
+ }
+ std::cout << std::endl;
+ }
+
+
template <typename I>
inline
void
println(const box2d& b, const I& input)
{
- point2d p;
- int& row = p.row();
- int& col = p.col();
- const int
- max_row = b.max_row(),
- max_col = b.max_col();
+ accu::max_<unsigned> len_;
+ mln_piter(I) p(input.domain());
+ for_all(p)
+ {
+ std::ostringstream o;
+ o << format(input(p));
+ len_.take(o.str().length());
+ }
+ unsigned len = len_ + 1;
- for (row = b.min_row(); row <= max_row; ++row)
+ image2d<char> output(b.nrows(), b.ncols() * len, 0);
+ level::fill(output, ' ');
+ for_all(p)
{
- for (col = b.min_col(); col <= max_col; ++col)
- if (input.has(p))
- std::cout << format(input(p)) << ' ';
- else
- std::cout << " ";
+ std::ostringstream oss;
+ oss << format(input(p));
+ point2d w( p.row() - b.min_row(),
+ (p.col() - b.min_col()) * len);
+ put_word(output, w, oss.str());
+ }
+
+ for (unsigned row = 0; row < b.nrows(); ++row)
+ {
+ for (unsigned col = 0; col < b.ncols() * len; ++col)
+ std::cout << output.at(row, col);
std::cout << std::endl;
}
std::cout << std::endl;
Index: mln/core/dpoint2d.hh
--- mln/core/dpoint2d.hh (revision 2153)
+++ mln/core/dpoint2d.hh (working copy)
@@ -35,6 +35,7 @@
*/
# include <mln/core/dpoint.hh>
+# include <mln/core/def/coord.hh>
namespace mln
@@ -43,7 +44,7 @@
/*! \brief Type alias for a delta-point defined on the 2D square
* grid with integer coordinates.
*/
- typedef dpoint<grid::square, int> dpoint2d;
+ typedef dpoint<grid::square, def::coord> dpoint2d;
} // end of namespace mln
Index: mln/core/macros.hh
--- mln/core/macros.hh (revision 2153)
+++ mln/core/macros.hh (working copy)
@@ -49,6 +49,12 @@
// b
+/// Shortcuts to access the bkd_iter type associated to T.
+/// \{
+# define mln_bkd_iter(T) typename T::bkd_iter
+# define mln_bkd_iter_(T) T::bkd_iter
+/// \}
+
/// Shortcuts to access the bkd_niter type associated to T.
/// \{
# define mln_bkd_niter(T) typename T::bkd_niter
@@ -112,6 +118,12 @@
// e
+/// Shortcuts to access the element type associated to T.
+/// \{
+# define mln_element(T) typename T::element
+# define mln_element_(T) T::element
+/// \}
+
/// Shortcuts to access the encoding type associated to T.
/// \{
# define mln_enc(T) typename T::enc
@@ -127,6 +139,12 @@
// f
+/// Shortcuts to access the fwd_iter type associated to T.
+/// \{
+# define mln_fwd_iter(T) typename T::fwd_iter
+# define mln_fwd_iter_(T) T::fwd_iter
+/// \}
+
/// Shortcuts to access the fwd_niter type associated to T.
/// \{
# define mln_fwd_niter(T) typename T::fwd_niter
@@ -175,6 +193,12 @@
# define mln_invert_(T) T::invert
/// \}
+/// Shortcuts to access the iterator type associated to T.
+/// \{
+# define mln_iter(T) typename T::iter
+# define mln_iter_(T) T::iter
+/// \}
+
// l
@@ -243,6 +267,12 @@
# define mln_qiter_(T) T::fwd_qiter
/// \}
+/// Shortcuts to access the qualified-subject type associated to T.
+/// \{
+# define mln_q_subject(T) typename T::q_subject
+# define mln_q_subject_(T) T::q_subject
+/// \}
+
// n
@@ -276,13 +306,23 @@
# define mln_site_(T) T::site
/// \}
-/// Shortcuts to access the subject type associated to T.
+// /// Shortcuts to access the subject type associated to T.
+// /// \{
+// # define mln_subject(T) typename T::subject
+// # define mln_subject_(T) T::subject
+// /// \}
+
+
+// t
+
+/// Shortcuts to access the target type associated to T.
/// \{
-# define mln_subject(T) typename T::subject
-# define mln_subject_(T) T::subject
+# define mln_target(T) typename T::target
+# define mln_target_(T) T::target
/// \}
+
// v
/// Shortcuts to access the value type associated to T.
Index: mln/core/point.hh
--- mln/core/point.hh (revision 2153)
+++ mln/core/point.hh (working copy)
@@ -35,6 +35,7 @@
* \todo Try to generalize less_than with Gl and Gr.
*/
+# include <mln/core/def/coord.hh>
# include <mln/core/concept/gpoint.hh>
# include <mln/core/internal/coord_impl.hh>
# include <mln/fun/i2v/all_to.hh>
@@ -43,6 +44,7 @@
# include <mln/algebra/vec.hh>
# include <mln/metal/converts_to.hh>
# include <mln/core/h_vec.hh>
+# include <mln/util/yes.hh>
namespace mln
@@ -109,7 +111,7 @@
* \param[in] i The coordinate index.
* \pre \p i < \c dim
*/
- C operator[](unsigned i) const;
+ const C& operator[](unsigned i) const;
/*! \brief Read-write access to the \p i-th coordinate value.
* \param[in] i The coordinate index.
@@ -117,6 +119,14 @@
*/
C& operator[](unsigned i);
+
+ /// Read-only access to the last coordinate.
+ const C& last_coord() const;
+
+ /// Read-write access to the last coordinate.
+ C& last_coord();
+
+
/// Constructor without argument.
point();
@@ -167,11 +177,26 @@
/// Transform to point in homogene coordinate system.
h_vec<G::dim, C> to_h_vec() const;
+ /// Point with all coordinates set to the maximum value.
+ static const point<G,C>& plus_infty();
+
+ /// Point with all coordinates set to the mininum value.
+ static const point<G,C>& minus_infty();
+
protected:
algebra::vec<G::dim, C> coord_;
};
+
+ /// FIXME...
+ template <typename G, typename C>
+ const algebra::vec<G::dim - 1, C>& cut_(const point<G,C>& p);
+
+ template <typename C>
+ const util::yes& cut_(const point<grid::tick,C>& p);
+
+
namespace util
{
@@ -208,7 +233,7 @@
template <typename G, typename C>
inline
- C point<G,C>::operator[](unsigned i) const
+ const C& point<G,C>::operator[](unsigned i) const
{
assert(i < dim);
return this->coord_[i];
@@ -222,6 +247,23 @@
return this->coord_[i];
}
+ template <typename G, typename C>
+ inline
+ const C&
+ point<G,C>::last_coord() const
+ {
+ return this->coord_[dim - 1];
+ }
+
+ template <typename G, typename C>
+ inline
+ C&
+ point<G,C>::last_coord()
+ {
+ return this->coord_[dim - 1];
+ }
+
+
// Constructors.
template <typename G, typename C>
@@ -395,6 +437,43 @@
}
+ template <typename G, typename C>
+ inline
+ const point<G,C>&
+ point<G,C>::plus_infty()
+ {
+ static const point<G,C> the_(all_to(mln_max(C)));
+ return the_;
+ }
+
+ template <typename G, typename C>
+ inline
+ const point<G,C>&
+ point<G,C>::minus_infty()
+ {
+ static const point<G,C> the_(all_to(mln_min(C)));
+ return the_;
+ }
+
+
+ template <typename G, typename C>
+ inline
+ const algebra::vec<G::dim - 1, C>&
+ cut_(const point<G,C>& p)
+ {
+ return *(const algebra::vec<G::dim - 1, C>*)(& p.to_vec());
+ }
+
+ template <typename C>
+ inline
+ const util::yes&
+ cut_(const point<grid::tick,C>& p)
+ {
+ util::yes* the_;
+ return *the_;
+ }
+
+
namespace util
{
Index: mln/core/window.hh
--- mln/core/window.hh (revision 2153)
+++ mln/core/window.hh (working copy)
@@ -255,7 +255,7 @@
const std::vector<D>&
window<D>::std_vector() const
{
- return dps_.vect();
+ return dps_.std_vector();
}
template <typename D>
Index: mln/core/category.hh
--- mln/core/category.hh (revision 2153)
+++ mln/core/category.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -33,6 +33,9 @@
* \brief Definition of the category holder type.
*/
+# include <mln/metal/equal.hh>
+
+
namespace mln
{
@@ -70,6 +73,45 @@
typedef typename category<T>::ret ret;
};
+
+
+ // Utility meta-function: from a category and a type, get the super category.
+
+ namespace internal
+ {
+
+ template < typename Category, typename T >
+ struct helper_super_category_;
+
+ template < template <class> class Category, typename T >
+ struct helper_super_category_< Category<void>, T >
+ {
+ typedef typename Category<void>::super ret; // One super category: keep it.
+ };
+
+ template < template <class> class Category, typename S, typename T >
+ struct helper_super_category_< Category<S>, T >
+ :
+ private metal::equal< typename Category<void>::super, void* >::check_t
+ {
+ // New case.
+ typedef S ret;
+ };
+
+ // For bwd in-compatibility.
+ template < template <class> class Category, typename T >
+ struct helper_super_category_< Category<void*>, T >;
+
+
+ template < typename Category, typename T >
+ struct super_category_ // Entry.
+ {
+ typedef typename helper_super_category_< Category, T >::ret ret;
+ };
+
+ } // end of namespace mln::internal
+
+
} // end of namespace mln
Index: mln/core/contract.hh
--- mln/core/contract.hh (revision 2153)
+++ mln/core/contract.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -48,8 +48,24 @@
/// Postcondition.
# define mln_postcondition(expr) assert(expr)
+
+namespace mln
+{
+
/// Implication.
-# define mln_implies(lexpr, repxr) assert(! (rexpr) || (lexpr))
+ bool implies(bool lexpr, bool rexpr);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ bool implies(bool lexpr, bool rexpr)
+ {
+ return ! (rexpr) || (lexpr);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
#endif // ! MLN_CORE_CONTRACT_HH
Index: mln/core/internal/coord_impl.hh
--- mln/core/internal/coord_impl.hh (revision 2153)
+++ mln/core/internal/coord_impl.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -57,7 +57,7 @@
template <typename C, typename E>
struct coord_impl_<1, C, E>
{
- C ind() const;
+ const C& ind() const;
private:
typedef coord_impl_<1, C, E> self_;
@@ -67,17 +67,17 @@
template <typename C, typename E>
struct coord_impl_<2, C, E>
{
- C row() const;
- C col() const;
+ const C&row() const;
+ const C&col() const;
};
/// \internal
template <typename C, typename E>
struct coord_impl_<3, C, E>
{
- C sli() const;
- C row() const;
- C col() const;
+ const C&sli() const;
+ const C&row() const;
+ const C&col() const;
};
@@ -91,7 +91,7 @@
template <typename C, typename E>
struct mutable_coord_impl_<1, C, E>
{
- C ind() const;
+ const C& ind() const;
C& ind();
};
@@ -99,9 +99,9 @@
template <typename C, typename E>
struct mutable_coord_impl_<2, C, E>
{
- C row() const;
+ const C& row() const;
C& row();
- C col() const;
+ const C& col() const;
C& col();
};
@@ -109,11 +109,11 @@
template <typename C, typename E>
struct mutable_coord_impl_<3, C, E>
{
- C sli() const;
+ const C& sli() const;
C& sli();
- C row() const;
+ const C& row() const;
C& row();
- C col() const;
+ const C& col() const;
C& col();
};
@@ -126,7 +126,7 @@
template <typename C, typename E>
inline
- C coord_impl_<1, C, E>::ind() const
+ const C& coord_impl_<1, C, E>::ind() const
{
return internal::force_exact<E>(*this)[0];
}
@@ -135,14 +135,14 @@
template <typename C, typename E>
inline
- C coord_impl_<2, C, E>::row() const
+ const C& coord_impl_<2, C, E>::row() const
{
return internal::force_exact<E>(*this)[0];
}
template <typename C, typename E>
inline
- C coord_impl_<2, C, E>::col() const
+ const C& coord_impl_<2, C, E>::col() const
{
return internal::force_exact<E>(*this)[1];
}
@@ -151,21 +151,21 @@
template <typename C, typename E>
inline
- C coord_impl_<3, C, E>::sli() const
+ const C& coord_impl_<3, C, E>::sli() const
{
return internal::force_exact<E>(*this)[0];
}
template <typename C, typename E>
inline
- C coord_impl_<3, C, E>::row() const
+ const C& coord_impl_<3, C, E>::row() const
{
return internal::force_exact<E>(*this)[1];
}
template <typename C, typename E>
inline
- C coord_impl_<3, C, E>::col() const
+ const C& coord_impl_<3, C, E>::col() const
{
return internal::force_exact<E>(*this)[2];
}
@@ -177,7 +177,7 @@
template <typename C, typename E>
inline
- C mutable_coord_impl_<1, C, E>::ind() const
+ const C& mutable_coord_impl_<1, C, E>::ind() const
{
return internal::force_exact<E>(*this)[0];
}
@@ -193,7 +193,7 @@
template <typename C, typename E>
inline
- C mutable_coord_impl_<2, C, E>::row() const
+ const C& mutable_coord_impl_<2, C, E>::row() const
{
return internal::force_exact<E>(*this)[0];
}
@@ -207,7 +207,7 @@
template <typename C, typename E>
inline
- C mutable_coord_impl_<2, C, E>::col() const
+ const C& mutable_coord_impl_<2, C, E>::col() const
{
return internal::force_exact<E>(*this)[1];
}
@@ -223,7 +223,7 @@
template <typename C, typename E>
inline
- C mutable_coord_impl_<3, C, E>::sli() const
+ const C& mutable_coord_impl_<3, C, E>::sli() const
{
return internal::force_exact<E>(*this)[0];
}
@@ -237,7 +237,7 @@
template <typename C, typename E>
inline
- C mutable_coord_impl_<3, C, E>::row() const
+ const C& mutable_coord_impl_<3, C, E>::row() const
{
return internal::force_exact<E>(*this)[1];
}
@@ -251,7 +251,7 @@
template <typename C, typename E>
inline
- C mutable_coord_impl_<3, C, E>::col() const
+ const C& mutable_coord_impl_<3, C, E>::col() const
{
return internal::force_exact<E>(*this)[2];
}
Index: mln/core/internal/site_relative_iterator_base.hh
--- mln/core/internal/site_relative_iterator_base.hh (revision 2153)
+++ mln/core/internal/site_relative_iterator_base.hh (working copy)
@@ -81,7 +81,7 @@
/// sub-classes provide an update() method for the client to say
/// that she really want to read the iterator just after the
/// center has changed.
- const mln_psite(S)& unproxy() const;
+ const mln_psite(S)& subj_();
/// Hook to the current location.
const mln_psite(S)& p_hook_() const;
@@ -167,7 +167,7 @@
template <typename S, typename E>
inline
const mln_psite(S)&
- site_relative_iterator_base<S,E>::unproxy() const
+ site_relative_iterator_base<S,E>::subj_()
{
mln_psite(S) p_now = exact(this)->compute_p_();
mln_assertion(p_now == p_);
Index: mln/core/internal/site_iterator_base.hh
--- mln/core/internal/site_iterator_base.hh (revision 2153)
+++ mln/core/internal/site_iterator_base.hh (working copy)
@@ -61,12 +61,7 @@
*/
template <typename S, typename E>
struct site_iterator_base : Site_Iterator<E>,
-
- proxy_impl< mln_psite(S), E>,
-
- site_impl< false, // Constant access to site /
subject.
- mln_site(S),
- E >
+ proxy_impl< const mln_psite(S)&, E>
{
/// The associated site type (as a Site_Proxy).
typedef mln_site(S) site;
@@ -83,14 +78,8 @@
*/
operator mln_site(S)() const;
- /// The associated subject type (as a Proxy).
- typedef mln_psite(S) subject;
-
- /// The associated q_subject type (as a Proxy).
- typedef const mln_psite(S)& q_subject;
-
/// Give the subject (required by the Proxy interface).
- const mln_psite(S)& unproxy() const;
+ const mln_psite(S)& subj_();
/// Give the target address. It might be 0.
const S*& target_();
@@ -101,6 +90,10 @@
/// The target.
const S* s_;
+
+ private:
+
+ typedef proxy_impl< const mln_psite(S)&, E> super_;
};
@@ -117,9 +110,7 @@
inline
site_iterator_base<S, E>::operator mln_site(S)() const
{
- typedef proxy_impl<mln_psite(S), E> super;
- mln_precondition(exact(this)->is_valid());
- return this->super::operator site(); // Featured by
internal::proxy_impl<*>.
+ return this->to_site();
}
template <typename S, typename E>
@@ -127,14 +118,14 @@
const mln_site(S)&
site_iterator_base<S, E>::to_site() const
{
- mln_precondition(exact(*this).is_valid()); // FIXME: OK?
- return internal::to_site( exact(this)->p_hook_() );
+ mln_precondition(exact(*this).is_valid());
+ return this->get_subject();
}
template <typename S, typename E>
inline
const mln_psite(S)&
- site_iterator_base<S, E>::unproxy() const
+ site_iterator_base<S, E>::subj_()
{
return exact(this)->p_hook_();
}
Index: mln/core/internal/site_set_base.hh
--- mln/core/internal/site_set_base.hh (revision 2153)
+++ mln/core/internal/site_set_base.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -30,14 +30,12 @@
/*! \file mln/core/internal/site_set_base.hh
*
- * \brief Definition of a base class for site set classes.
+ * \brief Definition of the common base class for all site set
+ * classes.
*/
# include <mln/core/concept/site_set.hh>
# include <mln/core/concept/site_proxy.hh>
-# include <mln/core/grids.hh>
-# include <mln/metal/is_a.hh>
-# include <mln/metal/if.hh>
namespace mln
@@ -53,12 +51,22 @@
template <typename P, typename E>
struct site_set_base_ : public Site_Set<E>
{
-
/// Site associated type.
- typedef typename internal::site_from<P>::ret site;
+ typedef typename subject<P>::ret site;
+
+ /// Test if the site set is empty. This final method dispatches
+ /// to is_empty_ whose default implementation relies on the
+ /// 'nsites' method.
+ bool is_empty() const;
protected:
site_set_base_();
+
+ private:
+ // Default impl based on the number of sites. It can be
+ // overridden in subclasses that do not feature the 'nsites'
+ // method.
+ bool is_empty_() const;
};
@@ -70,6 +78,22 @@
{
}
+ template <typename S, typename E>
+ inline
+ bool
+ site_set_base_<S,E>::is_empty() const
+ {
+ return exact(this)->is_empty_();
+ }
+
+ template <typename S, typename E>
+ inline
+ bool
+ site_set_base_<S,E>::is_empty_() const
+ {
+ return exact(this)->nsites() == 0;
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::internal
Index: mln/core/internal/data.hh
--- mln/core/internal/data.hh (revision 2153)
+++ mln/core/internal/data.hh (working copy)
@@ -31,6 +31,8 @@
/*! \file mln/core/internal/data.hh
*
* \brief Declaration of the type of image data.
+ *
+ * \todo Rename as image_data (more explicit!)
*/
Index: mln/core/internal/image_base.hh
--- mln/core/internal/image_base.hh (revision 2153)
+++ mln/core/internal/image_base.hh (working copy)
@@ -30,7 +30,7 @@
/*! \file mln/core/internal/image_base.hh
*
- * \brief Definition of a base class for some images.
+ * \brief Definition of the common base class for all images.
*/
# include <mln/core/concept/image.hh>
@@ -38,6 +38,7 @@
# include <mln/core/trait/qlf_value.hh>
# include <mln/core/internal/check/image_all.hh>
# include <mln/core/internal/data.hh>
+# include <mln/core/internal/morpher_lvalue.hh>
# include <mln/util/tracked_ptr.hh>
@@ -60,23 +61,6 @@
namespace internal
{
- /*! \internal Return the lvalue type when an image with type \c I is
- * morphed.
- *
- */
- template <typename I>
- struct morpher_lvalue_
- {
- typedef mln_lvalue(I) ret;
- };
-
- template <typename I>
- struct morpher_lvalue_< const I >
- {
- typedef mln_rvalue(I) ret;
- };
-
-
template <typename E>
struct image_checked_
@@ -88,10 +72,8 @@
- /*! \internal A base class for images.
- * Parameter \p S is a point set type.
- *
- */
+ /// \internal A base class for images. Parameter \p S is the
+ /// image site set type.
template <typename S, typename E>
struct image_base
:
Index: mln/core/internal/check/image_all.hh
--- mln/core/internal/check/image_all.hh (revision 2153)
+++ mln/core/internal/check/image_all.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -44,8 +44,7 @@
namespace internal
{
- /*! \internal Namespace of all image-related internal checks.
- */
+ /// \internal Namespace of all image-related internal checks.
namespace check
{
Index: mln/core/internal/check/image_fastest.hh
--- mln/core/internal/check/image_fastest.hh (revision 2153)
+++ mln/core/internal/check/image_fastest.hh (working copy)
@@ -118,6 +118,9 @@
unsigned (E::*m8)() const = & E::nelements;
m8 = 0;
+ unsigned (E::*m9)(const psite& p) const = & E::index_of_point;
+ m9 = 0;
+
// FIXME: how to check that qixter are defined when W is unknown!
}
Index: mln/core/internal/morpher_lvalue.hh
--- mln/core/internal/morpher_lvalue.hh (revision 0)
+++ mln/core/internal/morpher_lvalue.hh (revision 0)
@@ -0,0 +1,64 @@
+// Copyright (C) 2007, 2008 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 MLN_CORE_INTERNAL_MORPHER_LVALUE_HH
+# define MLN_CORE_INTERNAL_MORPHER_LVALUE_HH
+
+/*! \file mln/core/internal/morpher_lvalue.hh
+ *
+ * \brief Definition of a base class for some images.
+ */
+
+# include <mln/core/macros.hh>
+
+
+namespace mln
+{
+
+ namespace internal
+ {
+
+ /// \internal Return the lvalue type when an image with type \c I
+ /// is morphed.
+ template <typename I>
+ struct morpher_lvalue_
+ {
+ typedef mln_lvalue(I) ret;
+ };
+
+ template <typename I>
+ struct morpher_lvalue_< const I >
+ {
+ typedef mln_rvalue(I) ret;
+ };
+
+ } // end of namespace mln::internal
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_INTERNAL_MORPHER_LVALUE_HH
Index: mln/core/internal/image_identity.hh
--- mln/core/internal/image_identity.hh (revision 2153)
+++ mln/core/internal/image_identity.hh (working copy)
@@ -31,6 +31,9 @@
/*! \file mln/core/internal/image_identity.hh
*
* \brief Definition of a base class for image morphers w.r.t. identity.
+ *
+ * \todo Move "fastest impl" elsewhere; it can be used by some other
+ * classes.
*/
# include <mln/core/internal/image_morpher.hh>
@@ -43,12 +46,90 @@
{
+ // Fastest.
+
+ template <typename trait_speed, typename I, typename E>
+ struct image_identity_impl__fastest
+ {
+ // Nothing.
+ };
+
+ template <typename I, typename E>
+ struct image_identity_impl__fastest< mln::trait::image::speed::fastest, I, E >
+ {
+ private:
+
+ mlc_const(I)& del_() const
+ {
+ return * internal::force_exact<const E>(*this).delegatee_();
+ }
+
+ I& del_()
+ {
+ return * internal::force_exact<E>(*this).delegatee_();
+ }
+
+ public:
+
+ int delta_index(const mln_deduce(I, psite, delta)& dp) const
+ {
+ return del_().delta_index(dp);
+ }
+
+ mln_site(I) point_at_index(unsigned i) const
+ {
+ return del_().point_at_index(i);
+ }
+
+ unsigned border() const
+ {
+ return del_().border();
+ }
+
+ mln_qlf_value(I)* buffer()
+ {
+ return del_().buffer();
+ }
+
+ const mln_value(I)* buffer() const
+ {
+ return del_().buffer();
+ }
+
+ mln_rvalue(I) element(unsigned i) const
+ {
+ return del_().element(i);
+ }
+
+ mln_lvalue(I) element(unsigned i)
+ {
+ return del_().element(i);
+ }
+
+ unsigned nelements() const
+ {
+ return del_().nelements();
+ }
+ };
+
+ // Facade.
+
+ template <typename I, typename E>
+ struct image_identity_impl
+ : image_identity_impl__fastest< mln_trait_image_speed(E), I, E >
+ {
+ };
+
+
+
/*! \internal A base class for image morphers w.r.t. identity.
* Parameter \p S is a point set type.
*
*/
template <typename I, typename S, typename E>
- class image_identity : public image_morpher<I, S, E>
+ class image_identity
+ : public image_identity_impl<I, E>,
+ public image_morpher<I, S, E>
{
public:
@@ -85,6 +166,7 @@
};
+
# ifndef MLN_INCLUDE_ONLY
template <typename I, typename S, typename E>
Index: mln/core/internal/piter_adaptor.hh
--- mln/core/internal/piter_adaptor.hh (revision 2153)
+++ mln/core/internal/piter_adaptor.hh (working copy)
@@ -81,6 +81,10 @@
/// Change the site set targeted by this iterator.
void change_target(const S& s);
+ /// Change the site set targeted by pi_. This default impl is a
+ /// no-op. This method might be overridden.
+ void pi_change_target_(const S& s);
+
protected:
/// The adaptee site iterator.
@@ -152,11 +156,18 @@
this->s_ = & s;
// p might be also updated since it can hold a pointer towards
// the set it designates, so:
- pi_.change_target( exact(this)->pi_set_from_(s) );
+ exact(this)->pi_change_target_(s);
// Last:
this->invalidate();
}
+ template <typename Pi, typename S, typename E>
+ inline
+ void
+ piter_adaptor_<Pi,S,E>::pi_change_target_(const S& s)
+ {
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::internal
Index: mln/core/internal/pseudo_site_base.hh
--- mln/core/internal/pseudo_site_base.hh (revision 2153)
+++ mln/core/internal/pseudo_site_base.hh (working copy)
@@ -46,24 +46,20 @@
*
* Parameter \c P is FIXME: a point site type.
*/
- template <bool is_mutable, typename P, typename E>
+ template <typename P, typename E>
struct pseudo_site_base_ : Pseudo_Site<E>,
-
- proxy_impl<P, E>,
-
- site_impl< is_mutable,
- typename site_from<P>::ret,
- E >
+ proxy_impl<P, E>
{
+ private:
+ typedef typename proxy_impl<P, E>::HOT_actual_subject q_site_;
- // The associated site type.
- typedef typename internal::site_from<P>::ret site;
+ public:
- // The associated subject type (as a Proxy).
- typedef P subject;
+ // The associated site type.
+ typedef mlc_unqualif(q_site_) site;
- // The associated q_subject type (as a Proxy).
- typedef const P& q_subject;
+ // Direct access to the site.
+ const site& to_site() const;
protected:
pseudo_site_base_();
@@ -72,10 +68,18 @@
#ifndef MLN_INCLUDE_ONLY
- template <bool is_mutable, typename P, typename E>
+ template <typename P, typename E>
+ inline
+ pseudo_site_base_<P, E>::pseudo_site_base_()
+ {
+ }
+
+ template <typename P, typename E>
inline
- pseudo_site_base_<is_mutable, P, E>::pseudo_site_base_()
+ const typename pseudo_site_base_<P, E>::site&
+ pseudo_site_base_<P, E>::to_site() const
{
+ return this->get_subject();
}
#endif // ! MLN_INCLUDE_ONLY
Index: mln/core/point1d.hh
--- mln/core/point1d.hh (revision 2153)
+++ mln/core/point1d.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -43,7 +43,7 @@
/*! \brief Type alias for a point defined on the 1D square grid with
* integer coordinates.
*/
- typedef point_<grid::tick, int> point1d;
+ typedef point<grid::tick, def::coord> point1d;
} // end of namespace mln
Index: mln/core/point3d.hh
--- mln/core/point3d.hh (revision 2153)
+++ mln/core/point3d.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -43,7 +43,7 @@
/*! \brief Type alias for a point defined on the 3D square grid with
* integer coordinates.
*/
- typedef point_<grid::cube, int> point3d;
+ typedef point_<grid::cube, def::coord> point3d;
} // end of namespace mln
Index: mln/core/p_set_of.hh
--- mln/core/p_set_of.hh (revision 0)
+++ mln/core/p_set_of.hh (revision 0)
@@ -0,0 +1,237 @@
+// Copyright (C) 2008 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 MLN_CORE_P_SET_OF_HH
+# define MLN_CORE_P_SET_OF_HH
+
+/*! \file mln/core/p_set_of.hh
+ *
+ * \brief Definition of a set of site sets.
+ *
+ * \todo Zed: Add nsites and bbox when possible (see p_vaccess).
+ */
+
+# include <mln/core/p_double.hh>
+# include <mln/core/internal/site_set_base.hh>
+# include <mln/util/set.hh>
+
+
+
+namespace mln
+{
+
+ // Forward declaration.
+ template <typename S> class p_set_of;
+
+
+ namespace trait
+ {
+
+ template <typename S>
+ struct site_set_< p_set_of<S> >
+ {
+ typedef trait::site_set::nsites::unknown nsites;
+ typedef trait::site_set::bbox::unknown bbox;
+ typedef trait::site_set::contents::growing contents;
+ typedef trait::site_set::arity::multiple arity;
+ };
+
+ } // end of namespace trait
+
+
+
+ /*! \brief p_set_of is a set of site sets.
+ *
+ * Parameter \c S is the type of the contained site sets.
+ */
+ template <typename S>
+ class p_set_of : public internal::site_set_base_< mln_element(S),
+ p_set_of<S> >,
+ private mlc_is_a(S, Site_Set)::check_t
+ {
+ typedef p_set_of<S> self_;
+ typedef util::set<S> set_;
+ public:
+
+ /// Element associated type.
+ typedef S element;
+
+
+ /// Psite associated type.
+ typedef p_double_psite<self_, element> psite;
+
+ /// Forward Site_Iterator associated type.
+ typedef p_double_piter<self_,
+ mln_fwd_iter(set_),
+ mln_fwd_piter(S)> fwd_piter;
+
+ /// Backward Site_Iterator associated type.
+ typedef p_double_piter<self_,
+ mln_bkd_iter(set_),
+ mln_bkd_piter(S)> bkd_piter;
+
+ /// Site_Iterator associated type.
+ typedef fwd_piter piter;
+
+
+ /// Constructor without arguments.
+ p_set_of();
+
+
+ /// Test if \p p belongs to this point set.
+ bool has(const psite&) const;
+
+ /// Test if this set of runs is valid.
+ bool is_valid() const;
+
+
+ /// Insertion element associated type.
+ typedef S i_element;
+
+ /// Insert a site set \p s.
+ void insert(const S& s);
+
+
+ /// Return the \p i-th site set.
+ const S& operator[](unsigned i) const;
+
+
+ /// Return the size of this site set in memory.
+ std::size_t memory_size() const;
+
+ /// Hook to the set of runs.
+ const util::set<S>& set_hook_() const;
+
+
+ // Required by p_double-related classes.
+ const util::set<S>& set_1_() const;
+ template <typename I>
+ const S& set_2_(const I& it) const;
+
+ protected:
+
+ /// Set of site sets.
+ util::set<S> s_;
+ };
+
+
+
+ template <typename S>
+ std::ostream& operator<<(std::ostream& ostr, const p_set_of<S>&
s);
+
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename S>
+ inline
+ p_set_of<S>::p_set_of()
+ {
+ }
+
+ template <typename S>
+ inline
+ bool
+ p_set_of<S>::has(const psite&) const
+ {
+ // FIXME
+ return true;
+ }
+
+ template <typename S>
+ inline
+ bool
+ p_set_of<S>::is_valid() const
+ {
+ return true;
+ }
+
+ template <typename S>
+ inline
+ void
+ p_set_of<S>::insert(const S& s)
+ {
+ s_.append(s);
+ }
+
+ template <typename S>
+ inline
+ const S&
+ p_set_of<S>::operator[](unsigned i) const
+ {
+ mln_precondition(i < s_.nelements());
+ return s_[i];
+ }
+
+
+ template <typename S>
+ inline
+ std::size_t
+ p_set_of<S>::memory_size() const
+ {
+ return s_.memory_size();
+ }
+
+ template <typename S>
+ inline
+ const util::set<S>&
+ p_set_of<S>::set_hook_() const
+ {
+ return s_;
+ }
+
+ template <typename S>
+ inline
+ const util::set<S>&
+ p_set_of<S>::set_1_() const
+ {
+ return s_;
+ }
+
+ template <typename S>
+ template <typename I>
+ inline
+ const S&
+ p_set_of<S>::set_2_(const I& it) const
+ {
+ return it.element();
+ }
+
+
+ template <typename S>
+ std::ostream& operator<<(std::ostream& ostr, const p_set_of<S>&
s)
+ {
+ return ostr << s.set_hook_();
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_P_SET_OF_HH
Index: mln/core/box_piter.hh
--- mln/core/box_piter.hh (revision 2153)
+++ mln/core/box_piter.hh (working copy)
@@ -181,17 +181,32 @@
box_fwd_piter_<P>::next_()
{
for (int i = dim - 1; i >= 0; --i)
- if (p_[i] == s_->pmax()[i])
- p_[i] = s_->pmin()[i];
- else
+ if (p_[i] != s_->pmax()[i])
{
++p_[i];
break;
}
- if (p_ == s_->pmin())
+ else
+ {
+ p_[i] = s_->pmin()[i];
+ if (i == 0)
invalidate_();
}
+ // memo
+
+// for (int i = dim - 1; i >= 0; --i)
+// if (p_[i] != s_->pmax()[i])
+// {
+// ++p_[i];
+// break;
+// }
+// else
+// p_[i] = s_->pmin()[i];
+// if (p_ == s_->pmin())
+// invalidate_();
+ }
+
// box_bkd_piter_<P>
Index: mln/core/p_vaccess.hh
--- mln/core/p_vaccess.hh (revision 0)
+++ mln/core/p_vaccess.hh (revision 0)
@@ -0,0 +1,412 @@
+// Copyright (C) 2007, 2008 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 MLN_CORE_P_VACCESS_HH
+# define MLN_CORE_P_VACCESS_HH
+
+/*! \file mln/core/p_vaccess.hh
+ *
+ * \todo Factor the implementation classes for site set based on a
+ * couple of structures. Such piece of code shall be used in p_set_of
+ * and p_array_of.
+ *
+ * \todo Fix the FIXMEs.
+ */
+
+# include <utility>
+# include <mln/core/p_double.hh>
+# include <mln/core/internal/site_set_base.hh>
+# include <mln/core/internal/pseudo_site_base.hh>
+# include <mln/accu/bbox.hh>
+
+
+
+namespace mln
+{
+
+ // Forward declaration.
+ template <typename Sv, typename Sp> class p_vaccess;
+
+
+
+ namespace trait
+ {
+
+ template <typename Sv, typename Sp>
+ struct site_set_< p_vaccess<Sv,Sp> >
+ {
+ typedef mln_trait_site_set_nsites(Sp) nsites;
+ typedef mln_trait_site_set_bbox(Sp) bbox;
+ typedef trait::site_set::contents::growing contents;
+ typedef trait::site_set::arity::multiple arity;
+ };
+
+ } // end of namespace trait
+
+
+
+ namespace internal
+ {
+
+ // For .nsites()
+
+ template <typename trait_nsites, typename Sp>
+ struct p_vaccess_impl__nsites
+ {
+ protected:
+ template <typename T>
+ void update_nsites_(const T&); // No-op.
+ };
+
+ template <typename Sp>
+ struct p_vaccess_impl__nsites< trait::site_set::nsites::known, Sp>
+ {
+ p_vaccess_impl__nsites();
+ unsigned nsites() const;
+ protected:
+ void update_nsites_(const mln_site(Sp)& p);
+ template <typename S>
+ void update_nsites_(const Site_Set<S>& s);
+ unsigned nsites_;
+ };
+
+ // For .bbox()
+
+ template <typename trait_bbox, typename Sp>
+ struct p_vaccess_impl__bbox
+ {
+ typedef const mln::box<mln_site(Sp)>& q_box;
+ q_box bbox() const;
+
+ protected:
+ void update_bbox_(const mln_site(Sp)& p);
+ template <typename S>
+ void update_bbox_(const Site_Set<S>& s);
+
+ accu::bbox<mln_site(Sp)> bb_;
+ };
+
+ template <typename Sp>
+ struct p_vaccess_impl__bbox< trait::site_set::nsites::unknown, Sp >
+ {
+ protected:
+ template <typename T>
+ void update_bbox_(const T&); // No-op.
+ };
+
+ // Facade.
+
+ template <typename Sp>
+ struct p_vaccess_impl
+ : p_vaccess_impl__nsites< mln_trait_site_set_nsites(Sp), Sp>,
+ p_vaccess_impl__bbox < mln_trait_site_set_bbox(Sp), Sp>
+ {
+ };
+
+ } // end of namespace mln::internal
+
+
+
+ /*! \brief FIXME
+ */
+ template <typename Sv, typename Sp>
+ class p_vaccess : public internal::site_set_base_< mln_site(Sp),
+ p_vaccess<Sv,Sp> >,
+ public internal::p_vaccess_impl< Sp >
+ {
+ typedef p_vaccess<Sv,Sp> self_;
+ public:
+
+ /// Value associated type.
+ typedef mln_value(Sv) value;
+
+
+ /// Psite associated type.
+ typedef p_double_psite<self_, Sp> psite;
+
+ /// Forward Site_Iterator associated type.
+ typedef p_double_piter<self_, mln_fwd_viter(Sv), mln_fwd_piter(Sp)> fwd_piter;
+
+ /// Backward Site_Iterator associated type.
+ typedef p_double_piter<self_, mln_bkd_viter(Sv), mln_bkd_piter(Sp)> bkd_piter;
+
+ /// Site_Iterator associated type.
+ typedef fwd_piter piter;
+
+
+ /// Constructor.
+ p_vaccess();
+ p_vaccess(const Sv& vset);
+
+
+ /// Test if \p p belongs to this site set.
+ bool has(const psite& p) const;
+
+ /// Test if the couple (value \p v, psite \p p) belongs to this
+ /// site set.
+ bool has(const value& v, const mln_psite(Sp)& p) const;
+
+ /// Test if this site set is valid.
+ bool is_valid() const;
+
+
+ /// Element associated type.
+ typedef mln_element(Sp) element;
+
+ /// Insertion element associated type.
+ typedef std::pair<value, element> i_element;
+
+ /// Insert a pair \p v_e (value v, element e).
+ void insert(const i_element& v_e);
+
+ /// Insert \p e at value \p v.
+ void insert(const value& v, const element& e);
+
+
+ /// Return the site set at value \p v.
+ const Sp& operator()(const value& v) const;
+
+ /// Return the size of this site set in memory.
+ std::size_t memory_size() const;
+
+
+ /// Give the set of values.
+ const Sv& values() const;
+
+ // Required by p_double-related classes.
+ const Sv& set_1_() const;
+ const Sp& set_2_(const value& v) const;
+
+ protected:
+
+ Sv vs_;
+ std::vector<Sp> ps_;
+ };
+
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // p_vaccess<Sv,Sp>
+
+ template <typename Sv, typename Sp>
+ inline
+ p_vaccess<Sv,Sp>::p_vaccess()
+ : vs_(),
+ ps_(vs_.nvalues())
+ {
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ p_vaccess<Sv,Sp>::p_vaccess(const Sv& vset)
+ : vs_(vset),
+ ps_(vs_.nvalues())
+ {
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ bool
+ p_vaccess<Sv,Sp>::has(const psite&) const
+ {
+ // FIXME
+ return true;
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ bool
+ p_vaccess<Sv,Sp>::has(const value& v, const mln_psite(Sp)& p) const
+ {
+ return ps_[vs_.index_of(v)].has(p);
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ bool
+ p_vaccess<Sv,Sp>::is_valid() const
+ {
+ // FIXME
+ return true;
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ void
+ p_vaccess<Sv,Sp>::insert(const value& v, const element& e)
+ {
+ ps_[vs_.index_of(v)].insert(e);
+ this->update_nsites_(e);
+ this->update_bbox_(e);
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ void
+ p_vaccess<Sv,Sp>::insert(const i_element& v_e)
+ {
+ insert(v_e.first, v_e.second);
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ const Sp&
+ p_vaccess<Sv,Sp>::operator()(const value& v) const
+ {
+ return ps_[vs_.index_of(v)];
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ std::size_t
+ p_vaccess<Sv,Sp>::memory_size() const
+ {
+ std::size_t mem = 0;
+ for (unsigned i = 0; i < ps_.size(); ++i)
+ mem += ps_[i].memory_size();
+ return sizeof(*this) + mem;
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ const Sv&
+ p_vaccess<Sv,Sp>::values() const
+ {
+ return vs_;
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ const Sv&
+ p_vaccess<Sv,Sp>::set_1_() const
+ {
+ return vs_;
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ const Sp&
+ p_vaccess<Sv,Sp>::set_2_(const value& v) const
+ {
+ return ps_[vs_.index_of(v)];
+ }
+
+
+ namespace internal
+ {
+
+ // p_vaccess_impl__nsites
+
+ template <typename trait_nsites, typename Sp>
+ template <typename T>
+ inline
+ void
+ p_vaccess_impl__nsites<trait_nsites, Sp>::update_nsites_(const T&)
+ {
+ // No-op.
+ }
+
+ template <typename Sp>
+ inline
+ p_vaccess_impl__nsites<trait::site_set::nsites::known,
Sp>::p_vaccess_impl__nsites()
+ : nsites_(0)
+ {
+ }
+
+ template <typename Sp>
+ inline
+ unsigned
+ p_vaccess_impl__nsites<trait::site_set::nsites::known, Sp>::nsites() const
+ {
+ return nsites_;
+ }
+
+ template <typename Sp>
+ inline
+ void
+ p_vaccess_impl__nsites<trait::site_set::nsites::known,
Sp>::update_nsites_(const mln_site(Sp)&)
+ {
+ ++nsites_;
+ }
+
+ template <typename Sp>
+ template <typename S>
+ inline
+ void
+ p_vaccess_impl__nsites<trait::site_set::nsites::known,
Sp>::update_nsites_(const Site_Set<S>& s)
+ {
+ nsites_ += exact(s).nsites();
+ }
+
+ // p_vaccess_impl__bbox
+
+ template <typename trait_bbox, typename Sp>
+ inline
+ typename p_vaccess_impl__bbox<trait_bbox, Sp>::q_box
+ p_vaccess_impl__bbox<trait_bbox, Sp>::bbox() const
+ {
+ return bb_.to_result();
+ }
+
+ template <typename trait_bbox, typename Sp>
+ inline
+ void
+ p_vaccess_impl__bbox<trait_bbox, Sp>::update_bbox_(const mln_site(Sp)& p)
+ {
+ bb_.take(p);
+ }
+
+ template <typename trait_bbox, typename Sp>
+ template <typename S>
+ inline
+ void
+ p_vaccess_impl__bbox<trait_bbox, Sp>::update_bbox_(const Site_Set<S>&
s)
+ {
+ bb_.take(exact(s).bbox());
+ }
+
+ template <typename Sp>
+ template <typename T>
+ inline
+ void
+ p_vaccess_impl__bbox< trait::site_set::nsites::unknown, Sp
>::update_bbox_(const T&)
+ {
+ // No-op.
+ }
+
+ } // end of namespace mln::internal
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_P_VACCESS_HH
Index: mln/core/p_queue_fast.hh
--- mln/core/p_queue_fast.hh (revision 2153)
+++ mln/core/p_queue_fast.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -30,68 +30,94 @@
/*! \file mln/core/p_queue_fast.hh
*
- * \brief Definition of a point set class faster but needs more memory
- * space.
+ * \brief Definition of a queue of sites that is fast but uses extra
+ * memory w.r.t. a simple queue.
+ *
+ * \todo Add insert.
*/
-# include <vector>
-# include <deque>
-# include <algorithm>
-# include <iterator>
-
-# include <mln/core/internal/site_set_base.hh>
-# include <mln/core/p_array_piter.hh>
-# include <mln/accu/bbox.hh>
+# include <mln/core/p_array.hh>
namespace mln
{
- // Fwd decls.
- template <typename P> struct p_array_fwd_piter_;
- template <typename P> struct p_array_bkd_piter_;
+ // Forward declaration.
+ template <typename P> class p_queue_fast;
- /*! \brief Point queue class (based on std::deque).
- *
- * This is a mathematical set of points (unique insertion).
- *
- * \todo Make it work with P being a Point_Site.
- *
- * \warning We have some troubles with point set comparison based on
- * a call to npoints() when this container is multiple.
+
+ namespace trait
+ {
+
+ template <typename P>
+ struct site_set_< p_queue_fast<P> >
+ {
+ typedef trait::site_set::nsites::known nsites;
+ typedef trait::site_set::bbox::unknown bbox;
+ typedef trait::site_set::contents::growing contents;
+ typedef trait::site_set::arity::multiple arity;
+ };
+
+ } // end of namespace trait
+
+
+
+ /*! \brief Point queue class (based on p_array<P>).
*/
template <typename P>
class p_queue_fast : public internal::site_set_base_< P, p_queue_fast<P> >
{
+ typedef p_queue_fast<P> self_;
public:
+ /// Element associated type.
+ typedef P element;
+
+ /// Psite associated type.
+ typedef p_indexed_psite<self_> psite;
+
/// Forward Site_Iterator associated type.
- typedef p_array_fwd_piter_<P> fwd_piter;
+ typedef p_indexed_fwd_piter<self_> fwd_piter;
/// Backward Site_Iterator associated type.
- typedef p_array_bkd_piter_<P> bkd_piter;
+ typedef p_indexed_bkd_piter<self_> bkd_piter;
+
+ /// Site_Iterator associated type.
+ typedef fwd_piter piter;
+
/// Constructor.
p_queue_fast();
- /// Test is \p p belongs to this point set.
- bool has(const P& p) const;
+ /// Reserve \p n cells.
+ void reserve(std::size_t n);
- /// Test if queue is empty or not.
- bool is_empty() const;
+ /// Test if \p p belongs to this point set.
+ bool has(const psite& p) const;
- /// Give the number of points.
- std::size_t npoints() const;
+ /// Test if index \p i belongs to this point set.
+ bool has(const util::index& i) const;
+
+ /// This set is always valid so it returns true.
+ bool is_valid() const;
- /// Give the exact bounding box.
- const box_<P>& bbox() const;
+ /// Test if \p p belongs to this point set.
+ bool compute_has(const P& p) const;
+
+ /// Give the number of points.
+ unsigned nsites() const;
- /// Push force a point \p p in the queue.
- p_queue_fast<P>& push_force(const P& p);
/// Push a point \p p in the queue.
- p_queue_fast<P>& push(const P& p);
+ void push(const P& p);
+
+ /// Insertion element associated type.
+ typedef P i_element;
+
+ /// Insert a point \p p (equivalent as 'push').
+ void insert(const P& p);
+
/// Pop (remove) the front point \p p from the queue; \p p is the
/// least recently inserted point.
@@ -106,28 +132,28 @@
/// the queue; \p p is the least recently inserted point.
const P& pop_front();
+
+ /// Purge the queue to save (free) some memory.
+ void purge();
+
/// Clear the queue.
void clear();
- /// Return the corresponding std::vector of points.
- const std::vector<P>& vect() const;
/// Return the \p i-th point.
const P& operator[](unsigned i) const;
+ /// Return the corresponding std::vector of points.
+ const std::vector<P>& std_vector() const;
+
+ /// Return the size of this site set in memory.
+ std::size_t memory_size() const;
+
protected:
- std::vector<P> q_;
- std::size_t begin_;
- std::size_t end_;
-
- mutable std::vector<P> vect_;
- mutable bool vect_needs_update_;
- void vect_update_() const;
-
- mutable accu::bbox<P> bb_;
- mutable bool bb_needs_update_;
- void bb_update_() const;
+ p_array<P> q_;
+ unsigned begin_;
+ unsigned end_;
};
@@ -138,8 +164,6 @@
inline
p_queue_fast<P>::p_queue_fast()
{
- // vect_needs_update_ = false;
- bb_needs_update_ = false;
begin_ = 0;
end_ = 0;
}
@@ -147,88 +171,81 @@
template <typename P>
inline
void
- p_queue_fast<P>::vect_update_() const
+ p_queue_fast<P>::reserve(std::size_t n)
{
- vect_.clear();
- vect_.reserve(q_.size());
- std::copy(q_.begin(), q_.end(),
- std::back_inserter(vect_));
- vect_needs_update_ = false;
+ q_.reserve();
}
template <typename P>
inline
void
- p_queue_fast<P>::bb_update_() const
+ p_queue_fast<P>::purge()
{
- bb_.init();
- for (std::size_t i = this->begin_; i < this->end_; ++i)
- bb_.take(q_[i]);
- bb_needs_update_ = false;
+ std::vector<P>& v = q_.hook_std_vector_();
+ std::copy(v.begin() + begin_,
+ v.begin() + end_,
+ v.begin());
+ v.resize(end_ - begin_);
+ end_ -= begin_;
+ begin_ = 0;
}
template <typename P>
inline
bool
- p_queue_fast<P>::has(const P& p) const
+ p_queue_fast<P>::has(const psite& p) const
{
- for (unsigned i = this->begin_; i < this->end_; ++i)
- if (q_[i] == p)
- return true;
+ mln_precondition(p.target_() == this); // FIXME: Refine.
+ if (p.index() < 0 || unsigned(p.index()) >= nsites())
return false;
+ // The type of rhs below is mln_site(p_array<P>).
+ mln_invariant(p.to_site() == (*this)[p.index()]);
+ return true;
}
template <typename P>
inline
bool
- p_queue_fast<P>::is_empty() const
+ p_queue_fast<P>::has(const util::index& i) const
{
- return (this->begin_ == this->end_);
+ return i >= 0 && unsigned(i) < nsites();
}
template <typename P>
inline
- std::size_t
- p_queue_fast<P>::npoints() const
+ bool
+ p_queue_fast<P>::compute_has(const P& p) const
{
- mln_precondition(this->end_ >= this->begin_);
- return (this->end_ - this->begin_);
+ for (unsigned i = begin_; i < end_; ++i)
+ if (q_[i] == p)
+ return true;
+ return false;
}
template <typename P>
inline
- const box_<P>&
- p_queue_fast<P>::bbox() const
+ bool
+ p_queue_fast<P>::is_valid() const
{
- mln_precondition(npoints() != 0);
- if (bb_needs_update_)
- bb_update_();
- return bb_.to_result();
+ return true;
}
template <typename P>
inline
- p_queue_fast<P>&
- p_queue_fast<P>::push_force(const P& p)
- {
- q_.push_back(p);
- ++this->end_;
- if (! vect_needs_update_)
+ unsigned
+ p_queue_fast<P>::nsites() const
{
- // vect_needs_update_ = true;
- bb_needs_update_ = true;
- }
- return *this;
+ mln_invariant(end_ >= begin_);
+ return end_ - begin_;
}
template <typename P>
inline
- p_queue_fast<P>&
+ void
p_queue_fast<P>::push(const P& p)
{
- mln_precondition(! this->has(p));
- // FIXME: Our choice is "error if multiple insertions"
- return this->push_force(p);
+ q_.append(p);
+ ++end_;
}
template <typename P>
@@ -236,13 +253,8 @@
void
p_queue_fast<P>::pop()
{
- ++this->begin_;
-// q_.pop_front();
-// if (! vect_needs_update_)
-// {
-// vect_needs_update_ = true;
-// bb_needs_update_ = true;
-// }
+ mln_precondition(! this->is_empty());
+ ++begin_;
}
template <typename P>
@@ -259,42 +271,51 @@
const P&
p_queue_fast<P>::pop_front()
{
+ mln_precondition(! this->is_empty());
const P& res = this->front();
-
this->pop();
return res;
}
-
template <typename P>
inline
void
p_queue_fast<P>::clear()
{
- this->end_ = begin_;
-// q_.clear();
-// vect_.clear();
-// vect_needs_update_ = false;
- bb_needs_update_ = false;
+ end_ = begin_;
+ }
+
+ template <typename P>
+ inline
+ const P&
+ p_queue_fast<P>::operator[](unsigned i) const
+ {
+ mln_precondition(i < nsites());
+ return q_[begin_ + i];
+ }
+
+ template <typename P>
+ inline
+ void
+ p_queue_fast<P>::insert(const P& p)
+ {
+ this->push(p);
}
template <typename P>
inline
const std::vector<P>&
- p_queue_fast<P>::vect() const
+ p_queue_fast<P>::std_vector() const
{
- if (vect_needs_update_)
- vect_update_();
- return vect_;
+ return q_.std_vector();
}
template <typename P>
inline
- const P&
- p_queue_fast<P>::operator[](unsigned i) const
+ std::size_t
+ p_queue_fast<P>::memory_size() const
{
- mln_precondition(i < npoints());
- return q_[begin_ + i];
+ return q_.memory_size() + 2 * sizeof(unsigned);
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/core/sub_image.hh
--- mln/core/sub_image.hh (revision 2153)
+++ mln/core/sub_image.hh (working copy)
@@ -29,13 +29,17 @@
# define MLN_CORE_SUB_IMAGE_HH
/*!
- * \file sub_image.hh
+ * \file mln/core/sub_image.hh
*
* \brief Definition of morpher that makes an image become restricted
* given by a point set.
+ *
+ * \todo Add a special case for "ima | box"; think about some other
+ * special cases...
*/
# include <mln/core/internal/image_domain_morpher.hh>
+# include <mln/core/image/instant.hh>
namespace mln
@@ -119,15 +123,33 @@
+
template <typename I, typename S>
sub_image<const I, S>
operator|(const Image<I>& ima, const Site_Set<S>& pset);
+
+// template <typename I, typename S>
+// sub_image<I, S>
+// operator|(Image<I>& ima, const Site_Set<S>& pset);
+
+
+// REPLACEMENT:
+
template <typename I, typename S>
- sub_image<I, S>
+ instant_< sub_image<I, S> >
operator|(Image<I>& ima, const Site_Set<S>& pset);
+// NEW:
+
+ template <typename I, typename S>
+ sub_image<I, S>
+ operator|(instant_<I> ima, const Site_Set<S>& pset)
+ {
+ return ima.un_instant() | pset;
+ }
+
template <typename I, typename S, typename J>
void init_(tag::image_t, sub_image<I,S>& target, const J& model);
@@ -219,9 +241,18 @@
return tmp;
}
+// template <typename I, typename S>
+// inline
+// sub_image<I, S>
+// operator|(Image<I>& ima, const Site_Set<S>& pset)
+// {
+// sub_image<I, S> tmp(exact(ima), exact(pset));
+// return tmp;
+// }
+
template <typename I, typename S>
inline
- sub_image<I, S>
+ instant_< sub_image<I, S> >
operator|(Image<I>& ima, const Site_Set<S>& pset)
{
sub_image<I, S> tmp(exact(ima), exact(pset));
Index: mln/core/pset_if_piter.hh
--- mln/core/pset_if_piter.hh (revision 2153)
+++ mln/core/pset_if_piter.hh (working copy)
@@ -66,8 +66,8 @@
/// Go to the next point.
void next_();
- /// The set site targeted by pi_.
- const S& pi_set_from_(const pset_if<S,F>& s) const;
+ /// Change the set site targeted by pi_.
+ void pi_change_target_(const pset_if<S,F>& s);
private:
typedef pset_if_piter_<Pi,S,F> self_;
@@ -117,10 +117,10 @@
template <typename Pi, typename S, typename F>
inline
- const S&
- pset_if_piter_<Pi,S,F>::pi_set_from_(const pset_if<S,F>& s) const
+ void
+ pset_if_piter_<Pi,S,F>::pi_change_target_(const pset_if<S,F>& s) const
{
- return s.overset();
+ pi_.change_target(s.overset());
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/core/dpoint.hh
--- mln/core/dpoint.hh (revision 2153)
+++ mln/core/dpoint.hh (working copy)
@@ -33,6 +33,7 @@
* \brief Definition of the generic delta-point class mln::dpoint.
*/
+# include <mln/core/def/coord.hh>
# include <mln/core/concept/gdpoint.hh>
# include <mln/core/internal/coord_impl.hh>
# include <mln/fun/i2v/all.hh>
Index: mln/core/p_array_piter.hh
--- mln/core/p_array_piter.hh (revision 2153)
+++ mln/core/p_array_piter.hh (working copy)
@@ -1,4 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -56,6 +57,10 @@
/// Constructor.
p_array_fwd_piter_(const p_array<P>& arr);
+ /// Constructor.
+ template <typename S>
+ p_array_fwd_piter_(const Site_Set<S>& arr);
+
/// Test if the iterator is valid.
bool is_valid_() const;
@@ -100,6 +105,10 @@
/// Constructor.
p_array_bkd_piter_(const p_array<P>& arr);
+ /// Constructor.
+ template <typename S>
+ p_array_bkd_piter_(const Site_Set<S>& arr);
+
/// Test if the iterator is valid.
bool is_valid_() const;
@@ -145,6 +154,14 @@
}
template <typename P>
+ template <typename S>
+ inline
+ p_array_fwd_piter_<P>::p_array_fwd_piter_(const Site_Set<S>& arr)
+ {
+ this->change_target(exact(arr).array_hook());
+ }
+
+ template <typename P>
inline
bool
p_array_fwd_piter_<P>::is_valid_() const
@@ -204,6 +221,14 @@
}
template <typename P>
+ template <typename S>
+ inline
+ p_array_bkd_piter_<P>::p_array_bkd_piter_(const Site_Set<S>& arr)
+ {
+ this->change_target(exact(arr).array_hook());
+ }
+
+ template <typename P>
inline
bool
p_array_bkd_piter_<P>::is_valid_() const
@@ -251,14 +276,14 @@
int
index_of_in(const p_array_fwd_piter_<P>& p, const A& arr)
{
- return index_of_in(p.unproxy(), arr);
+ return index_of_in(p.unproxy_(), arr);
}
template <typename P, typename A>
int
index_of_in(const p_array_bkd_piter_<P>& p, const A& arr)
{
- return index_of_in(p.unproxy(), arr);
+ return index_of_in(p.unproxy_(), arr);
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/core/image/all.hh
--- mln/core/image/all.hh (revision 0)
+++ mln/core/image/all.hh (revision 0)
@@ -0,0 +1,43 @@
+// Copyright (C) 2008 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 MLN_CORE_IMAGE_ALL_HH
+# define MLN_CORE_IMAGE_ALL_HH
+
+/*! \file mln/core/image/all.hh
+ *
+ * \brief File that includes all image types.
+ *
+ * \todo Make it effective after having moved image-defining files.
+ */
+
+
+# include <mln/core/image/instant.hh>
+// FIXME: Complete...
+
+
+#endif // ! MLN_CORE_IMAGE_ALL_HH
Index: mln/core/image/instant.hh
--- mln/core/image/instant.hh (revision 0)
+++ mln/core/image/instant.hh (revision 0)
@@ -0,0 +1,155 @@
+// Copyright (C) 2008 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 MLN_CORE_IMAGE_INSTANT_HH
+# define MLN_CORE_IMAGE_INSTANT_HH
+
+/*! \file mln/core/instant.hh
+ *
+ * \brief Definition of a morpher that prevent an image from sharing
+ * his data.
+ *
+ * \todo Fix FIXME; see todo in image_identity...
+ */
+
+# include <mln/core/internal/image_identity.hh>
+# include <mln/metal/is_not_const.hh>
+
+
+
+namespace mln
+{
+
+ // Forward declaration.
+ template <typename I> struct instant_;
+
+
+ namespace trait
+ {
+
+ template <typename I>
+ struct image_< instant_<I> > : image_< I > // Same as I except...
+ {
+ // ...this change.
+ typedef trait::image::category::identity_morpher category;
+ };
+
+ } // end of namespace mln::trait
+
+
+
+ namespace internal
+ {
+
+ /// \internal Data structure for \c mln::instant_<I>.
+ template <typename I>
+ struct data< instant_<I> >
+ {
+ data(const I& ima);
+ I ima_;
+ };
+
+ } // end of namespace mln::internal
+
+
+
+
+
+ /*! \brief FIXME
+ *
+ */
+ template <typename I>
+ struct instant_
+
+ : public mln::internal::image_identity< I, mln_pset(I), instant_<I> >,
+ private mlc_is_not_const(I)::check_t
+ {
+
+ /// Skeleton.
+ typedef tag::image_<I> skeleton; // Remove the "instant" envelope.
+
+ /// Constructor.
+ instant_(I& ima);
+
+ /// Remove the "instant" envelope.
+ I& un_instant_();
+ I& un_instant_() const;
+ };
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+ // internal::data< instant_<I> >
+
+ template <typename I>
+ inline
+ data< instant_<I> >::data(const I& ima)
+ : ima_(ima)
+ {
+ }
+
+ } // end of namespace mln::internal
+
+
+ // instant_<I>
+
+ template <typename I>
+ inline
+ instant_<I>::instant_(I& ima)
+ {
+ mln_precondition(ima.has_data());
+ this->data_ = new internal::data< instant_<I> >(ima);
+ }
+
+ template <typename I>
+ inline
+ I&
+ instant_<I>::un_instant_()
+ {
+ mln_precondition(this->has_data());
+ return this->data_->ima_;
+ }
+
+ template <typename I>
+ inline
+ I&
+ instant_<I>::un_instant_() const
+ {
+ mln_precondition(this->has_data());
+ return const_cast<I&>(this->data_->ima_);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_IMAGE_INSTANT_HH
Index: mln/core/box.hh
--- mln/core/box.hh (revision 2153)
+++ mln/core/box.hh (working copy)
@@ -31,6 +31,8 @@
/*! \file mln/core/box.hh
*
* \brief This file defines a generic box class.
+ *
+ * \todo Test if the safety code in box::box() is not too slow.
*/
# include <mln/core/concept/box.hh>
@@ -128,10 +130,13 @@
/// Give a larger box.
box<P> to_larger(unsigned b) const;
- /// Test that the box owns valid data, i.e., pmin is 'less-than'
- /// pmax.
+ /// Test that the box owns valid data, i.e., is initialized and
+ /// with pmin being 'less-than' pmax.
bool is_valid() const;
+ /// Return the size of this site set in memory.
+ std::size_t memory_size() const;
+
protected:
P pmin_, pmax_;
@@ -158,9 +163,9 @@
bool
box<P>::is_valid() const
{
- typedef util::less<P> less_t;
- static const less_t op = less_t();
- return op(pmin_, pmax_);
+ // Validity is: for all i, pmin_[i] <= pmax_[i].
+ // Nota bene: a one-point box is valid.
+ return util::op_less_or_equal(pmin_, pmax_);
}
template <typename P>
@@ -200,7 +205,10 @@
template <typename P>
inline
box<P>::box()
+ : pmin_(P::plus_infty()),
+ pmax_(P::minus_infty())
{
+ // FIXME: The code above can be slow; think about removing it...
}
template <typename P>
@@ -287,6 +295,14 @@
template <typename P>
inline
+ std::size_t
+ box<P>::memory_size() const
+ {
+ return sizeof(*this);
+ }
+
+ template <typename P>
+ inline
std::ostream& operator<<(std::ostream& ostr, const box<P>& b)
{
mln_precondition(b.is_valid());
Index: mln/core/p_queue.hh
--- mln/core/p_queue.hh (revision 2153)
+++ mln/core/p_queue.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -60,7 +60,7 @@
* (i.e., no-op if multiple or allow multiple insertions).
*
* \warning We have some troubles with point set comparison based on
- * a call to npoints() when this container is multiple.
+ * a call to nsites() when this container is multiple.
*/
template <typename P>
class p_queue : public internal::site_set_base_< P, p_queue<P> >
@@ -79,11 +79,8 @@
/// Test is \p p belongs to this point set.
bool has(const P& p) const;
- /// Test if queue is empty or not.
- bool is_empty() const;
-
/// Give the number of points.
- std::size_t npoints() const;
+ unsigned nsites() const;
/// Give the exact bounding box.
const box_<P>& bbox() const;
@@ -178,16 +175,8 @@
template <typename P>
inline
- bool
- p_queue<P>::is_empty() const
- {
- return (q_.empty());
- }
-
- template <typename P>
- inline
- std::size_t
- p_queue<P>::npoints() const
+ unsigned
+ p_queue<P>::nsites() const
{
return q_.size();
}
@@ -197,7 +186,7 @@
const box_<P>&
p_queue<P>::bbox() const
{
- mln_precondition(npoints() != 0);
+ mln_precondition(nsites() != 0);
if (bb_needs_update_)
bb_update_();
return bb_.to_result();
@@ -286,7 +275,7 @@
const P&
p_queue<P>::operator[](unsigned i) const
{
- mln_precondition(i < npoints());
+ mln_precondition(i < nsites());
return q_[i];
}
Index: mln/core/p_key.hh
--- mln/core/p_key.hh (revision 0)
+++ mln/core/p_key.hh (revision 0)
@@ -0,0 +1,652 @@
+// Copyright (C) 2008 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 MLN_CORE_P_KEY_HH
+# define MLN_CORE_P_KEY_HH
+
+/*! \file mln/core/p_key.hh
+ *
+ * \brief Definition of a FIXME
+ *
+ * \todo Be more verbose in run_().
+ */
+
+# include <map>
+# include <mln/core/concept/function.hh>
+# include <mln/core/p_set.hh>
+# include <mln/core/p_double.hh>
+# include <mln/core/internal/site_set_base.hh>
+# include <mln/util/less.hh>
+
+
+namespace mln
+{
+
+ // Forward declaration.
+ template <typename K, typename P> class p_key;
+
+
+
+ namespace trait
+ {
+
+ template <typename K, typename P>
+ struct site_set_< p_key<K,P> >
+ {
+ typedef trait::site_set::nsites::known nsites;
+ typedef trait::site_set::bbox::unknown bbox;
+ typedef trait::site_set::contents::growing contents;
+ typedef trait::site_set::arity::unique arity;
+ };
+
+ } // end of namespace trait
+
+
+
+
+ /*! \brief Priority queue class.
+ *
+ * FIXME
+ */
+ template <typename K, typename P>
+ class p_key : public internal::site_set_base_< P,
+ p_key<K,P> >
+ {
+ typedef p_key<K,P> self_;
+ public:
+
+ /// Element associated type.
+ typedef P element;
+
+
+ /// Psite associated type.
+ typedef p_double_psite< self_, p_set<P> > psite;
+
+ /// Forward Site_Iterator associated type.
+ typedef p_double_piter<self_,
+ mln_fwd_iter(util::set<K>),
+ mln_fwd_piter(p_set<P>)> fwd_piter;
+
+ /// Backward Site_Iterator associated type.
+ typedef p_double_piter<self_,
+ mln_bkd_iter(util::set<K>),
+ mln_bkd_piter(p_set<P>)> bkd_piter;
+
+ /// Site_Iterator associated type.
+ typedef fwd_piter piter;
+
+
+ /// Constructor.
+ p_key();
+
+
+ /// Test is the psite \p p belongs to this site set.
+ bool has(const psite&) const;
+
+ /// Test is the psite \p p belongs to this site set.
+ bool has(const P& p) const;
+
+
+ /// Test this set validity so returns always true.
+ bool is_valid() const;
+
+ /// Give the number of sites.
+ unsigned nsites() const;
+
+
+ /// Insertion element associated type.
+ typedef std::pair<K,P> i_element;
+
+ /// Insert a pair \p k_p (key k, site p).
+ void insert(const i_element& k_p);
+
+ /// Insert a pair (key \p k, site \p p).
+ void insert(const K& k, const P& p);
+
+
+ void unsafe_insert_(const K& k, const P& p);
+
+
+
+ /// Removal element associated type.
+ typedef P r_element;
+
+ /// Remove a site \p p.
+ void remove(const P& p);
+
+ /// Remove all sites with key \p k.
+ void remove_key(const K& k);
+
+ /// Change the key \p k into a new value \p new_k.
+ void change_key(const K& k, const K& new_k);
+
+ /// Change the keys by applying the function \p f.
+ template <typename F>
+ void change_keys(const Function_v2v<F>& f);
+
+
+
+ /// Clear this site set.
+ void clear();
+
+
+ /// Give the queue with the priority \p priority. This method
+ /// always works: if the priority is not in this set, an empty
+ /// queue is returned.
+ const p_set<P>& operator()(const K& key) const;
+
+ /// Give the key associated with site \p p.
+ const K& key(const P& p) const;
+
+ /// Give the set of keys.
+ const util::set<K>& keys() const;
+
+
+ /// Test if the \p priority exists.
+ bool exists_key(const K& key) const;
+
+
+ // Required by p_double-related classes.
+ const util::set<K>& set_1_() const;
+ const p_set<P>& set_2_(const K& key) const;
+
+
+ /// Return the size of this site set in memory.
+ std::size_t memory_size() const;
+
+ protected:
+
+ // Bunch of keys.
+ util::set<K> b_;
+
+ // Function: key k -> set of sites {p}.
+ typedef std::map<K, p_set<P>, util::less<K> > s_t;
+ s_t s_;
+
+ // Function: site p -> key k.
+ typedef std::map<P, K, util::less<P> > k_t;
+ k_t k_;
+
+ // Number of sites.
+ unsigned n_;
+
+ // Run invariance tests and return the result.
+ bool run_() const;
+ };
+
+
+
+ template <typename K, typename P>
+ std::ostream& operator<<(std::ostream& ostr, const p_key<K,P>&
pk);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename K, typename P>
+ inline
+ p_key<K,P>::p_key()
+ {
+ n_ = 0;
+ mln_invariant(run_());
+ }
+
+ template <typename K, typename P>
+ inline
+ bool
+ p_key<K,P>::has(const psite&) const
+ {
+ mln_invariant(run_());
+ // FIXME
+ return true;
+ }
+
+ template <typename K, typename P>
+ inline
+ bool
+ p_key<K,P>::has(const P& p) const
+ {
+ mln_invariant(run_());
+ return k_.find(p) != k_.end();
+ }
+
+ template <typename K, typename P>
+ inline
+ bool
+ p_key<K,P>::is_valid() const
+ {
+ mln_invariant(run_());
+ return true;
+ }
+
+ template <typename K, typename P>
+ inline
+ unsigned
+ p_key<K,P>::nsites() const
+ {
+ mln_invariant(run_());
+ return n_;
+ }
+
+
+ template <typename K, typename P>
+ inline
+ void
+ p_key<K,P>::unsafe_insert_(const K& k, const P& p)
+ {
+ s_[k].insert(p);
+ k_[p] = k;
+ ++n_;
+ b_.insert(k);
+ mln_invariant(run_());
+ }
+
+
+ template <typename K, typename P>
+ inline
+ void
+ p_key<K,P>::insert(const K& k, const P& p)
+ {
+ mln_invariant(run_());
+ typename k_t::iterator p_k = k_.find(p);
+ if (p_k != k_.end())
+ // p is already in this set (so n_ is unchanged).
+ {
+ K p_key = p_k->second;
+ mln_assertion(b_.has(p_key));
+ mln_assertion(s_[p_key].has(p));
+ if (p_key == k)
+ // No-op.
+ return;
+ // p moves from s_[p_key] to s_[k].
+ s_[p_key].remove(p);
+ s_[k].insert(p);
+ // Update key of p.
+ p_k->second = k;
+ }
+ else
+ // Actual insertion.
+ {
+ s_[k].insert(p);
+ k_[p] = k;
+ ++n_;
+ }
+ b_.insert(k);
+ mln_invariant(run_());
+ }
+
+ template <typename K, typename P>
+ inline
+ void
+ p_key<K,P>::insert(const i_element& k_p)
+ {
+ this->insert(k_p.first, k_p.second); // Also test invariants.
+ }
+
+ template <typename K, typename P>
+ inline
+ void
+ p_key<K,P>::remove(const P& p)
+ {
+ mln_invariant(run_());
+ typename k_t::iterator p_k = k_.find(p);
+
+ if (p_k == k_.end())
+ // No-op because p does not belong to this site set.
+ return;
+
+ K p_key = p_k->second;
+ mln_assertion(b_.has(p_key));
+
+ // Update k_.
+ k_.erase(p_k);
+
+ // Update s_.
+ typename s_t::iterator k_s = s_.find(p_key);
+ mln_assertion(k_s != s_.end()); // p_key found in s_.
+ p_set<P>& s = k_s->second;
+ mln_assertion(s.has(p)); // p is in s_[p_key].
+
+ if (s.nsites() == 1)
+ {
+ // Clean up for p is the only site with p_key.
+ s_.erase(k_s);
+ b_.remove(p_key);
+ }
+ else
+ {
+ // Simple removal.
+ s.remove(p);
+ }
+
+ // Update n_.
+ --n_;
+
+ mln_invariant(run_());
+ }
+
+ template <typename K, typename P>
+ inline
+ void
+ p_key<K,P>::remove_key(const K& k)
+ {
+ mln_invariant(run_());
+ typename s_t::iterator k_s = s_.find(k);
+
+ if (k_s == s_.end())
+ // No-op because key k does not exist.
+ return;
+
+ // Update b_.
+ b_.remove(k);
+
+ // Update k_.
+ p_set<P>& s = k_s->second;
+ mln_piter(p_set<P>) p(s);
+ for_all(p)
+ k_.erase(p);
+
+ // Update n_.
+ n_ -= s.nsites();
+
+ // Update s_.
+ s_.erase(k_s);
+
+ mln_invariant(run_());
+ }
+
+
+ template <typename K, typename P>
+ inline
+ void
+ p_key<K,P>::change_key(const K& k, const K& new_k)
+ {
+ mln_invariant(run_());
+
+ if (new_k == k)
+ // No-op.
+ return;
+
+ typename s_t::iterator k_s = s_.find(k);
+ if (k_s == s_.end())
+ // No-op because key k does not exist.
+ return;
+
+ // Update b_.
+ b_.remove(k);
+ b_.insert(new_k);
+
+ // Update k_.
+ p_set<P>& s = k_s->second;
+ if (s.nsites() < n_ / 10) // Few elements to be moved.
+ {
+ // s.nsites() iterations.
+ mln_piter(p_set<P>) p(s);
+ for_all(p)
+ k_[p] = new_k;
+ }
+ else
+ {
+ // n_ iterations.
+ typename k_t::iterator p_k;
+ for (p_k = k_.begin(); p_k != k_.end(); ++p_k)
+ if (p_k->second == k)
+ p_k->second = new_k;
+ }
+
+ // Update s_.
+ s_[new_k] += s;
+ s_.erase(k_s);
+
+ mln_invariant(run_());
+ }
+
+ template <typename K, typename P>
+ template <typename F>
+ inline
+ void
+ p_key<K,P>::change_keys(const Function_v2v<F>& f_)
+ {
+ mln_invariant(run_());
+
+ const F& f = exact(f_);
+ std::map<K,K> lut;
+
+ // Update b_.
+ {
+ util::set<K> new_b;
+ mln_iter(util::set<K>) k(b_);
+ for_all(k)
+ new_b.insert(lut[k] = f(k));
+ b_ = new_b;
+ }
+
+ // Update k_ and s_.
+ {
+ s_t new_s;
+ typename k_t::iterator p_k;
+ for (p_k = k_.begin(); p_k != k_.end(); ++p_k)
+ {
+ p_k->second = lut[p_k->second];
+ new_s[p_k->second].insert(p_k->first);
+ }
+ s_ = new_s;
+ }
+
+ mln_invariant(run_());
+ }
+
+ template <typename K, typename P>
+ inline
+ void
+ p_key<K,P>::clear()
+ {
+ mln_invariant(run_());
+ b_.clear();
+ s_.clear();
+ k_.clear();
+ n_ = 0;
+ mln_invariant(run_());
+ }
+
+ template <typename K, typename P>
+ inline
+ std::size_t
+ p_key<K,P>::memory_size() const
+ {
+ mln_invariant(run_());
+ return 0; // FIXME
+// std::size_t mem_q = 0;
+// typename std::map<P, Q>::const_iterator i;
+// for (i = q_.begin(); i != q_.end(); ++i)
+// mem_q += i->second.memory_size();
+// return p_.memory_size() + sizeof(q_) + sizeof(n_);
+ }
+
+ template <typename K, typename P>
+ inline
+ const p_set<P>&
+ p_key<K,P>::operator()(const K& key) const
+ {
+ static const p_set<P> nil_ = p_set<P>();
+ if (exists_key(key)) // Also test invariants.
+ return s_.find(key)->second;
+ else
+ return nil_;
+ }
+
+ template <typename K, typename P>
+ inline
+ const K&
+ p_key<K,P>::key(const P& p) const
+ {
+ mln_invariant(run_());
+ mln_precondition(k_.find(p) != k_.end());
+ return k_.find(p)->second;
+ }
+
+ template <typename K, typename P>
+ inline
+ const util::set<K>&
+ p_key<K,P>::keys() const
+ {
+ mln_invariant(run_());
+ return b_;
+ }
+
+ template <typename K, typename P>
+ inline
+ bool
+ p_key<K,P>::exists_key(const K& key) const
+ {
+ mln_invariant(run_());
+ return b_.has(key);
+ }
+
+ template <typename K, typename P>
+ inline
+ const util::set<K>&
+ p_key<K,P>::set_1_() const
+ {
+ return b_;
+ }
+
+ template <typename K, typename P>
+ inline
+ const p_set<P>&
+ p_key<K,P>::set_2_(const K& key) const
+ {
+ mln_precondition(b_.has(key));
+ return s_.find(key)->second;
+ }
+
+ template <typename K, typename P>
+ inline
+ bool
+ p_key<K,P>::run_() const
+ {
+ if (! implies(n_ == 0, b_.is_empty()))
+ {
+ std::cerr << "#1" << std::endl;
+ return false;
+ }
+
+ if (b_.nelements() != s_.size())
+ {
+ // Containers b_ and s_ are not consistent in size!
+ std::cerr << "#2" << std::endl;
+ return false;
+ }
+
+ if (k_.size() != n_)
+ {
+ // The number of entries in k_ is not n_!
+ std::cerr << "#3: k_.size=" << k_.size() << " n_="
<< n_ << std::endl;
+ return false;
+ }
+
+ unsigned n = 0;
+ mln_iter(util::set<K>) key(b_);
+ for_all(key)
+ {
+ typename s_t::const_iterator k_s = s_.find(key);
+
+ if (k_s == s_.end())
+ {
+ // This key is not found in s_!
+ std::cerr << "#4" << std::endl;
+ return false;
+ }
+
+ const p_set<P>& s = k_s->second;
+
+ if (s.nsites() == 0)
+ {
+ // The site set associated with this key is empty!
+ std::cerr << "#5" << std::endl;
+ return false;
+ }
+
+ n += s.nsites();
+
+ mln_piter(p_set<P>) p(s);
+ for_all(p) // For every site p with the current key w.r.t. s_.
+ {
+ typename k_t::const_iterator p_k = k_.find(p);
+
+ if (p_k == k_.end())
+ {
+ // There is no key entry for p in k_!
+ std::cerr << "#6" << std::endl;
+ return false;
+ }
+
+ if (p_k->second != key)
+ {
+ // We have an inconsistency for p between s_ and k_!
+ std::cerr << "#7" << std::endl;
+ return false;
+ }
+ }
+ }
+
+ if (n != n_)
+ {
+ // The number of elements in s_ is not n_!
+ std::cerr << "#8" << std::endl;
+ return false;
+ }
+
+ return true;
+ }
+
+
+
+
+
+ // Operator<<.
+
+ template <typename K, typename P>
+ std::ostream& operator<<(std::ostream& ostr, const p_key<K,P>&
pk)
+ {
+ ostr << '{';
+ typename util::set<K>::fwd_iter k(pk.keys());
+ for_all(k)
+ {
+ ostr << ' ' << k << ':';
+ ostr << pk.set_2_(k);
+ }
+ ostr << '}';
+ return ostr;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_P_KEY_HH
Index: mln/core/point2d.hh
--- mln/core/point2d.hh (revision 2153)
+++ mln/core/point2d.hh (working copy)
@@ -45,7 +45,7 @@
/*! \brief Type alias for a point defined on the 2D square grid with
* integer coordinates.
*/
- typedef point<grid::square, int> point2d;
+ typedef point<grid::square, def::coord> point2d;
namespace internal
@@ -54,11 +54,19 @@
// Specialization.
template <typename C, typename E>
- struct site_const_impl< point<grid::square, C>, E >
+ struct subject_impl< const point<grid::square, C>, E >
{
- C row() const;
- C col() const;
- C operator[](unsigned i) const;
+ typedef C coord;
+ enum { dim = 2 };
+
+ typedef const C& row_t;
+ const C& row() const;
+
+ typedef const C& col_t;
+ const C& col() const;
+
+ const C& operator[](unsigned i) const;
+ const C& last_coord() const;
private:
const E& exact_() const;
};
@@ -67,83 +75,99 @@
// Specialization for point<M,C>.
template <typename C, typename E>
- struct site_mutable_impl< point<grid::square, C>, E > :
- site_const_impl < point<grid::square, C>, E >
+ struct subject_impl< point<grid::square, C>, E > :
+ subject_impl< const point<grid::square, C>, E >
{
+ private:
+ typedef subject_impl< const point<grid::square, C>, E > super_;
+ E& exact_();
+ public:
+ using super_::row;
C& row();
+ using super_::col;
C& col();
+ using super_::operator[];
C& operator[](unsigned i);
- private:
- typedef site_const_impl< point<grid::square, C>, E > super;
- E& exact_();
};
# ifndef MLN_INCLUDE_ONLY
- // Either unproxy() or to_site() can be used below. In the
- // former case, the unproxied features ind() because it is a
- // point_ or another proxy to a point_.
-
- // site_const_impl
+ // subject_impl
template <typename C, typename E>
- C
- site_const_impl< point<grid::square, C>, E >::row() const
+ inline
+ const C&
+ subject_impl< const point<grid::square, C>, E >::row() const
{
- return exact_().to_site().row();
+ return exact_().get_subject().row();
}
template <typename C, typename E>
- C
- site_const_impl< point<grid::square, C>, E >::col() const
+ inline
+ const C&
+ subject_impl< const point<grid::square, C>, E >::col() const
{
- return exact_().to_site().col();
+ return exact_().get_subject().col();
}
template <typename C, typename E>
- C
- site_const_impl< point<grid::square, C>, E >::operator[](unsigned i)
const
+ inline
+ const C&
+ subject_impl< const point<grid::square, C>, E >::operator[](unsigned i)
const
{
mln_precondition(i < 2);
- return exact_().to_site()[i];
+ return exact_().get_subject()[i];
+ }
+
+ template <typename C, typename E>
+ inline
+ const C&
+ subject_impl< const point<grid::square, C>, E >::last_coord() const
+ {
+ return this->col();
}
template <typename C, typename E>
+ inline
const E&
- site_const_impl< point<grid::square, C>, E >::exact_() const
+ subject_impl< const point<grid::square, C>, E >::exact_() const
{
return internal::force_exact<const E>(*this);
}
- // site_mutable_impl
+ // subject_impl
template <typename C, typename E>
+ inline
C&
- site_mutable_impl< point<grid::square, C>, E >::row()
+ subject_impl< point<grid::square, C>, E >::row()
{
- return exact_().to_site().row();
+ return exact_().get_subject().row();
}
template <typename C, typename E>
+ inline
C&
- site_mutable_impl< point<grid::square, C>, E >::col()
+ subject_impl< point<grid::square, C>, E >::col()
{
- return exact_().to_site().col();
+ return exact_().get_subject().col();
}
template <typename C, typename E>
+ inline
C&
- site_mutable_impl< point<grid::square, C>, E >::operator[](unsigned i)
+ subject_impl< point<grid::square, C>, E >::operator[](unsigned i)
{
mln_precondition(i < 2);
- return exact_().to_site()[i];
+ return exact_().get_subject()[i];
}
template <typename C, typename E>
+ inline
E&
- site_mutable_impl< point<grid::square, C>, E >::exact_()
+ subject_impl< point<grid::square, C>, E >::exact_()
{
return internal::force_exact<E>(*this);
}
Index: mln/core/p_double.hh
--- mln/core/p_double.hh (revision 0)
+++ mln/core/p_double.hh (revision 0)
@@ -0,0 +1,309 @@
+// Copyright (C) 2008 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 MLN_CORE_P_DOUBLE_HH
+# define MLN_CORE_P_DOUBLE_HH
+
+/*! \file mln/core/p_double.hh
+ *
+ * FIXME
+ *
+ * \todo Document!
+ *
+ * \todo Zed: IMPORTANT FIXME: a psite shall know about both iterators
+ * to be fully located. Think about an image based on
+ * p_array_of<p_run<P>>: its psite has to know the first index to
+ * access the associated value set.
+ */
+
+# include <mln/core/internal/pseudo_site_base.hh>
+# include <mln/core/internal/site_set_iterator_base.hh>
+
+
+namespace mln
+{
+
+ // p_double_psite<S,Sp>
+
+ template <typename S, typename Sp>
+ class p_double_psite : public internal::pseudo_site_base_< const
mln_psite(Sp)&,
+ p_double_psite<S,Sp> >
+ {
+ public:
+
+ p_double_psite();
+
+ // Target associated type.
+ typedef S target;
+
+ const S* target_() const;
+
+ void change_target(const S& newtarget);
+
+ bool is_valid() const;
+
+ unsigned index() const;
+ const mln_psite(Sp)& p() const;
+
+ void change_i(unsigned i);
+
+ void change_p(const mln_psite(Sp)& p);
+
+ // As a Proxy:
+ const mln_psite(Sp)& subj_();
+
+ private:
+
+ const target* s_;
+ mutable unsigned i_;
+ mutable mln_psite(Sp) p_;
+ };
+
+
+
+ // p_double_piter<S,I1,I2>
+
+ template <typename S, typename I1, typename I2>
+ class p_double_piter
+ :
+ public internal::site_set_iterator_base< S,
+ p_double_piter<S,I1,I2> >
+ {
+ typedef p_double_piter<S,I1,I2> self_;
+ typedef internal::site_set_iterator_base<S,self_> super;
+ public:
+
+ /// Constructor with no argument.
+ p_double_piter();
+
+ /// Constructor.
+ p_double_piter(const S& s);
+
+ /// Test if the iterator is valid.
+ bool is_valid_() const;
+
+ /// Invalidate the iterator.
+ void invalidate_();
+
+ /// Start an iteration.
+ void start_();
+
+ /// Go to the next point.
+ void next_();
+
+ protected:
+ using super::p_;
+ using super::s_;
+
+ private:
+ I1 i1_;
+ I2 i2_;
+
+ // Progress to the next valid state if it exists.
+ void progress_();
+
+ };
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // p_double_psite<S,Sp>
+
+ template <typename S, typename Sp>
+ inline
+ p_double_psite<S,Sp>::p_double_psite()
+ {
+ }
+
+ template <typename S, typename Sp>
+ inline
+ const mln_psite(Sp)&
+ p_double_psite<S,Sp>::subj_()
+ {
+ return p_;
+ }
+
+ template <typename S, typename Sp>
+ inline
+ const S*
+ p_double_psite<S,Sp>::target_() const
+ {
+ return s_;
+ }
+
+ template <typename S, typename Sp>
+ inline
+ void
+ p_double_psite<S,Sp>::change_target(const S& s)
+ {
+ s_ = & s;
+ }
+
+ template <typename S, typename Sp>
+ inline
+ bool
+ p_double_psite<S,Sp>::is_valid() const
+ {
+ return s_ != 0 && p_.is_valid();
+ }
+
+ template <typename S, typename Sp>
+ inline
+ unsigned
+ p_double_psite<S,Sp>::index() const
+ {
+ return i_;
+ }
+
+ template <typename S, typename Sp>
+ inline
+ const mln_psite(Sp)&
+ p_double_psite<S,Sp>::p() const
+ {
+ return p_;
+ }
+
+ template <typename S, typename Sp>
+ inline
+ void
+ p_double_psite<S,Sp>::change_i(unsigned i)
+ {
+ i_ = i;
+ }
+
+ template <typename S, typename Sp>
+ inline
+ void
+ p_double_psite<S,Sp>::change_p(const mln_psite(Sp)& p)
+ {
+ p_ = p;
+ }
+
+
+ // p_double_piter<S,I1,I2>
+
+ template <typename S, typename I1, typename I2>
+ inline
+ p_double_piter<S,I1,I2>::p_double_piter()
+ {
+ }
+
+ template <typename S, typename I1, typename I2>
+ inline
+ p_double_piter<S,I1,I2>::p_double_piter(const S& s)
+ {
+ this->change_target(s);
+ i1_.change_target(s.set_1_());
+ invalidate_();
+ }
+
+ template <typename S, typename I1, typename I2>
+ inline
+ bool
+ p_double_piter<S,I1,I2>::is_valid_() const
+ {
+ return i2_.is_valid();
+ }
+
+ template <typename S, typename I1, typename I2>
+ inline
+ void
+ p_double_piter<S,I1,I2>::invalidate_()
+ {
+ i2_.invalidate();
+ }
+
+ template <typename S, typename I1, typename I2>
+ inline
+ void
+ p_double_piter<S,I1,I2>::start_()
+ {
+ i1_.start();
+ if (i1_.is_valid())
+ {
+ i2_.change_target(s_->set_2_(i1_));
+ i2_.start();
+ if (! i2_.is_valid())
+ progress_();
+ else
+ {
+ p_.change_i(i1_.index_());
+ p_.change_p(i2_);
+ }
+ }
+ else
+ i2_.invalidate();
+ mln_postcondition(implies(i2_.is_valid(), i1_.is_valid()));
+ }
+
+ template <typename S, typename I1, typename I2>
+ inline
+ void
+ p_double_piter<S,I1,I2>::next_()
+ {
+ i2_.next();
+ if (! i2_.is_valid())
+ progress_();
+ else
+ p_.change_p(i2_);
+ mln_postcondition(implies(i2_.is_valid(), i1_.is_valid()));
+ }
+
+ template <typename S, typename I1, typename I2>
+ inline
+ void
+ p_double_piter<S,I1,I2>::progress_()
+ {
+ // This routine is general; it does not make the assumption that
+ // the site set type features is_empty().
+ while (! i2_.is_valid() && i1_.is_valid())
+ {
+ i1_.next();
+ if (! i1_.is_valid())
+ {
+ // End of iterations.
+ i2_.invalidate(); // Safety.
+ return;
+ }
+ i2_.change_target(s_->set_2_(i1_));
+ i2_.start();
+ }
+ if (i2_.is_valid())
+ {
+ p_.change_i(i1_.index_());
+ p_.change_p(i2_);
+ }
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_P_DOUBLE_HH
Index: mln/core/p_mutable_array_of.hh
--- mln/core/p_mutable_array_of.hh (revision 0)
+++ mln/core/p_mutable_array_of.hh (revision 0)
@@ -0,0 +1,251 @@
+// Copyright (C) 2008 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 MLN_CORE_P_MUTABLE_ARRAY_OF_HH
+# define MLN_CORE_P_MUTABLE_ARRAY_OF_HH
+
+/*! \file mln/core/p_mutable_array_of.hh
+ *
+ * \brief Definition of a mutable array of site sets.
+ *
+ * \todo Zed: Add another version (p_array_of) of this class that can
+ * inherit, when possible, nsites and bbox (just like in p_vaccess).
+ * It is a different class since such a feature is incompatible with
+ * the "op[] mutable".
+ */
+
+# include <mln/core/p_double.hh>
+# include <mln/core/internal/site_set_base.hh>
+# include <mln/util/array.hh>
+
+
+
+namespace mln
+{
+
+ // Forward declaration.
+ template <typename S> class p_mutable_array_of;
+
+
+ namespace trait
+ {
+
+ template <typename S>
+ struct site_set_< p_mutable_array_of<S> >
+ {
+ typedef trait::site_set::nsites::unknown nsites;
+ typedef trait::site_set::bbox::unknown bbox;
+ typedef trait::site_set::contents::growing contents;
+ typedef trait::site_set::arity::multiple arity;
+ };
+
+ } // end of namespace trait
+
+
+
+ /*! \brief p_mutable_array_of is a mutable array of site sets.
+ *
+ * Parameter \c S is the type of the contained site sets.
+ */
+ template <typename S>
+ class p_mutable_array_of : public internal::site_set_base_< mln_element(S),
+ p_mutable_array_of<S> >,
+ private mlc_is_a(S, Site_Set)::check_t
+ {
+ typedef p_mutable_array_of<S> self_;
+ typedef util::array<S> array_;
+ public:
+
+ /// Element associated type.
+ typedef S element;
+
+
+ /// Psite associated type.
+ typedef p_double_psite<self_, element> psite;
+
+ /// Forward Site_Iterator associated type.
+ typedef p_double_piter<self_,
+ mln_fwd_iter(array_),
+ mln_fwd_piter(S)> fwd_piter;
+
+ /// Backward Site_Iterator associated type.
+ typedef p_double_piter<self_,
+ mln_bkd_iter(array_),
+ mln_bkd_piter(S)> bkd_piter;
+
+ /// Site_Iterator associated type.
+ typedef fwd_piter piter;
+
+
+ /// Constructor without arguments.
+ p_mutable_array_of();
+
+
+ /// Test if \p p belongs to this point set.
+ bool has(const psite&) const;
+
+ /// Test if this set of runs is valid.
+ bool is_valid() const;
+
+
+ /// Insertion element associated type.
+ typedef S i_element;
+
+ /// Insert a site set \p s.
+ void insert(const S& s);
+
+
+ /// Return the \p i-th site set (const version).
+ const S& operator[](unsigned i) const;
+
+ /// Return the \p i-th site set (mutable version).
+ S& operator[](unsigned i);
+
+
+ /// Return the size of this site set in memory.
+ std::size_t memory_size() const;
+
+ /// Hook to the set of runs.
+ const util::array<S>& array_hook_() const;
+
+
+ // Required by p_double-related classes.
+ const util::array<S>& set_1_() const;
+ template <typename I>
+ const S& set_2_(const I& it) const;
+
+ protected:
+
+ /// Array of site sets.
+ util::array<S> arr_;
+ };
+
+
+
+ template <typename S>
+ std::ostream& operator<<(std::ostream& ostr, const
p_mutable_array_of<S>& r);
+
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename S>
+ inline
+ p_mutable_array_of<S>::p_mutable_array_of()
+ {
+ }
+
+ template <typename S>
+ inline
+ bool
+ p_mutable_array_of<S>::has(const psite&) const
+ {
+ // FIXME
+ return true;
+ }
+
+ template <typename S>
+ inline
+ bool
+ p_mutable_array_of<S>::is_valid() const
+ {
+ return true;
+ }
+
+ template <typename S>
+ inline
+ void
+ p_mutable_array_of<S>::insert(const S& s)
+ {
+ arr_.append(s);
+ }
+
+ template <typename S>
+ inline
+ const S&
+ p_mutable_array_of<S>::operator[](unsigned i) const
+ {
+ mln_precondition(i < arr_.nelements());
+ return arr_[i];
+ }
+
+ template <typename S>
+ inline
+ S&
+ p_mutable_array_of<S>::operator[](unsigned i)
+ {
+ mln_precondition(i < arr_.nelements());
+ return arr_[i];
+ }
+
+ template <typename S>
+ inline
+ std::size_t
+ p_mutable_array_of<S>::memory_size() const
+ {
+ return arr_.memory_size();
+ }
+
+ template <typename S>
+ inline
+ const util::array<S>&
+ p_mutable_array_of<S>::array_hook_() const
+ {
+ return arr_;
+ }
+
+ template <typename S>
+ inline
+ const util::array<S>&
+ p_mutable_array_of<S>::set_1_() const
+ {
+ return arr_;
+ }
+
+ template <typename S>
+ template <typename I>
+ inline
+ const S&
+ p_mutable_array_of<S>::set_2_(const I& it) const
+ {
+ return it.element();
+ }
+
+
+ template <typename S>
+ std::ostream& operator<<(std::ostream& ostr, const
p_mutable_array_of<S>& a)
+ {
+ return ostr << a.array_hook_();
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_P_MUTABLE_ARRAY_OF_HH
Index: mln/core/p_priority_queue.hh
--- mln/core/p_priority_queue.hh (revision 2153)
+++ mln/core/p_priority_queue.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -25,321 +25,398 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_CORE_P_PRIORITY_QUEUE_HH
-# define MLN_CORE_P_PRIORITY_QUEUE_HH
+#ifndef MLN_CORE_P_PRIORITY_HH
+# define MLN_CORE_P_PRIORITY_HH
-/*! \file mln/core/p_priority_queue.hh
+/*! \file mln/core/p_priority.hh
*
- * \brief Definition of a point set class based on p_queue with
- * priority features.
+ * \brief Definition of a priority queue of sites.
+ *
+ * \todo Rename file as p_priority.hh
*/
-# include <vector>
-# include <deque>
# include <map>
-# include <algorithm>
-# include <iterator>
-
+# include <mln/core/p_double.hh>
# include <mln/core/internal/site_set_base.hh>
-# include <mln/core/p_array_piter.hh>
-# include <mln/accu/bbox.hh>
-# include <mln/core/p_queue.hh>
+# include <mln/util/set.hh>
+
namespace mln
{
- // Fwd decls.
- template <typename P> struct p_array_fwd_piter_;
- template <typename P> struct p_array_bkd_piter_;
+ // Forward declaration.
+ template <typename P, typename Q> class p_priority;
- /*! \brief Point priority queue class (based on p_queue and std::map).
- *
- * This is a mathematical set of points (unique insertion).
- *
- * \todo Make it work with P being a Point_Site.
+
+ namespace trait
+ {
+
+ template <typename P, typename Q>
+ struct site_set_< p_priority<P,Q> >
+ {
+ typedef trait::site_set::nsites::known nsites;
+ typedef trait::site_set::bbox::unknown bbox;
+ typedef trait::site_set::contents::growing contents;
+ typedef trait::site_set::arity::multiple arity;
+ };
+
+ } // end of namespace trait
+
+
+
+
+ /*! \brief Priority queue class.
*
- * \warning We have some troubles with point set comparison based on
- * a call to npoints() when this container is multiple.
+ * FIXME
*/
- template <typename P, typename T>
- class p_priority_queue : public internal::site_set_base_< P, p_priority_queue<P,
T> >
+ template <typename P, typename Q>
+ class p_priority : public internal::site_set_base_< mln_site(Q),
+ p_priority<P,Q> >
{
+ typedef p_priority<P,Q> self_;
+ typedef util::set<P> set_;
public:
+ /// Element associated type.
+ typedef mln_element(Q) element;
+
+
+ /// Psite associated type.
+ typedef p_double_psite<self_, Q> psite;
+
/// Forward Site_Iterator associated type.
- typedef p_array_fwd_piter_<P> fwd_piter;
+ typedef p_double_piter<self_, typename set_::bkd_iter, mln_fwd_piter(Q)>
fwd_piter;
/// Backward Site_Iterator associated type.
- typedef p_array_bkd_piter_<P> bkd_piter;
+ typedef p_double_piter<self_, typename set_::fwd_iter, mln_bkd_piter(Q)>
bkd_piter;
+
+ /// Site_Iterator associated type.
+ typedef fwd_piter piter;
+
/// Constructor.
- p_priority_queue();
+ p_priority();
+
+ /// Test is the psite \p p belongs to this site set.
+ bool has(const psite&) const;
- /// Test is \p p belongs to this point set.
- bool has(const P& p) const;
+ /// Test this set validity so returns always true.
+ bool is_valid() const;
- /// Test if queue is empty or not.
- bool is_empty() const;
+ /// Give the number of sites.
+ unsigned nsites() const;
- /// Give the number of points.
- size_t npoints() const;
- /// Give the exact bounding box.
- const box_<P>& bbox() const;
+ /// Push in the queue with \p priority the element \p e.
+ void push(const P& priority, const element& e);
- /// Push force a point \p p in the queue.
- p_priority_queue<P, T>& push_force(const P& p, T prio = 0);
+ /// Insertion element associated type.
+ typedef std::pair<P, element> i_element;
- /// Push a point \p p in the queue.
- p_priority_queue<P, T>& push(const P& p, T prio = 0);
+ /// Insert a pair \p p_e (priority p, element e).
+ void insert(const i_element& p_e);
- /// Pop (remove) the front point \p p from the queue; \p p is the
- /// least recently inserted point.
+
+ /// Pop (remove) from the queue an element with highest priority.
+ /// If several elements have this priority, the least recently
+ /// inserted is chosen. \pre ! is_empty()
void pop();
- /// Give the front point \p p of the queue; \p p is the least
- /// recently inserted point.
- const P& front() const;
-
- /// Pop (remove) the front point \p p from the queue; \p p is the
- /// least recently inserted point and give the front point \p p of
- /// the queue; \p p is the least recently inserted point.
- const P& pop_front();
+ /// Give an element with highest priority. If several elements
+ /// have this priority, the least recently inserted is chosen.
+ /// \pre ! is_empty()
+ const mln_element(Q)& front() const;
+
+ /// Return an element with highest priority and remove it from the
+ /// set. If several elements have this priority, the least
+ /// recently inserted is chosen. \pre ! is_empty()
+ mln_element(Q) pop_front();
+
/// Clear the queue.
void clear();
- /// Return the corresponding std::vector of points.
- const std::vector<P>& vect() const;
- /// Return the \p i-th point.
- const P& operator[](unsigned i) const;
+ /// Give the queue with the priority \p priority. This method
+ /// always works: if the priority is not in this set, an empty
+ /// queue is returned.
+ const Q& operator()(const P& priority) const;
- protected:
+ /// Give the set of priorities.
+ const util::set<P>& priorities() const;
- std::map<const T, p_queue<P> > q_;
+ /// Test if the \p priority exists.
+ bool exists_priority(const P& priority) const;
- mutable std::vector<P> vect_;
- mutable bool vect_needs_update_;
- void vect_update_() const;
-
- mutable accu::bbox<P> bb_;
- mutable bool bb_needs_update_;
- void bb_update_() const;
+ /// Give the highest priority.
+ /// \pre ! is_empty()
+ const P highest_priority() const;
- };
+ /// Give the lowest priority.
+ /// \pre ! is_empty()
+ const P lowest_priority() const;
+ // Required by p_double-related classes.
+ const util::set<P>& set_1_() const;
+ const Q& set_2_(const P& priority) const;
-# ifndef MLN_INCLUDE_ONLY
- template <typename P, typename T>
- inline
- p_priority_queue<P, T>::p_priority_queue()
- {
- vect_needs_update_ = false;
- bb_needs_update_ = false;
- }
+ /// Return the size of this site set in memory.
+ std::size_t memory_size() const;
- template <typename P, typename T>
- inline
- void
- p_priority_queue<P, T>::vect_update_() const
- {
- vect_.clear();
- vect_.reserve(npoints());
+ protected:
- typename std::map<T, p_queue<P> >::const_iterator it = q_.begin ();
+ util::set<P> p_;
+ std::map<P,Q> q_;
+ unsigned n_;
- for (; it != q_.end (); ++it)
- std::copy((*it).second.vect().begin(), (*it).second.vect().end(),
- std::back_inserter(vect_));
- vect_needs_update_ = false;
- }
+ // Run invariance tests and return the result.
+ bool run_() const;
+ };
- template <typename P, typename T>
- inline
- void
- p_priority_queue<P, T>::bb_update_() const
- {
- bb_.init();
- typename std::map<T, p_queue<P> >::const_iterator it = q_.begin ();
- for (; it != q_.end (); ++it)
- for (unsigned i = 0; i < (*it).second.npoints (); ++i)
- bb_.take((*it).second[i]);
- bb_needs_update_ = false;
- }
+ template <typename P, typename Q>
+ std::ostream& operator<<(std::ostream& ostr, const
p_priority<P,Q>& pq);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+ template <typename P, typename Q>
+ inline
+ p_priority<P,Q>::p_priority()
+ {
+ n_ = 0;
+ mln_invariant(run_());
+ }
- template <typename P, typename T>
+ template <typename P, typename Q>
inline
bool
- p_priority_queue<P, T>::has(const P& p) const
+ p_priority<P,Q>::has(const psite&) const
{
- typename std::map<T, p_queue<P> >::const_iterator it = q_.begin ();
-
- for (; it != q_.end (); ++it)
- if ((*it).second.has (p))
+ mln_invariant(run_());
+ // FIXME
return true;
- return false;
}
- template <typename P, typename T>
+ template <typename P, typename Q>
inline
bool
- p_priority_queue<P, T>::is_empty() const
+ p_priority<P,Q>::is_valid() const
{
- typename std::map<T, p_queue<P> >::const_iterator it = q_.begin ();
-
- for (; it != q_.end (); ++it)
- if (!(*it).second.is_empty ())
- return false;
+ mln_invariant(run_());
return true;
}
- template <typename P, typename T>
+ template <typename P, typename Q>
inline
- size_t
- p_priority_queue<P, T>::npoints() const
+ unsigned
+ p_priority<P,Q>::nsites() const
{
- unsigned res = 0;
-
- typename std::map<T, p_queue<P> >::const_iterator it = q_.begin ();
+ mln_invariant(run_());
+ return n_;
+ }
- for (; it != q_.end (); ++it)
- if (!(*it).second.is_empty ())
- res += (*it).second.npoints();
- return res;
+ template <typename P, typename Q>
+ inline
+ void
+ p_priority<P,Q>::push(const P& priority, const element& e)
+ {
+ mln_invariant(run_());
+ p_.insert(priority); // No-op if this priority already exists.
+ q_[priority].push(e);
+ ++n_;
+ mln_invariant(run_());
}
- template <typename P, typename T>
+ template <typename P, typename Q>
inline
- const box_<P>&
- p_priority_queue<P, T>::bbox() const
+ void
+ p_priority<P,Q>::insert(const i_element& p_e)
{
- mln_precondition(npoints() != 0);
- if (bb_needs_update_)
- bb_update_();
- return bb_.to_result();
+ this->push(p_e.first, p_e.second); // Also test invariants.
}
- template <typename P, typename T>
+ template <typename P, typename Q>
inline
- p_priority_queue<P, T>&
- p_priority_queue<P, T>::push_force(const P& p, T prio)
+ void
+ p_priority<P,Q>::pop()
{
- q_[prio].push_force (p);
- if (! vect_needs_update_)
+ mln_precondition(! this->is_empty()); // Also test invariants.
+ P prior = highest_priority();
+ q_[prior].pop();
+ if (q_[prior].is_empty())
{
- vect_needs_update_ = true;
- bb_needs_update_ = true;
+ q_.erase(prior);
+ p_.remove(prior);
}
- return *this;
+ --n_;
+ mln_invariant(run_());
}
- template <typename P, typename T>
+ template <typename P, typename Q>
inline
- p_priority_queue<P, T>&
- p_priority_queue<P, T>::push(const P& p, T prio)
+ const mln_element(Q)&
+ p_priority<P,Q>::front() const
{
- if (! has(p))
- return this->push_force(p, prio);
- else
- return *this;
+ mln_precondition(! this->is_empty()); // Also test invariants.
+ return q_[highest_priority()].front();
+ }
+
+ template <typename P, typename Q>
+ inline
+ mln_element(Q)
+ p_priority<P,Q>::pop_front()
+ {
+ mln_precondition(! this->is_empty()); // Also test invariants.
+ // FIXME: can be speeded up, return const& when possible...
+ mln_element(Q) e = this->front();
+ this->pop();
+ return e;
}
- template <typename P, typename T>
+ template <typename P, typename Q>
inline
void
- p_priority_queue<P, T>::pop()
+ p_priority<P,Q>::clear()
{
- typename std::map<T, p_queue<P> >::reverse_iterator it = q_.rbegin ();
+ mln_invariant(run_());
+ p_.clear();
+ q_.clear();
+ n_ = 0;
+ mln_invariant(run_());
+ }
- for (; it != q_.rend (); ++it)
- if (!(*it).second.is_empty ())
- return (*it).second.pop ();
+ template <typename P, typename Q>
+ inline
+ std::size_t
+ p_priority<P,Q>::memory_size() const
+ {
+ mln_invariant(run_());
+ std::size_t mem_q = 0;
+ typename std::map<P, Q>::const_iterator i;
+ for (i = q_.begin(); i != q_.end(); ++i)
+ mem_q += i->second.memory_size();
+ return p_.memory_size() + sizeof(q_) + sizeof(n_);
+ }
- if (! vect_needs_update_)
+ template <typename P, typename Q>
+ inline
+ const Q&
+ p_priority<P,Q>::operator()(const P& priority) const
{
- vect_needs_update_ = true;
- bb_needs_update_ = true;
+ static const Q nil_ = Q();
+ if (exists_priority(priority)) // Also test invariants.
+ {
+ std::map<P,Q>& mq = const_cast<std::map<P,Q>&>(q_);
+ mln_assertion(mq[priority].nsites() > 0);
+ return mq[priority];
}
+ else
+ return nil_;
}
- template <typename P, typename T>
+ template <typename P, typename Q>
inline
- const P&
- p_priority_queue<P, T>::front() const
+ const util::set<P>&
+ p_priority<P,Q>::priorities() const
{
- mln_precondition(! q_.empty());
-
- typename std::map<T, p_queue<P> >::const_reverse_iterator it = q_.rbegin
();
-
- for (; it != q_.rend (); ++it)
- if (!(*it).second.is_empty ())
- break;
- return (*it).second.front ();
+ mln_invariant(run_());
+ return p_;
}
- template <typename P, typename T>
+ template <typename P, typename Q>
inline
- const P&
- p_priority_queue<P, T>::pop_front()
+ bool
+ p_priority<P,Q>::exists_priority(const P& priority) const
{
- const P& res = this->front();
+ mln_invariant(run_());
+ return p_.has(priority);
+ }
- this->pop();
- return res;
+ template <typename P, typename Q>
+ inline
+ const P
+ p_priority<P,Q>::highest_priority() const
+ {
+ mln_precondition(! this->is_empty()); // Also test invariants.
+ return p_.last_element();
}
- template <typename P, typename T>
+ template <typename P, typename Q>
inline
- void
- p_priority_queue<P, T>::clear()
+ const P
+ p_priority<P,Q>::lowest_priority() const
{
- typename std::map<T, p_queue<P> >::iterator it = q_.begin ();
+ mln_precondition(! this->is_empty()); // Also test invariants.
+ return p_.first_element();
+ }
- for (; it != q_.end (); ++it)
- (*it).second.clear ();
- q_.clear();
- vect_needs_update_ = false;
- bb_needs_update_ = false;
+ template <typename P, typename Q>
+ inline
+ const util::set<P>&
+ p_priority<P,Q>::set_1_() const
+ {
+ return p_;
}
- template <typename P, typename T>
+ template <typename P, typename Q>
inline
- const std::vector<P>&
- p_priority_queue<P, T>::vect() const
+ const Q&
+ p_priority<P,Q>::set_2_(const P& priority) const
{
- if (vect_needs_update_)
- vect_update_();
- return vect_;
+ mln_precondition(p_.has(priority));
+ std::map<P,Q>& mq = const_cast<std::map<P,Q>&>(q_);
+ mln_precondition(mq[priority].nsites() > 0);
+ return mq[priority];
}
- template <typename P, typename T>
+ template <typename P, typename Q>
inline
- const P&
- p_priority_queue<P, T>::operator[](unsigned i) const
+ bool
+ p_priority<P,Q>::run_() const
{
- mln_precondition(i < npoints());
+ if (! implies(n_ == 0, p_.is_empty()))
+ return false;
+
+ if (! (p_.nelements() == q_.size()))
+ // Containers p_ and q_ are not consistent in size!
+ return false;
+
+ typename util::set<P>::iter p(p_);
+ for_all(p)
+ if (q_.find(p) == q_.end())
+ // We have an empty queue (with priority p)!
+ return false;
+
+ typename std::map<P,Q>::const_iterator i;
+ for (i = q_.begin(); i != q_.end(); ++i)
+ if (! p_.has(i->first))
+ // A priority is unknown (for a known queue)!
+ return false;
+
+ return true;
+ }
+
- typename std::map<T, p_queue<P> >::const_reverse_iterator it = q_.rbegin
();
- unsigned cpt = 0;
+ // Operator<<.
- for (; it != q_.rend (); ++it)
+ template <typename P, typename Q>
+ std::ostream& operator<<(std::ostream& ostr, const
p_priority<P,Q>& pq)
{
- if (!(*it).second.is_empty ())
- for (cpt = 0; cpt < (*it).second.npoints (); ++cpt)
+ ostr << '{';
+ typename util::set<P>::bkd_iter p(pq.priorities());
+ for_all(p)
{
- if (i == 0)
- return (*it).second[cpt];
- --i;
- }
+ ostr << ' ' << p << ':';
+ ostr << pq.set_2_(p);
}
- return (*it).second[cpt];
+ ostr << '}';
+ return ostr;
}
# endif // ! MLN_INCLUDE_ONLY
@@ -347,4 +424,4 @@
} // end of namespace mln
-#endif // ! MLN_CORE_P_PRIORITY_QUEUE_HH
+#endif // ! MLN_CORE_P_PRIORITY_HH
Index: mln/core/p_set.hh
--- mln/core/p_set.hh (revision 2153)
+++ mln/core/p_set.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -30,74 +30,121 @@
/*! \file mln/core/p_set.hh
*
- * \brief Definition of a point set class based on std::set.
+ * \brief Definition of a mathematical set of sites (based on
+ * util::set).
*/
-# include <mln/core/internal/site_set_base.hh>
-# include <mln/core/internal/set_of.hh>
-# include <mln/accu/bbox.hh>
# include <mln/core/p_array.hh>
+# include <mln/util/set.hh>
namespace mln
{
- /*! \brief Point set class based on std::set.
+ // Forward declaration.
+ template <typename P> class p_set;
+
+
+ namespace trait
+ {
+
+ template <typename P>
+ struct site_set_< p_set<P> >
+ {
+ typedef trait::site_set::nsites::known nsites;
+ typedef trait::site_set::bbox::unknown bbox;
+ typedef trait::site_set::contents::free contents;
+ typedef trait::site_set::arity::unique arity;
+ };
+
+ } // end of namespace trait
+
+
+
+ /*! \brief Point set class based on util::set.
*
* This is a mathematical set of points (not a multi-set). The
* parameter \p P shall be a Point type.
- *
- * \todo Test if \p P being a Point_Site is ok.
*/
template <typename P>
- class p_set : public internal::site_set_base_< P, p_set<P> >,
- private internal::set_of_<P>
+ class p_set : public internal::site_set_base_< P, p_set<P> >
{
- typedef internal::set_of_<P> super_;
-
+ typedef p_set<P> self_;
public:
+ /// Element associated type.
+ typedef P element;
+
+ /// Psite associated type.
+ typedef p_indexed_psite<self_> psite;
+
/// Forward Site_Iterator associated type.
- typedef p_array_fwd_piter_<P> fwd_piter;
+ typedef p_indexed_fwd_piter<self_> fwd_piter;
/// Backward Site_Iterator associated type.
- typedef p_array_bkd_piter_<P> bkd_piter;
+ typedef p_indexed_bkd_piter<self_> bkd_piter;
+
+ /// Site_Iterator associated type.
+ typedef fwd_piter piter;
+
/// Constructor.
p_set();
- /// Test is \p p belongs to this point set.
+
+ /// Test if psite \p p belongs to this point set.
+ bool has(const psite& p) const;
+
+ /// Test if \p p belongs to this point set.
bool has(const P& p) const;
- /// Return the corresponding std::vector of points.
- using super_::vect;
+ /// Test if index \p i belongs to this point set.
+ bool has(const util::index& i) const;
- /// Give the number of points.
- std::size_t npoints() const;
+ /// Test this set validity so returns always true.
+ bool is_valid() const;
- /// Insert a point \p p.
- p_set<P>& insert(const P& p);
- // FIXME : doesn't compile
- // /// Remove a point \p p.
- // p_set<P>& remove(P& p);
+ /// Give the number of sites.
+ unsigned nsites() const;
- /// Return the \p i-th point.
- const P& operator[](unsigned i) const;
+
+ /// Insertion element associated type.
+ typedef P i_element;
+
+ /// Insert a site \p p.
+ void insert(const P& p);
+
+ /// Removal element associated type.
+ typedef P r_element;
+
+ /// Remove a site \p p.
+ void remove(const P& p);
/// Clear this set.
void clear();
- /// Give the exact bounding box.
- const box_<mln_point(P)>& bbox() const;
+
+ /// Return the \p i-th site.
+ const P& operator[](unsigned i) const;
+
+
+ /// Return the size of this site set in memory.
+ std::size_t memory_size() const;
+
+ /// Return the corresponding std::vector of sites.
+ const std::vector<P>& std_vector() const;
+
+ /// Return the corresponding util::set of sites.
+ const util::set<P>& util_set() const;
protected:
- accu::bbox<P> bb_;
- // FIXME: Add invariant bb_.is_valid() <=> npoints() != 0
+ util::set<P> s_;
};
+
# ifndef MLN_INCLUDE_ONLY
template <typename P>
@@ -111,64 +158,100 @@
bool
p_set<P>::has(const P& p) const
{
- return this->super_::has(p);
+ return s_.has(p);
}
template <typename P>
inline
- std::size_t
- p_set<P>::npoints() const
+ bool
+ p_set<P>::has(const psite& p) const
+ {
+ mln_precondition(p.target_() == this); // FIXME: Refine.
+ if (! has(p.index()))
+ return false;
+ mln_invariant(p.to_site() == (*this)[p.index()]);
+ return true;
+ }
+
+ template <typename P>
+ inline
+ bool
+ p_set<P>::has(const util::index& i) const
+ {
+ return i >= 0 && unsigned(i) < nsites();
+ }
+
+ template <typename P>
+ inline
+ bool
+ p_set<P>::is_valid() const
{
- return this->super_::nelements();
+ return true;
}
template <typename P>
inline
- p_set<P>&
+ unsigned
+ p_set<P>::nsites() const
+ {
+ return s_.nelements();
+ }
+
+ template <typename P>
+ inline
+ void
p_set<P>::insert(const P& p)
{
- this->super_::insert(p);
- bb_.take(p);
- return *this;
+ s_.insert(p);
}
+ template <typename P>
+ inline
+ void
+ p_set<P>::remove(const P& p)
+ {
+ s_.remove(p);
+ }
- // FIXME : finish it.
- // template <typename P>
- // p_set<P>&
- // p_set<P>::remove(P& p)
- // {
- // this->super_::remove(p);
- // // FIXME: need to rebuild bb_ ?
- // //bb_.untake(p);
- // return *this;
- // }
+ template <typename P>
+ inline
+ void
+ p_set<P>::clear()
+ {
+ s_.clear();
+ }
template <typename P>
inline
const P&
p_set<P>::operator[](unsigned i) const
{
- mln_precondition(i < npoints());
- return this->super_::element(i);
+ mln_precondition(i < nsites());
+ return s_[i];
}
template <typename P>
inline
- void
- p_set<P>::clear()
+ std::size_t
+ p_set<P>::memory_size() const
+ {
+ return s_.memory_size();
+ }
+
+ template <typename P>
+ inline
+ const std::vector<P>&
+ p_set<P>::std_vector() const
{
- this->super_::clear();
- bb_.init();
+ return s_.std_vector();
}
template <typename P>
inline
- const box_<mln_point(P)>&
- p_set<P>::bbox() const
+ const util::set<P>&
+ p_set<P>::util_set() const
{
- mln_precondition(npoints() != 0);
- return bb_.to_result();
+ return s_;
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/core/line2d.hh
--- mln/core/line2d.hh (revision 2153)
+++ mln/core/line2d.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -25,18 +25,16 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_CORE_LINE2D_HH
-# define MLN_CORE_LINE2D_HH
+#ifndef MLN_CORE_P_LINE2D_HH
+# define MLN_CORE_P_LINE2D_HH
-/*! \file mln/core/line2d.hh
+/*! \file mln/core/p_line2d.hh
*
- * \brief Definition of a point set class based on std::vector.
+ * \brief Definition of a 2D discrete line of points (based on
+ * p_array).
*/
-# include <vector>
-
-# include <mln/core/internal/site_set_base.hh>
-# include <mln/core/p_array_piter.hh>
+# include <mln/core/p_array.hh>
# include <mln/core/box2d.hh>
# include <mln/math/all.hh>
@@ -44,46 +42,101 @@
namespace mln
{
+ // Forward declaration.
+ class p_line2d;
+
+
+
+ namespace trait
+ {
+
+ template <>
+ struct site_set_< p_line2d >
+ {
+ typedef trait::site_set::nsites::known nsites;
+ typedef trait::site_set::bbox::straight bbox;
+ typedef trait::site_set::contents::fixed contents;
+ typedef trait::site_set::arity::unique arity;
+ };
+
+ } // end of namespace trait
+
+
/*! \brief 2D line point set class.
*/
- class line2d : public internal::site_set_base_< point2d, line2d >
+ class p_line2d : public internal::site_set_base_< point2d, p_line2d >
{
+ typedef p_line2d self_;
public:
+ /// Element associated type.
+ typedef point2d element;
+
+ /// Psite associated type.
+ typedef p_indexed_psite<self_> psite;
+
+ /// Site_Iterator associated type.
+ typedef p_indexed_fwd_piter<self_> piter;
+
/// Forward Site_Iterator associated type.
- typedef p_array_fwd_piter_<point2d> fwd_piter;
+ typedef p_indexed_fwd_piter<self_> fwd_piter;
/// Backward Site_Iterator associated type.
- typedef p_array_bkd_piter_<point2d> bkd_piter;
+ typedef p_indexed_bkd_piter<self_> bkd_piter;
+ /// Constructor without argument.
+ p_line2d();
+
/// Constructor from point \p beg to point \p end.
- line2d(const point2d& beg, const point2d& end);
+ p_line2d(const point2d& beg, const point2d& end,
+ bool is_end_excluded = false);
+
+ /// Test if \p p belongs to this point set.
+ bool has(const psite& p) const;
+
+ /// Test if index \p i belongs to this point set.
+ bool has(const util::index& i) const;
+
+ /// Test if this line is valid, i.e., initialized.
+ bool is_valid() const;
- /// Test is \p p belongs to this point set.
- bool has(const point2d& p) const;
/// Give the number of points.
- std::size_t npoints() const;
+ unsigned nsites() const;
- /// Give the exact bounding box.
- const box_<point2d>& bbox() const;
+ /// Give the point that begins the line.
+ const point2d& begin() const;
- /// Return the corresponding std::vector of points.
- const std::vector<point2d>& vect() const;
+ /// Give the point that ends the line.
+ const point2d& end() const;
- /// Return the \p i-th point.
+ /// Return the \p i-th point of the line.
const point2d& operator[](unsigned i) const;
+
+ /// Box (qualified) associated type.
+ typedef const box2d& q_box;
+
+ /// Give the exact bounding box.
+ const box2d& bbox() const;
+
+
+ /// Return the size of this site set in memory.
+ std::size_t memory_size() const;
+
+ /// Return the corresponding std::vector of points.
+ const std::vector<point2d>& std_vector() const;
+
protected:
- point2d beg_, end_;
- std::vector<point2d> vect_;
+ p_array<point2d> arr_;
box2d bb_;
- void compute_();
+ void compute_(const point2d& beg, const point2d& end,
+ bool is_end_excluded);
};
@@ -91,30 +144,42 @@
# ifndef MLN_INCLUDE_ONLY
inline
- line2d::line2d(const point2d& beg, const point2d& end)
- : beg_(beg),
- end_(end)
+ p_line2d::p_line2d()
+ {
+ mln_postcondition(! is_valid());
+ }
+
+ inline
+ p_line2d::p_line2d(const point2d& beg, const point2d& end,
+ bool is_end_excluded)
{
- compute_();
+ if (is_end_excluded)
+ mln_precondition(end != beg);
+ compute_(beg, end, is_end_excluded);
+ mln_postcondition(is_valid());
}
inline
void
- line2d::compute_()
+ p_line2d::compute_(const point2d& beg, const point2d& end,
+ bool is_end_excluded)
{
- // vect_
- dpoint2d dp = end_ - beg_;
+ if (is_end_excluded)
+ mln_precondition(end != beg);
+
+ // Compute arr_.
+ dpoint2d dp = end - beg;
int
srow = math::sign(dp.row()), drow = math::abs(dp.row()), ddrow = 2 * drow,
scol = math::sign(dp.col()), dcol = math::abs(dp.col()), ddcol = 2 * dcol,
- row = beg_.row(),
- col = beg_.col();
+ row = beg.row(),
+ col = beg.col();
if ( dcol > drow )
{
int e = ddrow - dcol;
for (int i = 0; i < dcol; ++i)
{
- vect_.push_back(make::point2d(row, col));
+ arr_.append(make::point2d(row, col));
while (e >= 0)
{
row += srow;
@@ -129,7 +194,7 @@
int e = ddcol - drow;
for (int i = 0; i < drow; ++i)
{
- vect_.push_back(make::point2d(row, col));
+ arr_.append(make::point2d(row, col));
while (e >= 0)
{
col += scol;
@@ -139,54 +204,97 @@
e += ddcol;
}
}
- vect_.push_back(make::point2d(row, col));
- // bb_
- bb_.pmin() = make::point2d(math::min(beg_.row(), end_.row()),
- math::min(beg_.col(), end_.col()));
- bb_.pmax() = make::point2d(math::max(beg_.row(), end_.row()),
- math::max(beg_.col(), end_.col()));
+ if (! is_end_excluded)
+ arr_.append(make::point2d(row, col));
+
+ // Compute bb_.
+ point2d end_ = arr_[arr_.nsites() - 1];
+ bb_.pmin() = make::point2d(math::min(beg.row(), end_.row()),
+ math::min(beg.col(), end_.col()));
+ bb_.pmax() = make::point2d(math::max(beg.row(), end_.row()),
+ math::max(beg.col(), end_.col()));
+
+ mln_postcondition(this->begin() == beg);
+ mln_postcondition(is_end_excluded == (this->end() != end));
}
inline
bool
- line2d::has(const point2d& p) const
+ p_line2d::has(const psite& p) const
{
- if (! bb_.has(p))
+ mln_precondition(p.target_() == this); // FIXME: Refine.
+ if (! has(p.index()))
return false;
- // FIXME: Optimize!
- for (unsigned i = 0; i < vect_.size(); ++i)
- if (vect_[i] == p)
+ mln_invariant(p.to_site() == (*this)[p.index()]);
return true;
- return false;
}
inline
- std::size_t
- line2d::npoints() const
+ bool
+ p_line2d::has(const util::index& i) const
+ {
+ return i >= 0 && unsigned(i) < nsites();
+ }
+
+ inline
+ bool
+ p_line2d::is_valid() const
+ {
+ mln_invariant(implies(bb_.is_valid(), ! arr_.is_empty()));
+ return bb_.is_valid();
+ }
+
+ inline
+ unsigned
+ p_line2d::nsites() const
{
- return vect_.size();
+ return arr_.nsites();
}
inline
const box2d&
- line2d::bbox() const
+ p_line2d::bbox() const
{
+ mln_precondition(is_valid());
return bb_;
}
inline
const std::vector<point2d>&
- line2d::vect() const
+ p_line2d::std_vector() const
{
- return vect_;
+ return arr_.std_vector();
}
inline
const point2d&
- line2d::operator[](unsigned i) const
+ p_line2d::operator[](unsigned i) const
+ {
+ mln_precondition(i < nsites());
+ return arr_[i];
+ }
+
+ inline
+ const point2d&
+ p_line2d::begin() const
+ {
+ mln_precondition(is_valid());
+ return arr_[0];
+ }
+
+ inline
+ const point2d&
+ p_line2d::end() const
+ {
+ mln_precondition(is_valid());
+ return arr_[nsites() - 1];
+ }
+
+ inline
+ std::size_t
+ p_line2d::memory_size() const
{
- mln_precondition(i < npoints());
- return vect_[i];
+ return arr_.memory_size() + sizeof(box2d);
}
# endif // ! MLN_INCLUDE_ONLY
@@ -194,4 +302,4 @@
} // end of namespace mln
-#endif // ! MLN_CORE_LINE2D_HH
+#endif // ! MLN_CORE_P_LINE2D_HH
Index: mln/core/def/coord.hh
--- mln/core/def/coord.hh (revision 0)
+++ mln/core/def/coord.hh (revision 0)
@@ -0,0 +1,53 @@
+// Copyright (C) 2008 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 MLN_CORE_DEF_COORD_HH
+# define MLN_CORE_DEF_COORD_HH
+
+/*! \file mln/core/def/coord.hh
+ *
+ * \brief Definition of the default coordinate type.
+ */
+
+
+namespace mln
+{
+
+ namespace def
+ {
+
+
+ /// Definition of the default coordinate type: 'short'.
+ typedef short coord;
+
+
+ } // end of namespace mln::def
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_DEF_COORD_HH
Index: mln/core/p_run.hh
--- mln/core/p_run.hh (revision 2153)
+++ mln/core/p_run.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -30,20 +30,46 @@
/*! \file mln/core/p_run.hh
*
- * \brief Definition of a point set class based on std::set.
+ * \brief Definition of a run of points.
+ *
+ * \todo Get rid of the index attribute in psite.
+ *
+ * \todo Use a lazy approach (in subj) like in p_array psite.
*/
# include <mln/core/internal/site_set_base.hh>
-# include <mln/core/internal/set_of.hh>
-# include <mln/accu/bbox.hh>
+# include <mln/core/internal/pseudo_site_base.hh>
+# include <mln/util/index.hh>
+# include <mln/util/less.hh>
namespace mln
{
- // Fwd decls.
- template <typename P> struct p_run_fwd_piter_;
- template <typename P> struct p_run_bkd_piter_;
+ // Forward declarations.
+ template <typename P> class p_run;
+ template <typename P> class p_run_psite;
+ template <typename P> class p_run_fwd_piter_;
+ template <typename P> class p_run_bkd_piter_;
+
+ // We do not use here the p_indexed* classes to gain efficiency.
+
+
+ namespace trait
+ {
+
+ template <typename P>
+ struct site_set_< p_run<P> >
+ {
+ typedef trait::site_set::nsites::known nsites;
+ typedef trait::site_set::bbox::straight bbox;
+ typedef trait::site_set::contents::fixed contents;
+ typedef trait::site_set::arity::unique arity;
+ };
+
+ } // end of namespace trait
+
+
/*! \brief Point set class in run.
*
@@ -57,63 +83,147 @@
{
public:
+ /// Element associated type.
+ typedef P element;
+
+
+ /// Psite associated type.
+ typedef p_run_psite<P> psite;
+
/// Forward Site_Iterator associated type.
typedef p_run_fwd_piter_<P> fwd_piter;
/// Backward Site_Iterator associated type.
typedef p_run_bkd_piter_<P> bkd_piter;
+ /// Site_Iterator associated type.
+ typedef fwd_piter piter;
+
+
/// Constructor without argument.
p_run();
/// Constructor.
- p_run(const P& start, std::size_t len);
+ p_run(const P& start, unsigned short len);
+
+ /// Constructor.
+ p_run(const P& start, const P& end);
/// Set the starting point.
- void set_run(const P& start, std::size_t len);
+ void init(const P& start, unsigned short len);
+
- /// Test is \p p belongs to this point set.
+ /// Test if \p p belongs to this point set.
+ bool has(const psite& p) const;
+
+ /// Test if \p p belongs to this point set.
bool has(const P& p) const;
- /// Give the number of points.
- std::size_t npoints() const;
+ /// Test if index \p i belongs to this point set.
+ bool has_index(unsigned short i) const;
+
+ /// Give the number of sites.
+ unsigned nsites() const;
/// Give the length of the run.
- std::size_t length() const;
+ unsigned short length() const;
/// Return the \p i-th point.
- P operator[](unsigned i) const;
+ P operator[](unsigned short i) const;
- /// Return the first point.
- const P& first() const;
+ /// Return the starting point.
+ const P& start() const;
+
+ /// Return (compute) the ending point.
+ P end() const;
+
+ /// Test if this run is valid, i.e., with length > 0.
+ bool is_valid() const;
+
+
+ /// Box associated type.
+ typedef mln::box<P> q_box;
/// Give the exact bounding box.
- const box_<mln_point(P)>& bbox() const;
+ mln::box<P> bbox() const;
- /// Set a relation order to p_run.
- bool operator<(const p_run<P>& rhs) const;
- protected:
+ /// Return the size of this site set in memory.
+ std::size_t memory_size() const;
- accu::bbox<P> bb_;
- // FIXME: Add invariant bb_.is_valid() <=> npoints() != 0
+ protected:
/// The first point of the run.
- P p_;
+ P start_;
/// The length of the run.
- std::size_t len_;
+ unsigned short len_;
+ };
+
+
+ template <typename P>
+ std::ostream& operator<<(std::ostream& ostr, const p_run<P>&
r);
+
- /// For internal use.
- bool is_valid_;
+ namespace util
+ {
+
+ template <typename P>
+ struct less< p_run<P> >
+ {
+ bool operator()(const p_run<P>& lhs,
+ const p_run<P>& rhs) const;
};
+ } // end of namespace mln::util
+
+
+
+ // p_run_psite<P>
+
template <typename P>
- std::ostream& operator<<(std::ostream& out, const p_run<P>&
pr)
+ class p_run_psite : public internal::pseudo_site_base_< const P&,
+ p_run_psite<P> >
{
- out << "Run: (" << pr.first() << ", " <<
pr.length() << ")";
- return out;
- }
+ typedef p_run_psite<P> self;
+ typedef internal::pseudo_site_base_<const P&, self> super;
+
+ public:
+
+ // This associated type is important to know that this particular
+ // pseudo site knows the site set it refers to.
+ typedef p_run<P> target;
+
+ // As a Proxy:
+ const P& subj_();
+
+ p_run_psite();
+
+ p_run_psite(const p_run<P>& run, int i);
+
+ int index() const;
+
+ void change_index(int i);
+ void inc_index();
+ void dec_index();
+
+ const p_run<P>* target_() const;
+ void change_target(const p_run<P>& new_target);
+
+ bool is_valid() const;
+
+ operator util::index() const;
+
+ const p_run<P>& run() const;
+
+ private:
+
+ const p_run<P>* run_;
+ int i_;
+ mutable P p_;
+ };
+
+
# ifndef MLN_INCLUDE_ONLY
@@ -121,38 +231,65 @@
inline
p_run<P>::p_run()
{
- is_valid_ = false;
+ len_ = 0;
}
template <typename P>
inline
- p_run<P>::p_run(const P& start, std::size_t len)
- : p_(start),
- len_(len)
+ p_run<P>::p_run(const P& start, unsigned short len)
{
mln_precondition(len != 0);
- P p = start;
- bb_.init();
- bb_.take(p);
- p[P::dim - 1] += len - 1;
- bb_.take(p);
- is_valid_ = true;
+ init(start, len);
+ }
+
+ template <typename P>
+ inline
+ p_run<P>::p_run(const P& start, const P& end)
+ : start_(start)
+ {
+ mln_precondition(cut_(end) == cut_(start));
+ mln_precondition(end.last_coord() >= start.last_coord());
+ len_ = end.last_coord() - start.last_coord() + 1;
}
template <typename P>
inline
void
- p_run<P>::set_run(const P& start, std::size_t len)
+ p_run<P>::init(const P& start, unsigned short len)
{
mln_precondition(len != 0);
- p_ = start;
+ start_ = start;
len_ = len;
- P p = start;
- bb_.init();
- bb_.take(p);
- p[P::dim - 1] += len - 1;
- bb_.take(p);
- is_valid_ = true;
+ }
+
+ template <typename P>
+ inline
+ bool
+ p_run<P>::is_valid() const
+ {
+ return len_ != 0;
+ }
+
+ template <typename P>
+ inline
+ mln::box<P>
+ p_run<P>::bbox() const
+ {
+ mln::box<P> b(this->start_, this->end());
+ return b;
+ }
+
+ template <typename P>
+ inline
+ bool
+ p_run<P>::has(const psite& p) const
+ {
+ mln_precondition(p.target_() == this); // FIXME: Refine.
+ if (p.index() < 0 || unsigned(p.index()) >= len_)
+ return false;
+ // The type of rhs below is mln_site(p_run<P>).
+ mln_invariant(p.to_site() == (*this)[p.index()]);
+ return true;
}
template <typename P>
@@ -160,77 +297,216 @@
bool
p_run<P>::has(const P& p) const
{
- mln_precondition(is_valid_);
- bool res = true;
- for (int i = P::dim - 2; i >= 0; --i)
- if (!(res = (res && p[i] == p_[i])))
+ mln_precondition(is_valid());
+ if (cut_(p) != cut_(start_))
return false;
- return (p[P::dim - 1] >= p_[P::dim - 1]
- && p[P::dim - 1] < p_[P::dim - 1] + (signed)len_);
+ return
+ p.last_coord() >= start_.last_coord() &&
+ p.last_coord() < start_.last_coord() + len_;
}
template <typename P>
inline
- std::size_t
- p_run<P>::npoints() const
+ bool
+ p_run<P>::has_index(unsigned short i) const
{
- mln_precondition(is_valid_);
+ return i < len_;
+ }
+
+ template <typename P>
+ inline
+ unsigned
+ p_run<P>::nsites() const
+ {
+ mln_precondition(is_valid());
return len_;
}
template <typename P>
inline
- std::size_t
+ unsigned short
p_run<P>::length() const
{
- mln_precondition(is_valid_);
+ mln_precondition(is_valid());
return len_;
}
template <typename P>
inline
P
- p_run<P>::operator[](unsigned i) const
+ p_run<P>::operator[](unsigned short i) const
{
- mln_precondition(is_valid_);
- mln_precondition(i < npoints());
- P p = p_;
- p[P::dim - 1] += i;
+ mln_precondition(is_valid());
+ mln_precondition(i < len_);
+ P p = start_;
+ p.last_coord() += i;
return p;
}
template <typename P>
inline
const P&
- p_run<P>::first() const
+ p_run<P>::start() const
{
- return p_;
+ return start_;
}
template <typename P>
inline
- const box_<mln_point(P)>&
- p_run<P>::bbox() const
+ P
+ p_run<P>::end() const
+ {
+ P p = start_;
+ p.last_coord() += len_ - 1;
+ return p;
+ }
+
+ template <typename P>
+ inline
+ std::size_t
+ p_run<P>::memory_size() const
+ {
+ return sizeof(*this);
+ }
+
+ template <typename P>
+ std::ostream& operator<<(std::ostream& ostr, const p_run<P>&
r)
+ {
+ ostr << '(' << r.start() << ", " <<
r.length() << ')';
+ return ostr;
+ }
+
+
+
+ // Ordering.
+
+ namespace util
+ {
+
+ template <typename P>
+ inline
+ bool
+ less< p_run<P> >::operator()(const p_run<P>& lhs,
+ const p_run<P>& rhs) const
+ {
+ return op_less(lhs.start(), rhs.start());
+ }
+
+ } // end of namespace mln::util
+
+
+
+ // p_run_psite<P>
+
+ template <typename P>
+ inline
+ p_run_psite<P>::p_run_psite()
+ : run_(0),
+ i_(0)
{
- mln_precondition(is_valid_);
- mln_precondition(npoints() != 0);
- return bb_.to_result();
+ }
+
+ template <typename P>
+ inline
+ p_run_psite<P>::p_run_psite(const p_run<P>& run, int i)
+ : run_(&run),
+ i_(i)
+ {
+ p_ = run.start();
+ p_.last_coord() += i_;
}
template <typename P>
inline
bool
- p_run<P>::operator<(const p_run<P>& rhs) const
+ p_run_psite<P>::is_valid() const
{
- return (this->p_ < rhs.p_)
- || (this->p_ == rhs.p_ && this->len_ < rhs.len_);
+ return run_ != 0 && run_->has_index(i_);
}
+ template <typename P>
+ inline
+ int
+ p_run_psite<P>::index() const
+ {
+ return i_;
+ }
+
+ template <typename P>
+ inline
+ void
+ p_run_psite<P>::change_index(int i)
+ {
+ p_.last_coord() += (i - i_);
+ i_ = i;
+ }
+
+ template <typename P>
+ inline
+ void
+ p_run_psite<P>::dec_index()
+ {
+ --i_;
+ p_.last_coord() -= 1;
+ }
+
+ template <typename P>
+ inline
+ void
+ p_run_psite<P>::inc_index()
+ {
+ ++i_;
+ p_.last_coord() += 1;
+ }
+
+ template <typename P>
+ inline
+ const p_run<P>*
+ p_run_psite<P>::target_() const
+ {
+ return run_;
+ }
+
+ template <typename P>
+ inline
+ void
+ p_run_psite<P>::change_target(const p_run<P>& new_target)
+ {
+ run_ = & new_target;
+ i_ = 0;
+ p_ = run_->start();
+ }
+
+ template <typename P>
+ inline
+ const P&
+ p_run_psite<P>::subj_()
+ {
+ return p_;
+ }
+
+ template <typename P>
+ inline
+ p_run_psite<P>::operator util::index() const
+ {
+ return i_;
+ }
+
+ template <typename P>
+ inline
+ const p_run<P>&
+ p_run_psite<P>::run() const
+ {
+ mln_precondition(run_ != 0);
+ return *run_;
+ }
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln
+
# include <mln/core/p_run_piter.hh>
+
#endif // ! MLN_CORE_P_RUN_HH
Index: mln/core/p_run_piter.hh
--- mln/core/p_run_piter.hh (revision 2153)
+++ mln/core/p_run_piter.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -34,6 +34,7 @@
*/
# include <mln/core/p_run.hh>
+# include <mln/core/internal/site_set_iterator_base.hh>
namespace mln
@@ -43,53 +44,36 @@
*
*/
template <typename P>
- struct p_run_fwd_piter_ : public internal::site_iterator_base_< P,
p_run_fwd_piter_<P> >
+ class p_run_fwd_piter_
+ :
+ public internal::site_set_iterator_base< p_run<P>,
+ p_run_fwd_piter_<P> >
{
typedef p_run_fwd_piter_<P> self_;
- typedef internal::site_iterator_base_< P, self_ > super_;
+ typedef internal::site_set_iterator_base< p_run<P>, self_ > super_;
public:
- // Make definitions from super class available.
- enum { dim = super_::dim };
-
/// Constructor without arguments.
p_run_fwd_piter_();
/// Coordinate associated type.
- p_run_fwd_piter_(const p_run<P>& pr);
-
- /// Assign a new run to iterate.
- void assign_run(const p_run<P>& pr);
-
- /// Reference of the corresponding point.
- const P& to_point() const;
-
- /// Read-only access to the \p i-th coordinate.
- mln_coord(P) operator[](unsigned i) const;
+ p_run_fwd_piter_(const p_run<P>& r);
/// Test if the iterator is valid.
- bool is_valid() const;
+ bool is_valid_() const;
/// Invalidate the iterator.
- void invalidate();
+ void invalidate_();
/// Start an iteration.
- void start();
+ void start_();
/// Go to the next point.
void next_();
- /// Get the index of the point in the run.
- unsigned ind() const;
-
- /// Convert the iterator into a point.
- operator P() const;
-
protected:
- const p_run<P>* run_;
- bool is_valid_;
- unsigned i_;
- P p_;
+ using super_::p_;
+ using super_::s_;
};
@@ -98,53 +82,36 @@
*
*/
template <typename P>
- struct p_run_bkd_piter_ : public internal::site_iterator_base_< P,
p_run_bkd_piter_<P> >
+ class p_run_bkd_piter_
+ :
+ public internal::site_set_iterator_base< p_run<P>,
+ p_run_bkd_piter_<P> >
{
typedef p_run_bkd_piter_<P> self_;
- typedef internal::site_iterator_base_< P, self_ > super_;
+ typedef internal::site_set_iterator_base< p_run<P>, self_ > super_;
public:
- // Make definitions from super class available.
- enum { dim = super_::dim };
-
/// Constructor without arguments.
p_run_bkd_piter_();
/// Coordinate associated type.
- p_run_bkd_piter_(const p_run<P>& pr);
-
- /// Assign a new run to iterate.
- void assign_run(const p_run<P>& pr);
-
- /// Reference of the corresponding point.
- const P& to_point() const;
-
- /// Read-only access to the \p i-th coordinate.
- mln_coord(P) operator[](unsigned i) const;
+ p_run_bkd_piter_(const p_run<P>& r);
/// Test if the iterator is valid.
- bool is_valid() const;
+ bool is_valid_() const;
/// Invalidate the iterator.
- void invalidate();
+ void invalidate_();
/// Start an iteration.
- void start();
+ void start_();
/// Go to the next point.
void next_();
- /// Get the index of the point in the run.
- unsigned ind() const;
-
- /// Convert the iterator into a point.
- operator P() const;
-
protected:
- const p_run<P>* run_;
- bool is_valid_;
- unsigned i_;
- P p_;
+ using super_::p_;
+ using super_::s_;
};
@@ -156,73 +123,39 @@
template <typename P>
inline
p_run_fwd_piter_<P>::p_run_fwd_piter_()
- : run_ (0),
- is_valid_(false)
- {
- }
-
- template <typename P>
- inline
- p_run_fwd_piter_<P>::p_run_fwd_piter_(const p_run<P>& pr)
- : run_(&pr),
- is_valid_(false)
- {
- }
-
- template <typename P>
- inline
- void
- p_run_fwd_piter_<P>::assign_run(const p_run<P>& pr)
- {
- run_ = ≺
- is_valid_ = false;
- }
-
- template <typename P>
- inline
- const P&
- p_run_fwd_piter_<P>::to_point() const
{
- mln_precondition(is_valid());
- mln_assertion(p_[P::dim - 1] - run_->first()[P::dim - 1] == signed(i_));
- return p_;
}
template <typename P>
inline
- mln_coord(P)
- p_run_fwd_piter_<P>::operator[](unsigned i) const
+ p_run_fwd_piter_<P>::p_run_fwd_piter_(const p_run<P>& r)
{
- mln_precondition(i < dim);
- mln_precondition(is_valid());
- mln_assertion(p_[P::dim - 1] - run_->first()[P::dim - 1] == signed(i_));
- return p_[i];
+ this->change_target(r);
}
template <typename P>
inline
bool
- p_run_fwd_piter_<P>::is_valid() const
+ p_run_fwd_piter_<P>::is_valid_() const
{
- return is_valid_;
+ mln_invariant(p_.index() >= 0);
+ return p_.index() < int(s_->length());
}
template <typename P>
inline
void
- p_run_fwd_piter_<P>::invalidate()
+ p_run_fwd_piter_<P>::invalidate_()
{
- is_valid_ = false;
+ p_.change_index(s_->length());
}
template <typename P>
inline
void
- p_run_fwd_piter_<P>::start()
+ p_run_fwd_piter_<P>::start_()
{
- p_ = run_->first();
- i_ = 0;
- is_valid_ = true;
+ p_.change_index(0);
}
template <typename P>
@@ -230,28 +163,7 @@
void
p_run_fwd_piter_<P>::next_()
{
- mln_assertion(p_[P::dim - 1] - run_->first()[P::dim - 1] == signed(i_));
- p_[dim - 1]++;
- ++i_;
- is_valid_ = p_[dim - 1] - run_->first()[dim - 1] < (signed)run_->length();
- }
-
- template <typename P>
- inline
- unsigned
- p_run_fwd_piter_<P>::ind() const
- {
- mln_assertion(p_[P::dim - 1] - run_->first()[P::dim - 1] == signed(i_));
- return i_;
- }
-
- template <typename P>
- inline
- p_run_fwd_piter_<P>::operator P() const
- {
- mln_precondition(is_valid());
- mln_assertion(p_[P::dim - 1] - run_->first()[P::dim - 1] == signed(i_));
- return p_;
+ p_.inc_index();
}
@@ -260,72 +172,39 @@
template <typename P>
inline
p_run_bkd_piter_<P>::p_run_bkd_piter_()
- : run_ (0)
- {
- }
-
- template <typename P>
- inline
- p_run_bkd_piter_<P>::p_run_bkd_piter_(const p_run<P>& pr)
- : run_(&pr),
- is_valid_(false)
{
}
template <typename P>
inline
- void
- p_run_bkd_piter_<P>::assign_run(const p_run<P>& pr)
+ p_run_bkd_piter_<P>::p_run_bkd_piter_(const p_run<P>& r)
{
- run_ = ≺
- is_valid_ = false;
- }
-
- template <typename P>
- inline
- const P&
- p_run_bkd_piter_<P>::to_point() const
- {
- mln_precondition(is_valid());
- mln_assertion(p_[P::dim - 1] - run_->first()[P::dim - 1] == signed(i_));
- return p_;
- }
-
- template <typename P>
- inline
- mln_coord(P)
- p_run_bkd_piter_<P>::operator[](unsigned i) const
- {
- mln_precondition(i < dim);
- mln_precondition(is_valid());
- mln_assertion(p_[P::dim - 1] - run_->first()[P::dim - 1] == signed(i_));
- return p_[i];
+ this->change_target(r);
}
template <typename P>
inline
bool
- p_run_bkd_piter_<P>::is_valid() const
+ p_run_bkd_piter_<P>::is_valid_() const
{
- return is_valid_;
+ mln_invariant(p_.index() < int(s_->length()));
+ return p_.index() >= 0;
}
template <typename P>
inline
void
- p_run_bkd_piter_<P>::invalidate()
+ p_run_bkd_piter_<P>::invalidate_()
{
- is_valid_ = false;
+ p_.change_index(-1);
}
template <typename P>
inline
void
- p_run_bkd_piter_<P>::start()
+ p_run_bkd_piter_<P>::start_()
{
- p_ = (*run_)[run_->length() - 1];
- i_ = run_->length() - 1;
- is_valid_ = true;
+ p_.change_index(s_->length() - 1);
}
template <typename P>
@@ -333,29 +212,9 @@
void
p_run_bkd_piter_<P>::next_()
{
- mln_assertion(p_[P::dim - 1] - run_->first()[P::dim - 1] == signed(i_));
- p_[dim - 1]--;
- --i_;
- is_valid_ = p_[dim - 1] - run_->first()[dim - 1] >= 0;
+ p_.dec_index();
}
- template <typename P>
- inline
- unsigned
- p_run_bkd_piter_<P>::ind() const
- {
- mln_assertion(p_[P::dim - 1] - run_->first()[P::dim - 1] == signed(i_));
- return i_;
- }
-
- template <typename P>
- inline
- p_run_bkd_piter_<P>::operator P() const
- {
- mln_precondition(is_valid());
- mln_assertion(p_[P::dim - 1] - run_->first()[P::dim - 1] == signed(i_));
- return p_;
- }
# endif // ! MLN_INCLUDE_ONLY
Index: mln/core/p_array.hh
--- mln/core/p_array.hh (revision 2153)
+++ mln/core/p_array.hh (working copy)
@@ -31,88 +31,30 @@
/*! \file mln/core/p_array.hh
*
* \brief Definition of a point set class based on std::vector.
+ *
+ * \todo Add a facade to index_of_in so that it dispatches when
+ * calling it with Object<p_array_site>.
+ *
+ * \todo Use util::index (instead of int) as many times as possible.
*/
# include <vector>
# include <mln/core/internal/site_set_base.hh>
# include <mln/core/internal/pseudo_site_base.hh>
-# include <mln/accu/bbox.hh>
# include <mln/util/index.hh>
namespace mln
{
- // Fwd decls.
+ // Forward declarations.
template <typename P> class p_array;
- template <typename P> struct p_array_fwd_piter_;
- template <typename P> struct p_array_bkd_piter_;
-
-
- // p_array_psite<P>
-
- template <typename P>
- class p_array_psite : public internal::pseudo_site_base_< false, // Not mutable.
- P,
- p_array_psite<P> >
- {
- typedef p_array_psite<P> self;
- typedef internal::pseudo_site_base_<true, P, self> super;
- public:
+ template <typename S> class p_indexed_psite;
+ template <typename S> struct p_indexed_fwd_piter;
+ template <typename S> struct p_indexed_bkd_piter;
- // This associated type is important to know that this particular
- // pseudo site knows the site set it refers to.
- typedef p_array<P> target_t;
-
-
- // As a Proxy:
-
- const P& unproxy() const;
-
- // As a Site_Proxy:
-
- typedef typename super::site site;
-
- const site& to_site() const;
-
- // As Itself.
-
- p_array_psite();
-
- p_array_psite(const p_array<P>& arr, int i);
-
- int index() const;
-
- void change_index(int i);
- void inc_index();
- void dec_index();
-
- const p_array<P>* target() const;
-
- const p_array<P>*& target();
-
- bool is_valid() const;
-
- operator util::index() const { return i_; }
-
-
- private:
-
- const p_array<P>* arr_;
- int i_;
- mutable P p_;
-
- void update_p_() const;
- };
-
-
- template <typename P, typename A>
- int index_of_in(const P&, const A&);
-
- template <typename P, typename A>
- int index_of_in(const p_array_psite<P>& p, const A& arr);
namespace trait
@@ -123,7 +65,7 @@
{
typedef trait::site_set::nsites::known nsites;
typedef trait::site_set::bbox::unknown bbox;
- typedef trait::site_set::contents::free contents;
+ typedef trait::site_set::contents::growing contents;
typedef trait::site_set::arity::multiple arity;
};
@@ -131,7 +73,6 @@
-
/*! \brief Site set class based on std::vector.
*
* This is a multi-set of sites.
@@ -139,23 +80,24 @@
template <typename P>
class p_array : public internal::site_set_base_< P, p_array<P> >
{
- typedef internal::site_set_base_< P, p_array<P> > super;
+ typedef p_array<P> self_;
public:
- /// The associated psite type.
- typedef p_array_psite<P> psite;
+ /// Element associated type.
+ typedef P element;
- /// The associated site type.
- typedef typename super::site site;
-
- /// Site_Iterator associated type.
- typedef p_array_fwd_piter_<P> piter;
+ /// Psite associated type.
+ typedef p_indexed_psite<self_> psite;
/// Forward Site_Iterator associated type.
- typedef p_array_fwd_piter_<P> fwd_piter;
+ typedef p_indexed_fwd_piter<self_> fwd_piter;
/// Backward Site_Iterator associated type.
- typedef p_array_bkd_piter_<P> bkd_piter;
+ typedef p_indexed_bkd_piter<self_> bkd_piter;
+
+ /// Site_Iterator associated type.
+ typedef fwd_piter piter;
+
/// Constructor.
p_array();
@@ -163,34 +105,27 @@
/// Constructor from a vector \p vect.
p_array(const std::vector<P>& vect);
+
/// Reserve \p n cells.
void reserve(std::size_t n);
+
/// Test is \p p belongs to this site set.
bool has(const psite& p) const;
- /// Test is \p i belongs to this site set.
- bool has(const util::index& i) const
- {
- return i >= 0 && i < int(vect_.size());
- }
+ /// Test is index \p i belongs to this site set.
+ bool has(const util::index& i) const;
- /// Give the i-th element.
- const P& operator[](const util::index& i) const
- {
- mln_precondition(has(i));
- return vect_[i];
- }
+ /// Test this set validity so returns always true.
+ bool is_valid() const;
- /// Test is index \p i belongs to this site set.
- // FIXME: Add an overload "has(index)".
- bool has_index(int i) const;
/// Change site \p p into \p new_p.
void change(const psite& p, const P& new_p);
/// Give the number of sites.
- std::size_t nsites() const;
+ unsigned nsites() const;
+
/// Append a point \p p.
p_array<P>& append(const P& p);
@@ -198,14 +133,15 @@
/// Append an array \p other of points.
p_array<P>& append(const p_array<P>& other);
+ /// Insertion element associated type.
+ typedef P i_element;
+
/// Insert a point \p p (equivalent as 'append').
void insert(const P& p);
/// Clear this set.
void clear();
- /// Return the corresponding std::vector of points.
- const std::vector<P>& vect() const;
/// Return the \p i-th site (constant).
const P& operator[](unsigned i) const;
@@ -213,6 +149,20 @@
/// Return the \p i-th site (mutable).
P& operator[](unsigned i);
+ /// Return the i-th element.
+ const P& operator[](const util::index& i) const;
+ // FIXME: Is-it useful? (redundant with 'int'?)
+
+
+ /// Return the size of this site set in memory.
+ std::size_t memory_size() const;
+
+ /// Return the corresponding std::vector of points.
+ const std::vector<P>& std_vector() const;
+
+ /// Hook to the std::vector.
+ std::vector<P>& hook_std_vector_();
+
protected:
std::vector<P> vect_;
@@ -220,6 +170,152 @@
+ // p_indexed_psite<P>
+
+ template <typename S>
+ class p_indexed_psite : public internal::pseudo_site_base_< const
mln_element(S)&,
+ p_indexed_psite<S> >
+ {
+ public:
+
+ typedef mln_element(S) element;
+
+ // This associated type is important to know that this particular
+ // pseudo site knows the site set it refers to.
+ typedef S target;
+
+ // As a Proxy:
+ const element& subj_();
+
+ // As Itself.
+
+ p_indexed_psite();
+
+ p_indexed_psite(const S& s, int i);
+
+ const util::index& index() const;
+
+ void change_index(int i);
+ void inc_index();
+ void dec_index();
+
+ const S* target_() const;
+ void change_target(const S& newtarget);
+
+ bool is_valid() const;
+
+ operator util::index() const;
+
+ private:
+
+ const S* s_;
+ util::index i_;
+ mutable element p_;
+ };
+
+
+
+ /// Forward iterator on sites of an indexed site set.
+
+ template <typename S>
+ class p_indexed_fwd_piter
+ :
+ public internal::site_set_iterator_base< S,
+ p_indexed_fwd_piter<S> >
+ {
+ typedef p_indexed_fwd_piter<S> self;
+ typedef internal::site_set_iterator_base<S, self> super;
+
+ public:
+
+ /// Constructor with no argument.
+ p_indexed_fwd_piter();
+
+ /// Constructor.
+ p_indexed_fwd_piter(const S& s);
+
+ /// Test if the iterator is valid.
+ bool is_valid_() const;
+
+ /// Invalidate the iterator.
+ void invalidate_();
+
+ /// Start an iteration.
+ void start_();
+
+ /// Go to the next point.
+ void next_();
+
+ /// Return the current index.
+ int index() const;
+
+ protected:
+ using super::p_;
+ using super::s_;
+ };
+
+
+
+ /// Backward iterator on sites of an indexed site set.
+
+ template <typename S>
+ class p_indexed_bkd_piter
+ :
+ public internal::site_set_iterator_base< S,
+ p_indexed_bkd_piter<S> >
+ {
+ typedef p_indexed_bkd_piter<S> self;
+ typedef internal::site_set_iterator_base<S, self> super;
+
+ public:
+
+ /// Constructor with no argument.
+ p_indexed_bkd_piter();
+
+ /// Constructor.
+ p_indexed_bkd_piter(const S& s);
+
+ /// Test if the iterator is valid.
+ bool is_valid_() const;
+
+ /// Invalidate the iterator.
+ void invalidate_();
+
+ /// Start an iteration.
+ void start_();
+
+ /// Go to the next point.
+ void next_();
+
+ /// Return the current index.
+ int index() const;
+
+ protected:
+ using super::p_;
+ using super::s_;
+ };
+
+
+
+ // Procedures.
+
+ template <typename P, typename S>
+ int index_of_in(const P&, const S&);
+
+ template <typename S>
+ int index_of_in(const p_indexed_psite<S>& p, const S& s);
+
+ template <typename S, typename A>
+ int index_of_in(const p_indexed_psite<S>& p, const A& a);
+
+ template <typename S, typename A>
+ int index_of_in(const p_indexed_fwd_piter<S>& p, const A& arr);
+
+ template <typename S, typename A>
+ int index_of_in(const p_indexed_bkd_piter<S>& p, const A& arr);
+
+
+
# ifndef MLN_INCLUDE_ONLY
@@ -251,25 +347,42 @@
bool
p_array<P>::has(const psite& p) const
{
- mln_precondition(p.target() == this); // FIXME: Refine.
- if (p.index() < 0 || p.index() >= int(vect_.size()))
+ mln_precondition(p.target_() == this); // FIXME: Refine.
+ if (! has(p.index()))
return false;
- site s_ = (*this)[p.index()];
- mln_invariant(p.to_site() == s_);
+ // The type of rhs below is mln_site(p_array<P>).
+ mln_invariant(p.to_site() == (*this)[p.index()]);
return true;
}
template <typename P>
inline
bool
- p_array<P>::has_index(int i) const
+ p_array<P>::has(const util::index& i) const
{
- return i >= 0 && i < int(vect_.size());
+ return i >= 0 && unsigned(i) < nsites();
}
template <typename P>
inline
- std::size_t
+ bool
+ p_array<P>::is_valid() const
+ {
+ return true;
+ }
+
+ template <typename P>
+ inline
+ const P&
+ p_array<P>::operator[](const util::index& i) const
+ {
+ mln_precondition(has(i));
+ return vect_[i];
+ }
+
+ template <typename P>
+ inline
+ unsigned
p_array<P>::nsites() const
{
return vect_.size();
@@ -298,7 +411,8 @@
p_array<P>::append(const p_array<P>& other)
{
vect_.insert(vect_.end(),
- other.vect().begin(), other.vect().end());
+ other.std_vector().begin(),
+ other.std_vector().end());
return *this;
}
@@ -312,14 +426,6 @@
template <typename P>
inline
- const std::vector<P>&
- p_array<P>::vect() const
- {
- return vect_;
- }
-
- template <typename P>
- inline
const P&
p_array<P>::operator[](unsigned i) const
{
@@ -345,131 +451,282 @@
vect_[p.index()] = new_p;
}
-
- // p_array_psite<P>
-
template <typename P>
inline
- p_array_psite<P>::p_array_psite()
- : arr_(0),
- i_(0)
+ std::size_t
+ p_array<P>::memory_size() const
{
+ return sizeof(*this) + nsites() * sizeof(P);
}
template <typename P>
inline
- void
- p_array_psite<P>::update_p_() const
+ const std::vector<P>&
+ p_array<P>::std_vector() const
{
- if (arr_ == 0 || ! arr_->has_index(i_))
- return;
- p_ = (*arr_)[i_];
+ return vect_;
}
template <typename P>
inline
- p_array_psite<P>::p_array_psite(const p_array<P>& arr, int i)
- : arr_(&arr),
- i_(i)
+ std::vector<P>&
+ p_array<P>::hook_std_vector_()
{
- update_p_();
+ return vect_;
}
- template <typename P>
+
+
+ // p_indexed_psite<S>
+
+ template <typename S>
inline
- const typename p_array_psite<P>::site&
- p_array_psite<P>::to_site() const
+ p_indexed_psite<S>::p_indexed_psite()
+ : s_(0),
+ i_(0)
{
- const site* s;
- internal::get_adr(s, *this);
- return *s;
}
- template <typename P>
+ template <typename S>
inline
- int
- p_array_psite<P>::index() const
+ p_indexed_psite<S>::p_indexed_psite(const S& s, int i)
+ : s_(& s),
+ i_(i)
+ {
+ }
+
+ template <typename S>
+ inline
+ const util::index&
+ p_indexed_psite<S>::index() const
{
return i_;
}
- template <typename P>
+ template <typename S>
inline
void
- p_array_psite<P>::change_index(int i)
+ p_indexed_psite<S>::change_index(int i)
{
i_ = i;
- update_p_();
}
- template <typename P>
+ template <typename S>
inline
void
- p_array_psite<P>::dec_index()
+ p_indexed_psite<S>::dec_index()
{
--i_;
- update_p_();
}
- template <typename P>
+ template <typename S>
inline
void
- p_array_psite<P>::inc_index()
+ p_indexed_psite<S>::inc_index()
{
++i_;
- update_p_();
}
- template <typename P>
+ template <typename S>
inline
- const p_array<P>*
- p_array_psite<P>::target() const
+ void
+ p_indexed_psite<S>::change_target(const S& newtarget)
{
- return arr_;
+ s_ = & newtarget;
+ i_ = -1; // Invalidate.
}
- template <typename P>
+ template <typename S>
inline
- const p_array<P>*&
- p_array_psite<P>::target()
+ bool
+ p_indexed_psite<S>::is_valid() const
{
- return arr_;
+ return s_ != 0 && s_->has(i_);
}
- template <typename P>
+ template <typename S>
inline
- const P&
- p_array_psite<P>::unproxy() const
+ const S*
+ p_indexed_psite<S>::target_() const
+ {
+ return s_;
+ }
+
+ template <typename S>
+ inline
+ const mln_element(S)&
+ p_indexed_psite<S>::subj_()
{
- mln_precondition(arr_ != 0);
- update_p_();
+ if (is_valid())
+ // Lazy update.
+ p_ = (*s_)[i_];
return p_;
}
+ template <typename S>
+ inline
+ p_indexed_psite<S>::operator util::index() const
+ {
+ return i_;
+ }
+
+
+ // p_indexed_fwd_piter<S>.
+
+ template <typename S>
+ inline
+ p_indexed_fwd_piter<S>::p_indexed_fwd_piter()
+ {
+ }
+
+ template <typename S>
+ inline
+ p_indexed_fwd_piter<S>::p_indexed_fwd_piter(const S& s)
+ {
+ this->change_target(s);
+ }
+
+ template <typename S>
+ inline
+ bool
+ p_indexed_fwd_piter<S>::is_valid_() const
+ {
+ mln_invariant(p_.index() >= 0);
+ return p_.index() < int(s_->nsites());
+ }
+
+ template <typename S>
+ inline
+ void
+ p_indexed_fwd_piter<S>::invalidate_()
+ {
+ p_.change_index(s_->nsites());
+ }
+
+ template <typename S>
+ inline
+ void
+ p_indexed_fwd_piter<S>::start_()
+ {
+ p_.change_index(0);
+ }
+
+ template <typename S>
+ inline
+ void
+ p_indexed_fwd_piter<S>::next_()
+ {
+ p_.inc_index();
+ }
+
+ template <typename S>
+ inline
+ int
+ p_indexed_fwd_piter<S>::index() const
+ {
+ return p_.index();
+ }
+
+
+ // p_indexed_bkd_piter<S>.
+
+ template <typename S>
+ inline
+ p_indexed_bkd_piter<S>::p_indexed_bkd_piter()
+ {
+ }
+
+ template <typename S>
+ inline
+ p_indexed_bkd_piter<S>::p_indexed_bkd_piter(const S& s)
+ {
+ this->change_target(s);
+ }
+
+ template <typename S>
+ inline
+ bool
+ p_indexed_bkd_piter<S>::is_valid_() const
+ {
+ mln_invariant(p_.index() < int(s_->nsites()));
+ return p_.index() >= 0;
+ }
+
+ template <typename S>
+ inline
+ void
+ p_indexed_bkd_piter<S>::invalidate_()
+ {
+ p_.change_index(-1);
+ }
+
+ template <typename S>
+ inline
+ void
+ p_indexed_bkd_piter<S>::start_()
+ {
+ p_.change_index(s_->nsites() - 1);
+ }
+
+ template <typename S>
+ inline
+ void
+ p_indexed_bkd_piter<S>::next_()
+ {
+ p_.dec_index();
+ }
+
+ template <typename S>
+ inline
+ int
+ p_indexed_bkd_piter<S>::index() const
+ {
+ return p_.index();
+ }
+
// Procedures
- template <typename P, typename A>
- int index_of_in(const P&, const A&)
+ template <typename P, typename S>
+ int index_of_in(const P&, const S&)
{
return -1;
}
- template <typename P, typename A>
- int index_of_in(const p_array_psite<P>& p, const A& arr)
+ template <typename S>
+ int index_of_in(const p_indexed_psite<S>& p, const S& s)
{
- if ((void*)(p.target()) == (void*)(&arr))
+ if ((void*)(p.target_()) == (void*)(&s))
return p.index();
else
- return index_of_in(p.unproxy(), arr);
+ return index_of_in(p.unproxy_(), s);
}
-# endif // ! MLN_INCLUDE_ONLY
+ template <typename S, typename A>
+ int index_of_in(const p_indexed_psite<S>& p, const A& a)
+ {
+ return index_of_in(p.unproxy_(), a);
+ }
-} // end of namespace mln
+ template <typename S, typename A>
+ inline
+ int
+ index_of_in(const p_indexed_fwd_piter<S>& p, const A& arr)
+ {
+ return index_of_in(p.unproxy_(), arr);
+ }
+ template <typename S, typename A>
+ inline
+ int
+ index_of_in(const p_indexed_bkd_piter<S>& p, const A& arr)
+ {
+ return index_of_in(p.unproxy_(), arr);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
-# include <mln/core/p_array_piter.hh>
+} // end of namespace mln
#endif // ! MLN_CORE_P_ARRAY_HH
Index: mln/core/concept/proxy.hh
--- mln/core/concept/proxy.hh (revision 2153)
+++ mln/core/concept/proxy.hh (working copy)
@@ -34,13 +34,15 @@
*
* \todo preinc and predec are not tested; post-like ops are not handled.
*
- * \todo add op=(Literal) when possible, so add a constness property.
+ * \todo add "op=(T)" when possible, so add a constness property.
+ * \todo add "opT()const" when possible.
*/
# include <mln/core/concept/object.hh>
-# include <mln/core/internal/force_exact.hh>
# include <mln/value/ops.hh> // So that we can handle builtins, scalars, and
objects.
+# include <mln/core/concept/proxy.hxx>
+
# define mln_decl_unop_proxy(Name, Symb) \
@@ -59,7 +61,7 @@
mln_trait_op_##Name(P) \
operator Symb (const mln::Proxy<P>& rhs) \
{ \
- return Symb exact(rhs).unproxy(); \
+ return Symb exact(rhs).unproxy_(); \
} \
\
struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
@@ -93,9 +95,9 @@
mln_trait_op_##Name(L, R) \
operator Symb (const mln::Proxy<L>& lhs, const mln::Proxy<R>&
rhs) \
{ \
- typedef typename internal::unproxy_couple<L, R>::L_helper L_unproxy; \
- typedef typename internal::unproxy_couple<L, R>::R_helper R_unproxy; \
- return L_unproxy::on(lhs) Symb R_unproxy::on(rhs); \
+ typedef typename internal::helper_unprox_binop<L, R>::L_helper L_helper; \
+ typedef typename internal::helper_unprox_binop<L, R>::R_helper R_helper; \
+ return L_helper::on(lhs) Symb R_helper::on(rhs); \
} \
\
template <typename P, typename O> \
@@ -103,7 +105,7 @@
mln_trait_op_##Name(P, O) \
operator Symb (const Proxy<P>& p, const Object<O>& o) \
{ \
- return exact(p).unproxy() Symb exact(o); \
+ return exact(p).unproxy_() Symb exact(o); \
} \
\
template <typename O, typename P> \
@@ -111,7 +113,7 @@
mln_trait_op_##Name(O, P) \
operator Symb (const Object<O>& o, const Proxy<P>& p) \
{ \
- return exact(o) Symb exact(p).unproxy(); \
+ return exact(o) Symb exact(p).unproxy_(); \
} \
\
struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
@@ -122,44 +124,10 @@
namespace mln
{
- // Fwd decls.
+ // Fwd decl.
template <typename E> struct Proxy;
- namespace internal
- {
-
- template <bool b, typename P> struct unproxy_if;
-
- template <typename P>
- struct unproxy_if< true, P >
- {
- typedef mln_subject(P) ret;
- static typename P::q_subject on(const Proxy<P>& p) { return
exact(p).unproxy(); }
- };
-
- template <typename P>
- struct unproxy_if< false, P >
- {
- typedef P ret;
- static const P& on(const Proxy<P>& p) { return exact(p); }
- };
-
- template <typename L, typename R>
- struct unproxy_couple
- {
- enum { L_level = L::proxy_level,
- R_level = R::proxy_level }; // To prevent a weird g++ warning.
- typedef internal::unproxy_if<(L_level >= R_level), L> L_helper;
- typedef internal::unproxy_if<(R_level >= L_level), R> R_helper;
- typedef typename L_helper::ret L_ret;
- typedef typename R_helper::ret R_ret;
- };
-
- } // end of namespace mln::internal
-
-
-
namespace trait
{
@@ -168,7 +136,8 @@
template < template <class> class Op, typename P >
struct set_unary_< Op, mln::Proxy, P >
{
- typedef mln_trait_unary(Op, mln_subject(P)) ret;
+ typedef mlc_unqualif(mln_q_subject(P)) S;
+ typedef mln_trait_unary(Op, S) ret;
};
// Binary ops.
@@ -177,7 +146,7 @@
typename L, typename R >
struct set_binary_< Op, mln::Proxy, L, mln::Proxy, R >
{
- typedef mln::internal::unproxy_couple<L, R> helper;
+ typedef mln::internal::helper_unprox_binop<L, R> helper;
typedef mln_trait_binary(Op,
typename helper::L_ret,
typename helper::R_ret) ret;
@@ -187,14 +156,16 @@
typename P, typename O >
struct set_binary_< Op, mln::Proxy, P, mln::Object, O >
{
- typedef mln_trait_binary(Op, mln_subject(P), O) ret;
+ typedef mlc_unqualif(mln_q_subject(P)) S;
+ typedef mln_trait_binary(Op, S, O) ret;
};
template < template <class, class> class Op,
typename O, typename P >
struct set_binary_< Op, mln::Object, O, mln::Proxy, P >
{
- typedef mln_trait_binary(Op, O, mln_subject(P)) ret;
+ typedef mlc_unqualif(mln_q_subject(P)) S;
+ typedef mln_trait_binary(Op, O, S) ret;
};
} // end of namespace mln::trait
@@ -214,31 +185,50 @@
* "proxy".
*/
template <typename E>
- struct Proxy : public Object<E>
+ struct Proxy : Object<E>
{
typedef Proxy<void> category;
/*
enum { proxy_level };
- typedef subject;
typedef q_subject;
- q_subject unproxy() const;
-
- // FIXME:
- // return "const subject&"?
- // overload with not-const method?
- // add op subject() const?
+ q_subject subj_();
*/
+
protected:
Proxy();
};
+ // subject
+
+ template <typename T>
+ struct subject
+ {
+ typedef typename mln::internal::unproxy_rec_<T>::ret q_ret;
+ typedef mlc_unqualif(q_ret) ret;
+ };
+
+
+ // unproxy_rec
+
+ template <typename T>
+ typename mln::internal::unproxy_rec_<T>::ret
+ unproxy_rec(T& t);
+
+ template <typename T>
+ typename mln::internal::unproxy_rec_<const T>::ret
+ unproxy_rec(const T& t);
+
+
+ // operator <<
template <typename P>
std::ostream& operator<<(std::ostream& ostr, const Proxy<P>&
p);
+ // operators
+
mln_decl_unop_proxy(uplus, + );
mln_decl_unop_proxy(uminus, - );
mln_decl_unop_proxy(preinc, ++ );
@@ -265,127 +255,50 @@
- namespace internal
- {
+# ifndef MLN_INCLUDE_ONLY
- // External way of getting an address of an object from/through a
- // proxy. This is a recursive implementation since we can have a
- // proxy of proxy, etc.
- // Case 1: Not found so unproxy.
+ // Proxy
- template <typename T, typename P>
- void get_adr(const T *& ptr, const Proxy<P>& obj)
+ template <typename E>
+ inline
+ Proxy<E>::Proxy()
{
- get_adr(ptr, exact(obj).unproxy());
- }
+ enum { proxy_level = E::proxy_level }; // FIXME: Check that it is >= 0...
- template <typename T, typename P>
- void get_adr( T *& ptr, Proxy<P>& obj)
- {
- get_adr(ptr, exact(obj).unproxy());
+ typedef typename E::q_subject q_subject;
+
+ q_subject (E::*m_)() = & E::subj_;
+ m_ = 0;
}
- // Case 2: Found. (Note that T can also be a Proxy.)
- template <typename T>
- void get_adr(const T *& ptr, const Object<T>& obj)
- {
- ptr = & exact(obj);
- }
+ // unproxy_rec
template <typename T>
- void get_adr( T *& ptr, Object<T>& obj)
+ inline
+ typename mln::internal::unproxy_rec_<T>::ret
+ unproxy_rec(T& t)
{
- ptr = & exact(obj);
+ return mln::internal::unproxy_rec_<T>::on(t);
}
template <typename T>
- void get_adr( T *& ptr, T& obj)
- {
- ptr = & obj;
- }
-
- // Case 3: Fail to found!
-
- template <typename T, typename O>
- void get_adr(const T *& ptr, const Object<O>& obj)
- {
- ptr = 0;
- }
-
- template <typename T, typename O>
- void get_adr( T *& ptr, Object<O>& obj)
- {
- ptr = 0;
- }
-
-
- // A proxy should convert towards its subject. And, if we have a
- // proxy of proxy, it should also convert towards its subject of
- // subject, and so on. It leads to a recursive implementation
- // where conversions are automatically obtained through
- // inheritance.
- //
- // E is a Proxy type; Subject is its subject type.
-
- template <typename Subject, typename E> struct proxy_impl;
-
- template <typename Subject, typename E, bool rec = true>
- struct helper_proxy_impl : proxy_impl< mln_subject(Subject), E > // Rec.
- {
- enum { proxy_level = Subject::proxy_level + 1};
- };
-
- template <typename Subject, typename E>
- struct helper_proxy_impl< Subject, E, false > // Stop rec.
- {
- enum { proxy_level = 1 };
- };
-
- template <typename Subject, typename E>
- struct proxy_impl : helper_proxy_impl< Subject, E,
- mlc_is_a(Subject, Proxy)::value >
- {
- operator Subject() const
- {
- return mln::internal::force_exact<const E>(*this).unproxy();
-
- // Technical note:
- //
- // The code above seems more effective than the one below:
- // const Subject* adr;
- // get_adr(adr, mln::internal::force_exact<const E>(*this));
- // mln_postcondition(adr != 0);
- // return *adr;
- }
- };
-
-
- } // end of namespace mln::internal
-
-
-
-
-# ifndef MLN_INCLUDE_ONLY
-
- template <typename E>
inline
- Proxy<E>::Proxy()
+ typename mln::internal::unproxy_rec_<const T>::ret
+ unproxy_rec(const T& t)
{
- enum { proxy_level = E::proxy_level }; // FIXME: Check that it is >= 0...
+ return mln::internal::unproxy_rec_<const T>::on(t);
+ }
- typedef mln_subject(E) subject;
- typedef typename E::q_subject q_subject;
- q_subject (E::*m)() const = & E::unproxy;
- m = 0;
- }
+ // operator <<
template <typename P>
+ inline
std::ostream& operator<<(std::ostream& ostr, const Proxy<P>&
p)
{
- return ostr << exact(p).unproxy();
+ return ostr << unproxy_rec(p);
}
Index: mln/core/concept/box.hh
--- mln/core/concept/box.hh (revision 2153)
+++ mln/core/concept/box.hh (working copy)
@@ -63,6 +63,9 @@
*/
unsigned len(unsigned i) const;
+ // Box associated type.
+ typedef const E& q_box;
+
/*! \brief Give the bounding box of this site set.
*
* Return the bounding box of this site set, so that is itself.
@@ -79,7 +82,7 @@
*
* \warning This method is final for all box classes.
*/
- std::size_t nsites() const;
+ unsigned nsites() const;
protected:
Box();
@@ -154,18 +157,20 @@
template <typename E>
inline
- std::size_t
+ unsigned
Box<E>::nsites() const
{
- std::size_t count = 1;
- typedef mln_site(E) P; // helps g++-3.3.5
+ if (! exact(this)->is_valid())
+ return 0;
+ unsigned count = 1;
+ typedef mln_site(E) P; // Helps g++-3.3.5.
for (unsigned i = 0; i < P::dim; ++i)
count *= exact(this)->len(i);
return count;
}
- // operators
+ // Operators.
template <typename Bl, typename Br>
inline
Index: mln/core/concept/proxy.hxx
--- mln/core/concept/proxy.hxx (revision 0)
+++ mln/core/concept/proxy.hxx (revision 0)
@@ -0,0 +1,453 @@
+// Copyright (C) 2008 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 MLN_CORE_CONCEPT_PROXY_HXX
+# define MLN_CORE_CONCEPT_PROXY_HXX
+
+# include <mln/core/internal/force_exact.hh>
+# include <mln/metal/unqualif.hh>
+# include <mln/metal/is_a.hh>
+# include <mln/metal/if.hh>
+# include <mln/metal/is_const.hh>
+# include <mln/metal/const.hh>
+# include <mln/metal/unconst.hh>
+# include <mln/metal/is_not_ref.hh>
+# include <mln/metal/ref.hh>
+
+
+namespace mln
+{
+
+ // Fwd decls.
+ template <typename E> struct Proxy;
+
+
+ namespace internal
+ {
+
+
+ // helper_unprox_binop
+
+ template <bool b, typename P> struct helper_unprox_if;
+
+ template <typename P>
+ struct helper_unprox_if< true, P >
+ {
+ typedef mlc_unqualif(mln_q_subject(P)) ret;
+ static mlc_const(mln_q_subject(P)) on(const Proxy<P>& p);
+ };
+
+ template <typename P>
+ struct helper_unprox_if< false, P >
+ {
+ typedef P ret;
+ static const P& on(const Proxy<P>& p);
+ };
+
+ template <typename L, typename R>
+ struct helper_unprox_binop
+ {
+ enum { L_level = L::proxy_level,
+ R_level = R::proxy_level }; // To prevent a weird g++ warning.
+ typedef internal::helper_unprox_if<(L_level >= R_level), L> L_helper;
+ typedef internal::helper_unprox_if<(R_level >= L_level), R> R_helper;
+ typedef typename L_helper::ret L_ret;
+ typedef typename R_helper::ret R_ret;
+ };
+
+
+
+ template <typename T>
+ struct unproxy_rec_;
+
+ template <typename O, bool is_proxy>
+ struct helper_unproxy_rec;
+
+
+ // P is a proxy type.
+
+ template <typename P>
+ struct helper_unproxy_rec< P, true >
+ {
+ typedef mln_exact(P) P_;
+ typedef typename P_::HOT_actual_subject ret;
+ static ret on(P& p);
+ };
+
+ template <typename P>
+ struct helper_unproxy_rec< const P, true >
+ {
+ typedef mln_exact(P) P_;
+ typedef mlc_const(typename P_::HOT_actual_subject) ret;
+ static ret on(const P& p);
+ };
+
+ // O is *not* a proxy type.
+
+ template <typename O>
+ struct helper_unproxy_rec< const O, false >
+ {
+ typedef const mln_exact(mlc_unqualif(O))& ret;
+ static ret on(const O& obj);
+ };
+
+ template <typename O>
+ struct helper_unproxy_rec< O, false >
+ {
+ typedef mln_exact(mlc_unqualif(O))& ret;
+ static ret on(O& obj);
+ };
+
+
+ template <typename T>
+ struct unproxy_rec_
+ {
+ enum { is_proxy = mlc_is_a(T, Proxy)::value };
+ typedef helper_unproxy_rec<T, is_proxy> helper;
+ typedef typename helper::ret ret;
+ static ret on(T& t);
+ };
+
+
+
+
+ // External way of getting an address of an object from/through a
+ // proxy. This is a recursive implementation since we can have a
+ // proxy of proxy, etc.
+
+ // Case 1: Not found so unproxy_ (once).
+
+ template <typename T, typename P>
+ void get_adr(const T *& ptr, const Proxy<P>& p);
+
+ template <typename T, typename P>
+ void get_adr( T *& ptr, Proxy<P>& p);
+
+ // Case 2: Found. (Note that T can also be a Proxy.)
+
+ template <typename T>
+ void get_adr(const T *& ptr, const Object<T>& obj);
+
+ template <typename T>
+ void get_adr( T *& ptr, Object<T>& obj);
+
+ template <typename T>
+ void get_adr( T *& ptr, T& t);
+
+ // Case 3: Fail to found!
+
+ template <typename T, typename O>
+ void get_adr(const T *& ptr, const Object<O>&);
+
+ template <typename T, typename O>
+ void get_adr( T *& ptr, Object<O>&);
+
+
+
+ // Every proxied class should derive from subject_impl. The class
+ // below is provided to be specialized so that an effective
+ // implementation (with the interface of the proxied class) can
+ // equip proxy classes.
+
+ template <typename Subject, typename E>
+ struct subject_impl
+ {
+ };
+
+ template <typename S, typename E>
+ struct subject_impl< S&, E >; // Safety.
+
+
+
+
+ template <typename prox>
+ struct helper_subject_of
+ {
+ typedef mlc_unqualif(prox)::q_subject subj;
+ // We have the proxy type (prox) and its subject type (subj).
+ // Both can be qualified with 'const' and/or '&'. We have to
+ // propagate when possible the proper qualifications to the
+ // resulting subject type.
+
+ // The rules are:
+ // (1) the subject is constant if either prox or subj is const
+ // ---so we have to propagate the possible constness of
+ // prox;
+ typedef mlc_if(mlc_is_const(prox), mlc_const(subj), subj) temp;
+
+ // (2) the subject is a reference if both prox and subj are
+ // references---so we have to remove the possible & if prox
+ // is not a reference.
+ typedef mlc_if(mlc_is_not_ref(prox), mlc_unref(temp), temp) ret;
+
+ // +-------------+---------+-------------+-------------+----------------+
+ // | prox / subj | const S | S | const S& | S& |
+ // +-------------+---------+-------------+-------------+----------------+
+ // | const P | const S | const S (1) | const S (2) | const S (1,2) |
+ // | P | const S | S | const S (2) | S (2) |
+ // | const P& | const S | const S (1) | const S& | const S& (1)
|
+ // | P& | const S | S | const S& | S& (*)
|
+ // +-------------+---------+-------------+-------------+----------------+
+ };
+
+
+ template <typename S> struct helper_subject_impl { typedef const S
ret; };
+ template <typename S> struct helper_subject_impl<S&> { typedef
S ret; }; // (*)
+ template <typename S> struct helper_subject_impl<const S&> { typedef
const S ret; };
+ template <typename S> struct helper_subject_impl<const S> { typedef
const S ret; };
+
+ // FIXME: I don't know yet how to deal with these cases:
+ template <typename S> struct helper_subject_impl<S*>;
+ template <typename S> struct helper_subject_impl<S*const>;
+
+
+ // A proxy should convert towards its subject. And, if we have a
+ // proxy of proxy, it should also convert towards its subject of
+ // subject, and so on. It leads to a recursive implementation
+ // where conversions are automatically obtained through
+ // inheritance.
+ //
+ // E is a Proxy type; Subject is its subject type.
+
+ template <typename Subject, typename E> struct get_proxy_impl;
+
+ template <typename Subject, typename E, bool rec = true>
+ struct helper_get_proxy_impl : get_proxy_impl< typename
helper_subject_of<Subject>::ret,
+ E > // Rec.
+ {
+ private:
+ typedef mlc_unqualif(Subject) unq_subject_;
+ public:
+ enum { proxy_level = unq_subject_::proxy_level + 1};
+ };
+
+ template <typename Subject, typename E>
+ struct helper_get_proxy_impl< Subject, E, false > // Stop rec.
+ :
+ subject_impl< typename helper_subject_impl<Subject>::ret,
+ E >
+ {
+ enum { proxy_level = 1 };
+
+ // FIXME: HOT: test code below
+
+ typedef Subject HOT_actual_subject;
+
+ HOT_actual_subject get_subject();
+ mlc_const(HOT_actual_subject) get_subject() const;
+ };
+
+ template <typename Subject, typename E>
+ struct get_proxy_impl : helper_get_proxy_impl< Subject, E,
+ mlc_is_a(Subject, Proxy)::value >
+ {
+ operator mlc_unqualif(Subject) () const;
+ };
+
+ template <typename Subject, typename E>
+ struct proxy_impl : get_proxy_impl< Subject, E>
+ {
+ typedef Subject q_subject;
+
+ // HERE: NEW
+ q_subject unproxy_()
+ {
+ return mln::internal::force_exact<E>(*this).subj_();
+ }
+ mlc_const(q_subject) unproxy_() const
+ {
+ E& self_ = mln::internal::force_exact<E>(*this);
+ return self_.subj_();
+ }
+ };
+
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // helper_unprox_if
+
+ template <typename P>
+ inline
+ mlc_const(mln_q_subject(P))
+ helper_unprox_if< true, P >::on(const Proxy<P>& p)
+ {
+ return exact(p).unproxy_();
+ }
+
+ template <typename P>
+ inline
+ const P&
+ helper_unprox_if< false, P >::on(const Proxy<P>& p)
+ {
+ return exact(p);
+ }
+
+ template <typename P>
+ inline
+ mln_exact(P)::HOT_actual_subject
+ helper_unproxy_rec< P, true >::on(P& p)
+ {
+ return unproxy_rec(exact(p).unproxy_());
+ }
+
+ // helper_unprox_rec
+
+ template <typename P>
+ inline
+ mlc_const(mln_exact(P)::HOT_actual_subject)
+ helper_unproxy_rec< const P, true >::on(const P& p)
+ {
+ return unproxy_rec(exact(p).unproxy_());
+ }
+
+ template <typename O>
+ inline
+ mln_exact(mlc_unqualif(O))&
+ helper_unproxy_rec< O, false >::on(O& obj)
+ {
+ return exact(obj);
+ }
+
+ template <typename O>
+ inline
+ const mln_exact(mlc_unqualif(O))&
+ helper_unproxy_rec< const O, false >::on(const O& obj)
+ {
+ return exact(obj);
+ }
+
+ // unproxy_rec_
+
+ template <typename T>
+ inline
+ typename unproxy_rec_<T>::ret
+ unproxy_rec_<T>::on(T& t)
+ {
+ typedef typename unproxy_rec_<T>::helper helper;
+ return helper::on(t);
+ }
+
+
+ // helper_get_proxy_impl<..>::get_subject()
+
+ template <typename Subject, typename E>
+ inline
+ typename helper_get_proxy_impl< Subject, E, false >::HOT_actual_subject
+ helper_get_proxy_impl< Subject, E, false >::get_subject()
+ {
+ return unproxy_rec(mln::internal::force_exact<E>(*this));
+ }
+
+ template <typename Subject, typename E>
+ inline
+ typename mln::metal::const_< typename helper_get_proxy_impl< Subject, E, false
>::HOT_actual_subject >::ret
+ helper_get_proxy_impl< Subject, E, false >::get_subject() const
+ {
+ return unproxy_rec(mln::internal::force_exact<const E>(*this));
+ }
+
+
+ // get_proxy_impl<..>::operator Subject()
+
+ template <typename Subject, typename E>
+ inline
+ get_proxy_impl<Subject, E>::operator mlc_unqualif(Subject) () const
+ {
+ return mln::internal::force_exact<const E>(*this).unproxy_();
+
+ // Technical note:
+ //
+ // The code above seems more effective than the one below:
+ // const Subject* adr;
+ // get_adr(adr, mln::internal::force_exact<const E>(*this));
+ // mln_postcondition(adr != 0);
+ // return *adr;
+ }
+
+
+ // get_adr
+
+ template <typename T, typename P>
+ inline
+ void get_adr(const T *& ptr, const Proxy<P>& p)
+ {
+ get_adr(ptr, exact(p).unproxy_());
+ }
+
+ template <typename T, typename P>
+ inline
+ void get_adr( T *& ptr, Proxy<P>& p)
+ {
+ get_adr(ptr, exact(p).unproxy_());
+ }
+
+ template <typename T>
+ inline
+ void get_adr(const T *& ptr, const Object<T>& obj)
+ {
+ ptr = & exact(obj);
+ }
+
+ template <typename T>
+ inline
+ void get_adr( T *& ptr, Object<T>& obj)
+ {
+ ptr = & exact(obj);
+ }
+
+ template <typename T>
+ inline
+ void get_adr( T *& ptr, T& t)
+ {
+ ptr = & t;
+ }
+
+ template <typename T, typename O>
+ inline
+ void get_adr(const T *& ptr, const Object<O>&)
+ {
+ ptr = 0;
+ }
+
+ template <typename T, typename O>
+ inline
+ void get_adr( T *& ptr, Object<O>&)
+ {
+ ptr = 0;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::internal
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_CONCEPT_PROXY_HXX
Index: mln/core/concept/site_proxy.hh
--- mln/core/concept/site_proxy.hh (revision 2153)
+++ mln/core/concept/site_proxy.hh (working copy)
@@ -46,98 +46,6 @@
template <typename E> struct Site_Proxy;
-
- namespace internal
- {
-
- // Every "Site_Proxy" class should derive from site_impl. The
- // couple of classes below are provided to be specialized so that
- // an effective implementation (with the interface of the
- // targetted site) can equip site proxy classes.
-
- template <typename Site, typename E>
- struct site_const_impl
- {
- // Default is none.
- };
-
- template <typename Site, typename E>
- struct site_mutable_impl
- {
- // Default is none.
- };
-
- template <bool is_mutable, typename Site, typename E>
- struct site_impl; // Is a selector w.r.t. to mutability.
-
- template <typename Site, typename E>
- struct site_impl</* is_mutable = */ true, Site, E> : site_mutable_impl<Site,
E>
- {
- };
-
- template <typename Site, typename E>
- struct site_impl</* is_mutable = */ false, Site, E> : site_const_impl<Site,
E>
- {
- };
-
-
-
- // Fwd decl.
- template <typename P> struct site_from;
-
- namespace deep
- {
-
- template <typename P, bool is_site_proxy = true>
- struct helper_site_from
- {
- typedef typename P::subject S;
- // Recursion.
- typedef typename mln::internal::site_from<S>::ret ret;
- // Routine.
- static const ret& on(const P& p)
- {
- return p.to_site();
- }
- };
-
- template <typename O>
- struct helper_site_from<O, /* is_site_proxy = */ false>
- {
- // Stop Recursion.
- typedef O ret;
- // Routine.
- static const ret& on(const O& obj)
- {
- return obj;
- }
- };
-
- } // end of namespace internal::deep
-
-
- /// Meta-routine to get the site type from a type \p P that can be
- /// either a site proxy or a site.
- template <typename P>
- struct site_from
- {
- typedef mln_exact(P) E;
- enum { is_site_proxy = mlc_is_a(E, Site_Proxy)::value };
- typedef typename deep::helper_site_from< E, is_site_proxy >::ret ret;
- };
-
-
- /// Access to site reference.
- template <typename O>
- const typename site_from<O>::ret&
- to_site(const O& obj);
-
-
- } // end of namespace internal
-
-
-
-
/// Site_Proxy category flag type.
template <>
struct Site_Proxy<void>
@@ -161,9 +69,6 @@
const site& to_site() const;
operator site() const;
-
- FIXME: Add if possible a mutable version of to_site().
- FIXME: Or (?) just remove this method (!)
*/
protected:
@@ -185,22 +90,6 @@
m2 = 0;
}
- namespace internal
- {
-
- // Access to site reference.
-
- template <typename O>
- const typename site_from<O>::ret&
- to_site(const O& obj)
- {
- typedef mln_exact(O) E;
- enum { is_site_proxy = mlc_is_a(E, Site_Proxy)::value };
- return deep::helper_site_from<E, is_site_proxy>::on(exact(obj));
- }
-
- } // end of namespace mln::internal
-
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln
Index: mln/core/concept/pseudo_site.hh
--- mln/core/concept/pseudo_site.hh (revision 2153)
+++ mln/core/concept/pseudo_site.hh (working copy)
@@ -64,11 +64,12 @@
{
typedef Pseudo_Site<void> category;
- // When a pseudo site features this associated type...
- // typedef target_t;
+ // typedef target;
- // ...then it also features the method:
- // const target_t* target();
+ // void change_target(const target& new_target);
+ // const target* target_() const; // Hook to the target.
+
+ bool has_target() const;
protected:
Pseudo_Site();
@@ -91,11 +92,27 @@
# ifndef MLN_INCLUDE_ONLY
template <typename E>
+ inline
Pseudo_Site<E>::Pseudo_Site()
{
- // FIXME
+ typedef mln_target(E) target;
+
+ void (E::*m1)(const target&) = & E::change_target;
+ m1 = 0;
+ const target* (E::*m2)() const = & E::target_;
+ m2 = 0;
+ }
+
+ template <typename E>
+ inline
+ bool
+ Pseudo_Site<E>::has_target() const
+ {
+ return exact(this)->target_() != 0;
}
+
+
namespace if_possible
{
@@ -109,9 +126,9 @@
{
template <typename P>
- void change_target(Pseudo_Site<P>& p, const typename P::target_t&
new_target) const
+ void change_target(Pseudo_Site<P>& p, const mln_target(P)& new_target)
const
{
- exact(p).target() = & new_target;
+ exact(p).change_target(new_target);
}
template <typename O, typename D>
@@ -135,33 +152,11 @@
} // namespace mln::if_possible::internal
-
- // FIXME: Was:
-
-// template <typename P>
-// void change_target(Pseudo_Site<P>& p, const typename P::target_t&
new_target)
-// {
-// exact(p).target() = & new_target;
-// }
-
-// template <typename O, typename D>
-// void change_target(Object<O>&, const D&)
-// {
-// // No-op.
-// }
-
-// template <typename P>
-// void change_target(P& p, const typename P::target_t& new_target)
-// {
-// exact(p).target() = & new_target;
-// }
-
-
template <typename O, typename D>
void change_target(O& o, const D& d)
{
enum { is_object = mlc_is_a(O, Object)::value };
- mln::if_possible::internal::helper< is_object >().change_target(o, d);
+ mln::if_possible::internal::helper< is_object >().change_target(exact(o),
d);
}
} // end of namespace mln::if_possible
Index: mln/core/concept/gdpoint.hh
--- mln/core/concept/gdpoint.hh (revision 2153)
+++ mln/core/concept/gdpoint.hh (working copy)
@@ -31,6 +31,8 @@
/*! \file mln/core/concept/delta_point_site.hh
*
* \brief Definition of the concept of mln::Gdpoint.
+ *
+ * \todo Add support for (s * dp)...
*/
# include <mln/core/concept/object.hh>
Index: mln/core/concept/site_set.hh
--- mln/core/concept/site_set.hh (revision 2153)
+++ mln/core/concept/site_set.hh (working copy)
@@ -33,8 +33,6 @@
* \brief Definition of the concept of mln::Site_Set.
*
* \todo Rewrite and move out the ops.
- *
- * \todo Check optional methods s.a. nsites and bbox.
*/
# include <mln/core/concept/site_iterator.hh>
@@ -78,16 +76,20 @@
typedef bkd_piter;
bool has(const psite& p) const;
- */
+ bool is_valid() const;
- template <typename S>
- E& insert_all(const Site_Set<S>& other);
+ std::size_t memory_size() const;
+ */
protected:
Site_Set();
};
+ template <typename Sl, typename Sr>
+ Sl& operator+=(Site_Set<Sl>& lhs, const Site_Set<Sr>& rhs);
+
+
/*! \brief Equality test between site sets \p lhs and \p rhs.
*
* \param[in] lhs A site set.
@@ -142,6 +144,88 @@
# ifndef MLN_INCLUDE_ONLY
+ namespace internal
+ {
+
+ // nsites: known or unknown.
+
+ template <typename trait_nsites, typename E>
+ struct site_set_nsites_check
+ {
+ static void run() { /* No requirement. */ }
+ };
+
+ template <typename E>
+ struct site_set_nsites_check< mln::trait::site_set::nsites::known, E >
+ {
+ static void run()
+ {
+ unsigned (E::*m)() const = & E::nsites;
+ m = 0;
+ }
+ };
+
+ // bbox: unknown, lazy, or straight.
+
+ template <typename trait_bbox, typename E>
+ struct site_set_bbox_check
+ {
+ static void run()
+ {
+ typedef typename E::q_box q_box;
+ q_box (E::*m)() const = & E::bbox;
+ m = 0;
+ }
+ };
+
+ template <typename E>
+ struct site_set_bbox_check< mln::trait::site_set::bbox::unknown, E >
+ {
+ static void run() { /* No requirement. */ }
+ };
+
+ // contents: fixed, growing, or free.
+
+ template <typename trait_contents, typename E>
+ struct site_set_contents_check;
+
+ template <typename E>
+ struct site_set_contents_check< mln::trait::site_set::contents::fixed, E >
+ {
+ static void run() { /* No requirement. */ }
+ };
+
+ template <typename E>
+ struct site_set_contents_check< mln::trait::site_set::contents::growing, E >
+ {
+ static void run()
+ {
+ typedef typename E::i_element i_element;
+ mlc_equal(mlc_unqualif(i_element), i_element)::check();
+ void (E::*m)(const i_element&) = & E::insert;
+ m = 0;
+ }
+ };
+
+ template <typename E>
+ struct site_set_contents_check< mln::trait::site_set::contents::free, E >
+ {
+ static void run()
+ {
+ typedef typename E::i_element i_element;
+ mlc_equal(mlc_unqualif(i_element), i_element)::check();
+ void (E::*m1)(const i_element&) = & E::insert;
+ m1 = 0;
+ typedef typename E::r_element r_element;
+ mlc_equal(mlc_unqualif(r_element), r_element)::check();
+ void (E::*m2)(const r_element&) = & E::remove;
+ m2 = 0;
+ }
+ };
+
+ } // end of namespace mln::internal
+
+
// fwd decl
template <typename P> struct box_;
@@ -160,29 +244,43 @@
// Check associated types.
typedef mln_site(E) site;
typedef mln_psite(E) psite;
+ typedef mln_piter(E) piter;
typedef mln_fwd_piter(E) fwd_piter;
typedef mln_bkd_piter(E) bkd_piter;
// Check methods.
- bool (E::*m)(const psite& p) const = & E::has;
- m = 0;
+ bool (E::*m1)(const psite& p) const = & E::has;
+ m1 = 0;
+ bool (E::*m2)() const = & E::is_valid;
+ m2 = 0;
+ std::size_t (E::*m3)() const = & E::memory_size;
+ m3 = 0;
+
+ // Check methods depending upon properties.
+ internal::site_set_nsites_check < mln_trait_site_set_nsites(E), E >::run();
+ internal::site_set_bbox_check < mln_trait_site_set_bbox(E), E >::run();
+ internal::site_set_contents_check< mln_trait_site_set_contents(E), E >::run();
}
- template <typename E>
- template <typename S>
+
+ // Operators.
+
+
+ template <typename Sl, typename Sr>
inline
- E& Site_Set<E>::insert_all(const Site_Set<S>& other)
+ Sl& operator+=(Site_Set<Sl>& lhs_, const Site_Set<Sr>& rhs)
{
- E& self = exact(*this);
- mln_fwd_piter(S) p(exact(other));
+ mlc_is( mln_trait_site_set_contents(Sl),
+ mln::trait::site_set::contents::dynamic )::check();
+ mlc_equal(mln_site(Sr), typename Sl::i_element)::check();
+ Sl& lhs = exact(lhs_);
+ mln_fwd_piter(Sr) p(exact(rhs));
for_all(p)
- self.insert(p);
- return self;
+ lhs.insert(p);
+ return lhs;
}
- // operators
-
template <typename Sl, typename Sr>
inline
Index: mln/core/concept/accumulator.hh
--- mln/core/concept/accumulator.hh (revision 2153)
+++ mln/core/concept/accumulator.hh (working copy)
@@ -51,6 +51,7 @@
};
+
/*! \brief Base class for implementation of accumulators.
*
* The parameter \a E is the exact type.
Index: mln/core/sparse_image.hh
--- mln/core/sparse_image.hh (revision 2153)
+++ mln/core/sparse_image.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -31,13 +31,15 @@
/*! \file mln/core/sparse_image.hh
*
* \brief Definition of an image with sparse encoding.
+ *
+ * \todo Update p_run_set<P> to p_set_of< p_run<P> >.
*/
-# include <mln/core/internal/run_image.hh>
+# include <vector>
+# include <mln/core/internal/image_primary.hh>
# include <mln/core/p_runs.hh>
-# include <mln/core/runs_psite.hh>
# include <mln/value/set.hh>
-# include <vector>
+
namespace mln
{
@@ -51,21 +53,15 @@
/// \internal Data structure for \c mln::sparse_image<P,T>.
template <typename P, typename T>
- struct data_< sparse_image<P,T> >
+ struct data< sparse_image<P,T> >
{
- data_();
-
- /// Image values.
- std::vector< std::vector<T> > values_;
+ data();
- /// domain of the image
- p_runs_<P> domain_;
+ /// Domain.
+ p_run_set<P> domain_;
- /// Return the size of the data in memory.
- unsigned size_mem() const;
-
- /// Finalize the domain (internal use).
- void finalize();
+ /// Image.
+ std::vector< std::vector<T> > values_;
};
} // end of namespace mln::internal
@@ -77,23 +73,31 @@
template <typename P, typename T>
struct image_< sparse_image<P,T> > : default_image_< T,
sparse_image<P,T> >
{
+ // misc
typedef trait::image::category::primary category;
-
- typedef trait::image::access::browsing access;
- // FIXME: Put the right dimension.
- typedef trait::image::space::two_d space;
+ typedef trait::image::speed::fast speed;
typedef trait::image::size::regular size;
- typedef trait::image::support::aligned support;
- typedef trait::image::border::none border;
- typedef trait::image::data::linear data;
- typedef trait::image::io::read_only io;
- typedef trait::image::speed::slow speed;
+ // value
+ typedef trait::image::value_access::direct value_access;
+ typedef trait::image::value_storage::piecewise value_storage;
+ typedef trait::image::value_browsing::value_wise value_browsing;
+ typedef trait::image::value_io::read_write value_io;
+
+ // site / domain
+ typedef trait::image::localization::basic_grid localization;
+ typedef trait::image::dimension::two_d dimension; // FIXME
+
+ // extended domain
+ typedef trait::image::ext_domain::none ext_domain;
+ typedef trait::image::ext_value::irrelevant ext_value;
+ typedef trait::image::ext_io::irrelevant ext_io;
};
} // end of namespace mln::trait
+
/*! \brief RLE image with different value in runs.
*
*
@@ -102,88 +106,97 @@
* This image is not point wise accessible.
*/
template <typename P, typename T>
- class sparse_image : public internal::run_image_< T, P, sparse_image<P, T>
>
+ class sparse_image
+ : public internal::image_primary< p_run_set<P>,
+ sparse_image<P,T> >
{
+ typedef sparse_image<P,T> self_;
+ typedef internal::image_primary<p_run_set<P>, self_> super_;
public:
+
+ /// Value associated type.
typedef T value;
+
+ /// Return type of read-only access.
+ typedef const T& rvalue;
+
+ /// Return type of read-write access.
typedef T& lvalue;
- typedef const T rvalue;
- typedef runs_psite<P> psite;
+
+
+ /// Value_Set associated type.
typedef mln::value::set<T> vset;
- typedef p_runs_<P> pset;
/// Skeleton.
typedef sparse_image< tag::psite_<P>, tag::value_<T> > skeleton;
+ /// Constructor without argument.
sparse_image();
+ /// Constructor from a set of runs.
+ sparse_image(const p_run_set<P>& s);
+
+
/// Add a new range to the image.
- void insert(const p_run<P>& pr, const std::vector<T>& value);
+ void insert(const p_run<P>& r, const std::vector<T>& vals);
+
+
+ typedef typename super_::psite psite;
+
+ /// Test if \p p is valid.
+ bool has(const psite& p) const;
/// Read-only access to the image value located at point \p p.
- rvalue operator() (const runs_psite<P>& site) const;
+ rvalue operator()(const psite& p) const;
/// Read-write access to the image value located at point \p p.
- lvalue operator() (const runs_psite<P>& site);
+ lvalue operator()(const psite& p);
- /// Test if this image has been initialized.
- bool has_data() const;
/// Give the set of values of the image.
const vset& values() const;
- /// Give the definition domain.
- const pset& domain() const;
+ /// Give the definition domain.
+ const p_run_set<P>& domain() const;
};
+
# ifndef MLN_INCLUDE_ONLY
namespace internal
{
- // internal::data_< sparse_image<I,S> >
+ // internal::data< sparse_image<I,S> >
template <typename P, typename T>
inline
- data_< sparse_image<P,T> >::data_()
+ data< sparse_image<P,T> >::data()
{
}
- template <typename P, typename T>
- inline
- unsigned
- data_< sparse_image<P,T> >::size_mem() const
- {
- return sizeof(T) * domain_.npoints() + domain_.size_mem();
- }
-
- template <typename P, typename T>
- inline
- void
- data_< sparse_image<P,T> >::finalize()
- {
- domain_.finalize();
- }
-
} // end of namespace mln::internal
+
template <typename P, typename T>
inline
sparse_image<P, T>::sparse_image()
{
- this->data_ = new internal::data_< sparse_image<P,T> >();
}
template <typename P, typename T>
inline
- bool
- sparse_image<P, T>::has_data() const
+ sparse_image<P,T>::sparse_image(const p_run_set<P>& s)
{
- return this->data_->values_.size() != 0;
+ this->data_ = new internal::data< sparse_image<P,T> >();
+ this->data_->domain_ = s;
+ const unsigned nr = s.nruns();
+ this->data_->values_.resize(nr);
+ for (unsigned r = 0; r < nr; ++r)
+ this->data_->values_[r].resize(s.run(r).nsites());
}
template <typename P, typename T>
@@ -197,40 +210,48 @@
template <typename P, typename T>
inline
void
- sparse_image<P, T>::insert(const p_run<P>& pr, const
std::vector<T>& value)
+ sparse_image<P,T>::insert(const p_run<P>& r, const
std::vector<T>& vals)
{
+ mln_precondition(r.nsites() == vals.size());
if (!this->has_data())
- this->data_ = new internal::data_< sparse_image<P,T> >();
- mln_assertion(this->data_->values_.size() == 0 ||
- pr.first() > this->data_->domain_[this->data_->domain_.nruns() -
1].first());
- this->data_->domain_.insert(pr);
- this->data_->values_.push_back(value);
+ this->data_ = new internal::data< sparse_image<P,T> >();
+ this->data_->domain_.insert(r);
+ this->data_->values_.push_back(vals);
+ }
+
+ template <typename P, typename T>
+ inline
+ bool
+ sparse_image<P,T>::has(const psite& p) const
+ {
+ mln_precondition(this->has_data());
+ return this->data_->domain_.has(p);
}
template <typename P, typename T>
inline
- typename sparse_image<P, T>::rvalue
- sparse_image<P, T>::operator() (const runs_psite<P>& site)
- const
+ const T&
+ sparse_image<P,T>::operator()(const psite& p) const
{
- mln_precondition(this->has(site));
- return this->data_->values_[site.p_of_run()][site.p_in_run()];
+ mln_precondition(this->has(p));
+ return this->data_->values_[p.index()][p.p().index()];
}
template <typename P, typename T>
inline
- typename sparse_image<P, T>::lvalue
- sparse_image<P, T>::operator() (const runs_psite<P>& site)
+ T&
+ sparse_image<P,T>::operator()(const psite& p)
{
- mln_precondition(this->has(site));
- return this->data_->values_[site.p_of_run()][site.p_in_run()];
+ mln_precondition(this->has(p));
+ return this->data_->values_[p.index()][p.p().index()];
}
template <typename P, typename T>
inline
- const typename sparse_image<P, T>::pset&
+ const p_run_set<P>&
sparse_image<P, T>::domain() const
{
+ mln_precondition(this->has_data());
return this->data_->domain_;
}
Index: mln/core/obsolete_p_vaccess.hh
--- mln/core/obsolete_p_vaccess.hh (revision 0)
+++ mln/core/obsolete_p_vaccess.hh (revision 0)
@@ -0,0 +1,803 @@
+// Copyright (C) 2007, 2008 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 MLN_CORE_P_VACCESS_HH
+# define MLN_CORE_P_VACCESS_HH
+
+/*! \file mln/core/p_vaccess.hh
+ *
+ * \todo Factor double-iterators into a class.
+ */
+
+# include <utility>
+# include <mln/core/internal/site_set_base.hh>
+# include <mln/core/internal/pseudo_site_base.hh>
+# include <mln/accu/bbox.hh>
+
+
+
+namespace mln
+{
+
+ // Forward declarations.
+ template <typename Sv, typename Sp> class p_vaccess;
+ template <typename Sv, typename Sp> class p_vaccess_psite;
+ template <typename Sv, typename Sp> class p_vaccess_fwd_piter;
+ template <typename Sv, typename Sp> class p_vaccess_bkd_piter;
+
+
+ namespace trait
+ {
+
+ template <typename Sv, typename Sp>
+ struct site_set_< p_vaccess<Sv,Sp> >
+ {
+ typedef mln_trait_site_set_nsites(Sp) nsites;
+ typedef mln_trait_site_set_bbox(Sp) bbox;
+ typedef trait::site_set::contents::fixed contents;
+ typedef trait::site_set::arity::multiple arity;
+ };
+
+ } // end of namespace trait
+
+
+
+ namespace internal
+ {
+
+ // For .nsites()
+
+ template <typename trait_nsites, typename Sp>
+ struct p_vaccess_impl__nsites
+ {
+ protected:
+ template <typename T>
+ void update_nsites_(const T&); // No-op.
+ };
+
+ template <typename Sp>
+ struct p_vaccess_impl__nsites< trait::site_set::nsites::known, Sp>
+ {
+ p_vaccess_impl__nsites();
+ unsigned nsites() const;
+ protected:
+ void update_nsites_(const mln_site(Sp)& p);
+ template <typename S>
+ void update_nsites_(const Site_Set<S>& s);
+ unsigned nsites_;
+ };
+
+ // For .bbox()
+
+ template <typename trait_bbox, typename Sp>
+ struct p_vaccess_impl__bbox
+ {
+ typedef const mln::box<mln_site(Sp)>& q_box;
+ q_box bbox() const;
+
+ protected:
+ void update_bbox_(const mln_site(Sp)& p);
+ template <typename S>
+ void update_bbox_(const Site_Set<S>& s);
+
+ accu::bbox<mln_site(Sp)> bb_;
+ };
+
+ template <typename Sp>
+ struct p_vaccess_impl__bbox< trait::site_set::nsites::unknown, Sp >
+ {
+ protected:
+ template <typename T>
+ void update_bbox_(const T&); // No-op.
+ };
+
+ // Facade.
+
+ template <typename Sp>
+ struct p_vaccess_impl
+ : p_vaccess_impl__nsites< mln_trait_site_set_nsites(Sp), Sp>,
+ p_vaccess_impl__bbox < mln_trait_site_set_bbox(Sp), Sp>
+ {
+ };
+
+ } // end of namespace mln::internal
+
+
+
+ /*! \brief FIXME
+ */
+ template <typename Sv, typename Sp>
+ class p_vaccess : public internal::site_set_base_< mln_site(Sp),
+ p_vaccess<Sv,Sp> >,
+ public internal::p_vaccess_impl< Sp >
+ {
+ public:
+
+ /// Value associated type.
+ typedef mln_value(Sv) value;
+
+ /// Psite associated type.
+ typedef p_vaccess_psite<Sv,Sp> psite;
+
+ /// Site_Iterator associated type.
+ typedef p_vaccess_fwd_piter<Sv,Sp> piter;
+
+ /// Forward Site_Iterator associated type.
+ typedef p_vaccess_fwd_piter<Sv,Sp> fwd_piter;
+
+ /// Backward Site_Iterator associated type.
+ typedef p_vaccess_bkd_piter<Sv,Sp> bkd_piter;
+
+
+ /// Constructor.
+ p_vaccess();
+ p_vaccess(const Sv& vset);
+
+
+ /// Test if \p p belongs to this site set.
+ bool has(const psite& p) const;
+
+ /// Test if the couple (value \p v, psite \p p) belongs to this
+ /// site set.
+ bool has(const value& v, const mln_psite(Sp)& p) const;
+
+ /// Test if this site set is valid.
+ bool is_valid() const;
+
+
+ /// Element associated type.
+ typedef mln_element(Sp) element;
+
+ /// Insertion element associated type.
+ typedef std::pair<value, element> i_element;
+
+ /// Insert a pair (value \p v, element \p e).
+ void insert(const i_element& v_e);
+
+ /// Insert \p e at value \p v.
+ void insert(const value& v, const element& e);
+
+
+ /// Return the site set at value \p v.
+ const Sp& operator()(const value& v) const;
+
+ /// Return the size of this site set in memory.
+ std::size_t memory_size() const;
+
+ const Sv& values() const
+ {
+ return vs_;
+ }
+
+ const Sv& set_1_() const
+ {
+ return vs_;
+ }
+
+ const Sp& set_2_(const value& v) const
+ {
+ return ps_[vs_.index_of(v)];
+ }
+
+
+ protected:
+
+ Sv vs_;
+ std::vector<Sp> ps_;
+ };
+
+
+
+ // p_vaccess_psite<Sv,Sp>
+
+ template <typename Sv, typename Sp>
+ class p_vaccess_psite : public internal::pseudo_site_base_< const
mln_psite(Sp)&,
+ p_vaccess_psite<Sv,Sp> >
+ {
+ public:
+
+ typedef mln_value(Sv) value;
+
+ p_vaccess_psite();
+
+ // Target associated type.
+ typedef p_vaccess<Sv,Sp> target;
+
+ const p_vaccess<Sv,Sp>* target_() const;
+
+ void change_target(const target& newtarget);
+
+ bool is_valid() const;
+
+ void change_v(const value& v);
+
+ void change_p(const mln_psite(Sp)& p);
+
+ void change_vp(const value& v, const mln_psite(Sp)& p);
+
+ // As a Proxy:
+ const mln_psite(Sp)& subj_();
+
+ const mln_value(Sv)& value_() const;
+ const mln_psite(Sp)& psite_() const;
+
+ private:
+
+ const target* s_;
+ value v_;
+ mutable mln_psite(Sp) p_;
+ };
+
+
+
+
+ /// Forward iterator.
+
+ template <typename Sv, typename Sp>
+ class p_vaccess_fwd_piter
+ :
+ public internal::site_set_iterator_base< p_vaccess<Sv,Sp>,
+ p_vaccess_fwd_piter<Sv,Sp> >
+ {
+ typedef p_vaccess_fwd_piter<Sv,Sp> self;
+ typedef internal::site_set_iterator_base<p_vaccess<Sv,Sp>, self> super;
+ public:
+
+ /// Constructor with no argument.
+ p_vaccess_fwd_piter();
+
+ /// Constructor.
+ p_vaccess_fwd_piter(const p_vaccess<Sv,Sp>& s);
+
+ /// Test if the iterator is valid.
+ bool is_valid_() const;
+
+ /// Invalidate the iterator.
+ void invalidate_();
+
+ /// Start an iteration.
+ void start_();
+
+ /// Go to the next point.
+ void next_();
+
+ mln_value(Sv) value() const;
+
+ protected:
+ using super::p_;
+ using super::s_;
+
+ private:
+ mln_fwd_viter(Sv) vi_;
+ mln_fwd_piter(Sp) pi_;
+
+ void progress_();
+ };
+
+
+
+
+
+ /// Backward iterator.
+
+ template <typename Sv, typename Sp>
+ class p_vaccess_bkd_piter
+ :
+ public internal::site_set_iterator_base< p_vaccess<Sv,Sp>,
+ p_vaccess_bkd_piter<Sv,Sp> >
+ {
+ typedef p_vaccess_bkd_piter<Sv,Sp> self;
+ typedef internal::site_set_iterator_base<p_vaccess<Sv,Sp>, self> super;
+ public:
+
+ /// Constructor with no argument.
+ p_vaccess_bkd_piter();
+
+ /// Constructor.
+ p_vaccess_bkd_piter(const p_vaccess<Sv,Sp>& s);
+
+ /// Test if the iterator is valid.
+ bool is_valid_() const;
+
+ /// Invalidate the iterator.
+ void invalidate_();
+
+ /// Start an iteration.
+ void start_();
+
+ /// Go to the next point.
+ void next_();
+
+ mln_value(Sv) value() const;
+
+ protected:
+ using super::p_;
+ using super::s_;
+
+ private:
+ mln_bkd_viter(Sv) vi_;
+ mln_bkd_piter(Sp) pi_;
+
+ void progress_();
+ };
+
+
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // p_vaccess<Sv,Sp>
+
+ template <typename Sv, typename Sp>
+ inline
+ p_vaccess<Sv,Sp>::p_vaccess()
+ : vs_(),
+ ps_(vs_.nvalues())
+ {
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ p_vaccess<Sv,Sp>::p_vaccess(const Sv& vset)
+ : vs_(vset),
+ ps_(vs_.nvalues())
+ {
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ bool
+ p_vaccess<Sv,Sp>::has(const psite& p) const
+ {
+ return has(p.value_(), p.psite_());
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ bool
+ p_vaccess<Sv,Sp>::has(const value& v, const mln_psite(Sp)& p) const
+ {
+ return ps_[vs_.index_of(v)].has(p);
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ bool
+ p_vaccess<Sv,Sp>::is_valid() const
+ {
+ // FIXME
+ return true;
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ void
+ p_vaccess<Sv,Sp>::insert(const value& v, const element& e)
+ {
+ ps_[vs_.index_of(v)].insert(e);
+ this->update_nsites_(e);
+ this->update_bbox_(e);
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ void
+ p_vaccess<Sv,Sp>::insert(const i_element& v_e)
+ {
+ insert(v_e.first, v_e.second);
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ const Sp&
+ p_vaccess<Sv,Sp>::operator()(const value& v) const
+ {
+ return ps_[vs_.index_of(v)];
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ std::size_t
+ p_vaccess<Sv,Sp>::memory_size() const
+ {
+ std::size_t mem = 0;
+ for (unsigned i = 0; i < ps_.size(); ++i)
+ mem += ps_[i].memory_size();
+ return sizeof(*this) + mem;
+ }
+
+
+ namespace internal
+ {
+
+ // p_vaccess_impl__nsites
+
+ template <typename trait_nsites, typename Sp>
+ template <typename T>
+ inline
+ void
+ p_vaccess_impl__nsites<trait_nsites, Sp>::update_nsites_(const T&)
+ {
+ // No-op.
+ }
+
+ template <typename Sp>
+ inline
+ p_vaccess_impl__nsites<trait::site_set::nsites::known,
Sp>::p_vaccess_impl__nsites()
+ : nsites_(0)
+ {
+ }
+
+ template <typename Sp>
+ inline
+ unsigned
+ p_vaccess_impl__nsites<trait::site_set::nsites::known, Sp>::nsites() const
+ {
+ return nsites_;
+ }
+
+ template <typename Sp>
+ inline
+ void
+ p_vaccess_impl__nsites<trait::site_set::nsites::known,
Sp>::update_nsites_(const mln_site(Sp)&)
+ {
+ ++nsites_;
+ }
+
+ template <typename Sp>
+ template <typename S>
+ inline
+ void
+ p_vaccess_impl__nsites<trait::site_set::nsites::known,
Sp>::update_nsites_(const Site_Set<S>& s)
+ {
+ nsites_ += exact(s).nsites();
+ }
+
+ // p_vaccess_impl__bbox
+
+ template <typename trait_bbox, typename Sp>
+ inline
+ typename p_vaccess_impl__bbox<trait_bbox, Sp>::q_box
+ p_vaccess_impl__bbox<trait_bbox, Sp>::bbox() const
+ {
+ return bb_.to_result();
+ }
+
+ template <typename trait_bbox, typename Sp>
+ inline
+ void
+ p_vaccess_impl__bbox<trait_bbox, Sp>::update_bbox_(const mln_site(Sp)& p)
+ {
+ bb_.take(p);
+ }
+
+ template <typename trait_bbox, typename Sp>
+ template <typename S>
+ inline
+ void
+ p_vaccess_impl__bbox<trait_bbox, Sp>::update_bbox_(const Site_Set<S>&
s)
+ {
+ bb_.take(exact(s).bbox());
+ }
+
+ template <typename Sp>
+ template <typename T>
+ inline
+ void
+ p_vaccess_impl__bbox< trait::site_set::nsites::unknown, Sp
>::update_bbox_(const T&)
+ {
+ // No-op.
+ }
+
+ } // end of namespace mln::internal
+
+
+
+ // p_vaccess_psite<Sv,Sp>
+
+ template <typename Sv, typename Sp>
+ inline
+ p_vaccess_psite<Sv,Sp>::p_vaccess_psite()
+ {
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ const mln_psite(Sp)&
+ p_vaccess_psite<Sv,Sp>::subj_()
+ {
+ return p_;
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ const p_vaccess<Sv,Sp>*
+ p_vaccess_psite<Sv,Sp>::target_() const
+ {
+ return s_;
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ void
+ p_vaccess_psite<Sv,Sp>::change_target(const target& newtarget)
+ {
+ s_ = & newtarget;
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ bool
+ p_vaccess_psite<Sv,Sp>::is_valid() const
+ {
+ return s_ != 0 && s_->has(v_, p_);
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ void
+ p_vaccess_psite<Sv,Sp>::change_v(const value& v)
+ {
+ v_ = v;
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ void
+ p_vaccess_psite<Sv,Sp>::change_p(const mln_psite(Sp)& p)
+ {
+ p_ = p;
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ void
+ p_vaccess_psite<Sv,Sp>::change_vp(const value& v, const mln_psite(Sp)&
p)
+ {
+ change_v(v);
+ change_p(p);
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ const mln_value(Sv)&
+ p_vaccess_psite<Sv,Sp>::value_() const
+ {
+ return v_;
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ const mln_psite(Sp)&
+ p_vaccess_psite<Sv,Sp>::psite_() const
+ {
+ return p_;
+ }
+
+
+ // p_vaccess_fwd_piter<Sv,Sp>
+
+ template <typename Sv, typename Sp>
+ inline
+ p_vaccess_fwd_piter<Sv,Sp>::p_vaccess_fwd_piter()
+ {
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ p_vaccess_fwd_piter<Sv,Sp>::p_vaccess_fwd_piter(const p_vaccess<Sv,Sp>&
s)
+ {
+ this->change_target(s);
+ vi_.change_target(s.values());
+ invalidate_();
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ bool
+ p_vaccess_fwd_piter<Sv,Sp>::is_valid_() const
+ {
+ return pi_.is_valid();
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ void
+ p_vaccess_fwd_piter<Sv,Sp>::invalidate_()
+ {
+ pi_.invalidate();
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ void
+ p_vaccess_fwd_piter<Sv,Sp>::start_()
+ {
+ vi_.start();
+ if (vi_.is_valid())
+ p_.change_v(vi_);
+ pi_.change_target((*s_)(vi_));
+ pi_.start();
+ if (! pi_.is_valid())
+ progress_();
+ else
+ p_.change_p(pi_);
+ mln_postcondition(implies(pi_.is_valid(), vi_.is_valid()));
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ void
+ p_vaccess_fwd_piter<Sv,Sp>::next_()
+ {
+ pi_.next();
+ if (! pi_.is_valid())
+ progress_();
+ else
+ p_.change_p(pi_);
+ mln_postcondition(implies(pi_.is_valid(), vi_.is_valid()));
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ mln_value(Sv)
+ p_vaccess_fwd_piter<Sv,Sp>::value() const
+ {
+ mln_precondition(vi_.is_valid());
+ return vi_;
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ void
+ p_vaccess_fwd_piter<Sv,Sp>::progress_()
+ {
+ // This routine is general; it does not make the assumption that
+ // the site set type features is_empty().
+ while (! pi_.is_valid() && vi_.is_valid())
+ {
+ vi_.next();
+ if (! vi_.is_valid())
+ {
+ // End of iterations.
+ pi_.invalidate(); // Safety.
+ return;
+ }
+ p_.change_v(vi_);
+ pi_.change_target((*s_)(vi_));
+ pi_.start();
+ }
+ if (pi_.is_valid())
+ p_.change_p(pi_);
+ }
+
+
+ // p_vaccess_bkd_piter<Sv,Sp>
+
+ template <typename Sv, typename Sp>
+ inline
+ p_vaccess_bkd_piter<Sv,Sp>::p_vaccess_bkd_piter()
+ {
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ p_vaccess_bkd_piter<Sv,Sp>::p_vaccess_bkd_piter(const p_vaccess<Sv,Sp>&
s)
+ {
+ this->change_target(s);
+ vi_.change_target(s.values());
+ invalidate_();
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ bool
+ p_vaccess_bkd_piter<Sv,Sp>::is_valid_() const
+ {
+ return pi_.is_valid();
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ void
+ p_vaccess_bkd_piter<Sv,Sp>::invalidate_()
+ {
+ pi_.invalidate();
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ void
+ p_vaccess_bkd_piter<Sv,Sp>::start_()
+ {
+ vi_.start();
+ if (vi_.is_valid())
+ p_.change_v(vi_);
+ pi_.change_target((*s_)(vi_));
+ pi_.start();
+ if (! pi_.is_valid())
+ progress_();
+ else
+ p_.change_p(pi_);
+ mln_postcondition(implies(pi_.is_valid(), vi_.is_valid()));
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ void
+ p_vaccess_bkd_piter<Sv,Sp>::next_()
+ {
+ pi_.next();
+ if (! pi_.is_valid())
+ progress_();
+ else
+ p_.change_p(pi_);
+ mln_postcondition(implies(pi_.is_valid(), vi_.is_valid()));
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ mln_value(Sv)
+ p_vaccess_bkd_piter<Sv,Sp>::value() const
+ {
+ mln_precondition(vi_.is_valid());
+ return vi_;
+ }
+
+ template <typename Sv, typename Sp>
+ inline
+ void
+ p_vaccess_bkd_piter<Sv,Sp>::progress_()
+ {
+ // This routine is general; it does not make the assumption that
+ // the site set type features is_empty().
+ while (! pi_.is_valid() && vi_.is_valid())
+ {
+ vi_.next();
+ if (! vi_.is_valid())
+ {
+ // End of iterations.
+ pi_.invalidate(); // Safety.
+ return;
+ }
+ p_.change_v(vi_);
+ pi_.change_target((*s_)(vi_));
+ pi_.start();
+ }
+ if (pi_.is_valid())
+ p_.change_p(pi_);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_P_VACCESS_HH
Index: mln/core/plain.hh
--- mln/core/plain.hh (revision 2153)
+++ mln/core/plain.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -35,12 +35,9 @@
*/
# include <cmath>
-
# include <mln/core/internal/image_identity.hh>
# include <mln/core/clone.hh>
-# include <mln/algebra/vec.hh>
-
namespace mln
{
Index: mln/core/p_runs.hh
--- mln/core/p_runs.hh (revision 2153)
+++ mln/core/p_runs.hh (working copy)
@@ -25,553 +25,390 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_CORE_P_RUNS_HH
-# define MLN_CORE_P_RUNS_HH
+#ifndef MLN_CORE_P_RUN_SET_HH
+# define MLN_CORE_P_RUN_SET_HH
-/*! \file mln/core/p_runs.hh
+/*! \file mln/core/p_run_set.hh
*
- * \brief Definition of mln::internal::p_runs_ class and its iterators
- * (for internal use only).
+ * \brief Definition of a set of runs.
+ *
+ * \todo Zed: Test for unicity (see FIXMEs).
+ *
+ * \todo Write a p_set_of<S> class with inheritance features (for
+ * nsites and bbox).
*/
-# include <mln/core/internal/site_set_base.hh>
-# include <mln/core/internal/site_iterator_base.hh>
-# include <mln/core/runs_psite.hh>
-# include <mln/core/p_run.hh>
# include <mln/accu/bbox.hh>
-# include <mln/util/lazy_set.hh>
-
-# include <utility>
+# include <mln/core/p_run.hh>
+# include <mln/core/p_double.hh>
+# include <mln/core/internal/piter_adaptor.hh>
+# include <mln/util/set.hh>
namespace mln
{
- // Forward declaration
- template <typename P> struct p_runs_fwd_piter_;
- template <typename P> struct p_runs_bkd_piter_;
+ // Forward declaration.
+ template <typename P> class p_run_set;
+
+
+ namespace trait
+ {
+
+ template <typename P>
+ struct site_set_< p_run_set<P> >
+ {
+ typedef trait::site_set::nsites::known nsites;
+ typedef trait::site_set::bbox::straight bbox;
+ typedef trait::site_set::contents::growing contents;
+ typedef trait::site_set::arity::unique arity;
+ };
+
+ } // end of namespace trait
- /*! \brief p_runs_ class represent a point set used in run_image_ class.
+
+
+ /*! \brief p_run_set is a mathematical set of runs.
*
* Parameter \c P is the type of the image point.
*/
template <typename P>
- class p_runs_ : public internal::site_set_base_< runs_psite<P>,
p_runs_<P> >
+ class p_run_set : public internal::site_set_base_< P, p_run_set<P> >
{
+ typedef p_run_set<P> self_;
+ typedef util::set< p_run<P> > set_;
public:
-// typedef util::lazy_set_<p_run<P> > container;
- typedef p_runs_fwd_piter_<P> fwd_piter;
- typedef p_runs_bkd_piter_<P> bkd_piter;
+ /// Element associated type.
+ typedef p_run<P> element;
- /// Constructor without arguments.
- p_runs_();
- /// Test is \p p belongs to this point set.
- bool has(const runs_psite<P>& ps) const;
+ /// Psite associated type.
+ typedef p_double_psite<self_, element> psite;
- /// Give the exact bounding box.
- const box_<P>& bbox() const;
+ /// Forward Site_Iterator associated type.
+ typedef p_double_piter<self_,
+ mln_fwd_iter(set_),
+ mln_fwd_piter(p_run<P>)> fwd_piter;
- /// Give the number of points.
- typename std::size_t npoints() const;
+ /// Backward Site_Iterator associated type.
+ typedef p_double_piter<self_,
+ mln_bkd_iter(set_),
+ mln_bkd_piter(p_run<P>)> bkd_piter;
- /// Insert a range, start at point \p p wit len \p len.
- void insert(const p_run<P>& pr);
+ /// Site_Iterator associated type.
+ typedef fwd_piter piter;
- /// Return the number of runs.
- unsigned nruns() const;
- /// Return the len of the range starting at point \p p.
- unsigned range_len_(const P& p) const;
+ /// Constructor without arguments.
+ p_run_set();
- /// Return the i-th run of the list of runs
- const p_run<P>& operator[](unsigned i) const;
- /// Return the size of the data in memory.
- unsigned size_mem() const;
+ /// Test if \p p belongs to this point set.
+ bool has(const psite& p) const;
- /// Finalize the lazy_set (internal use)
- void finalize();
+ /// Test if this set of runs is valid.
+ bool is_valid() const;
-// /// Return the container of the pset (internal use only).
-// const container& con() const;
- protected:
+ /// Box associated type.
+ typedef const mln::box<P>& q_box;
- /// Number of points.
- typename std::size_t npoints_;
+ /// Give the exact bounding box.
+ const box<P>& bbox() const;
- /// Points container
- util::lazy_set_<p_run<P> > con_;
- /// Exact bounding box.
- accu::bbox<P> fb_;
- };
+ /// Give the number of points.
+ unsigned nsites() const;
-# ifndef MLN_INCLUDE_ONLY
+ /// Give the number of runs.
+ unsigned nruns() const;
- template <typename P>
- inline
- p_runs_<P>::p_runs_() :
- npoints_(0)
- {
- }
+ /// Give the compression ratio: FIXME: explain...
+ float zratio() const;
- template <typename P>
- inline
- bool
- p_runs_<P>::has(const runs_psite<P>& ps) const
- {
- if (ps.p_of_run() < nruns()
- && ps.p_in_run() < con_[ps.p_of_run()].length())
- return (ps == con_[ps.p_of_run()][ps.p_in_run()]);
- else
- return false;
- }
- template <typename P>
- inline
- const box_<P>&
- p_runs_<P>::bbox() const
- {
- return fb_.to_result();
- }
+ /// Insertion element associated type.
+ typedef p_run<P> i_element;
- template <typename P>
- inline
- typename std::size_t
- p_runs_<P>::npoints() const
- {
- return npoints_;
- }
+ /// Insert a run \p r.
+ void insert(const p_run<P>& r);
- template <typename P>
- inline
- void
- p_runs_<P>::insert(const p_run<P>& pr)
- {
- typename std::vector<p_run<P> >::const_iterator iter =
con_.vect().begin();
- while (iter != con_.vect().end() && iter->first() < pr.first())
- ++iter;
-
- if (iter != con_.vect().begin())
- {
- typename std::vector<p_run<P> >::const_iterator prec = iter;
- --prec;
- bool equal = true;
- for (int i = P::dim - 2; i >= 0; --i)
- if (!(equal = equal && (prec->first()[i] == pr.first()[i])))
- break;
- if (equal)
- mln_assertion(prec->first()[P::dim - 1] + (signed)prec->length()
- <= pr.first()[P::dim - 1]);
- }
-
- if (iter != con_.vect().end())
- {
- bool equal = true;
- for (int i = P::dim - 2; i >= 0; --i)
- if (!(equal = equal && ((*iter).first()[i] == pr.first()[i])))
- break;
- if (equal)
- mln_assertion(pr.first()[P::dim - 1] + (signed)pr.length()
- <= iter->first()[P::dim - 1]);
- }
- con_.insert(pr);
-
- // update box
- fb_.take(pr.bbox().pmin());
- fb_.take(pr.bbox().pmax());
- // update size
- npoints_ += pr.npoints();
- }
+ /// Insert a run from \p start to \p end.
+ void insert(const P& start, const P& end);
- template <typename P>
- inline
- unsigned
- p_runs_<P>::nruns() const
- {
- return con_.nelements();
- }
+ /// Insert a run defined by \p start with length \p len.
+ void insert(const P& start, unsigned short len);
- template <typename P>
- inline
- unsigned
- p_runs_<P>::range_len_(const P& p) const
- {
- unsigned i;
- for (i = 0; i < con_.size(); ++i)
- {
- if (con_[i].first == p)
- return con_[i].second;
- }
- mln_assertion(i < con_.size());
+ /// Insert another set of runs.
+ void insert(const p_run_set<P>& other);
- //Hack
- return (con_[i].second);
- }
- template <typename P>
- inline
- const p_run<P>&
- p_runs_<P>::operator[](unsigned i) const
- {
- return con_[i];
- }
+ /// Return the i-th run.
+ const p_run<P>& run(unsigned i) const;
- template <typename P>
- inline
- unsigned
- p_runs_<P>::size_mem() const
- {
- if (con_.get_mode())
- return nruns() * (sizeof(P) + sizeof(unsigned));
- else
- return 2 * nruns() * (sizeof(P) + sizeof(unsigned));
- }
+ /// Return the size of this site set in memory.
+ std::size_t memory_size() const;
- template <typename P>
- inline
- void
- p_runs_<P>::finalize()
- {
- con_.set_const_mode(true);
- }
+ /// Hook to the set of runs.
+ const util::set< p_run<P> >& hook_() const;
-// template <typename P>
-// const typename p_runs_<P>::container&
-// p_runs_<P>::con() const
-// {
-// return con_;
-// }
+ // Required by p_double-related classes.
+ const util::set< p_run<P> >& set_1_() const;
+ template <typename I>
+ const p_run<P>& set_2_(const I& it) const;
-# endif // ! MLN_INCLUDE_ONLY
- /*! \brief Factorization class for p_runs_iterator_.
- *
- * Parameter \c P is the type of the point used in the point set.
- * Parameter \c E is the exact type of the iterator
- */
- template <typename P, typename E>
- class p_runs_piter_ : public internal::site_iterator_base_< runs_psite<P>, E
>
- {
- public:
+ protected:
- /// Conversion into a point.
- operator P () const;
+ /// Number of points.
+ unsigned nsites_;
- /// Reference to the corresponding point.
- const P& to_point() const;
+ /// Bounding box accumulator.
+ accu::bbox<P> b_;
- /// Access to the current point coordinates.
- mln_coord(P) operator[](unsigned i) const;
+ /// Set of runs.
+ util::set< p_run<P> > run_;
+ };
- /// Assign a new pset to the iterator
- void assign(const p_runs_<P>& pset);
- protected:
- /// Current point.
- P p_;
+ template <typename P>
+ std::ostream& operator<<(std::ostream& ostr, const
p_run_set<P>& r);
- /// Point set container.
- const p_runs_<P>* con_;
- p_runs_piter_(const p_runs_<P>& pset);
- p_runs_piter_();
+ namespace util
+ {
+
+ template <typename P>
+ struct less< p_run_set<P> >
+ {
+ bool operator()(const p_run_set<P>& lhs,
+ const p_run_set<P>& rhs) const;
};
+ } // end of namespace mln::util
+
+
+
# ifndef MLN_INCLUDE_ONLY
- template <typename P, typename E>
+ template <typename P>
inline
- p_runs_piter_<P, E>::p_runs_piter_(const p_runs_<P>& pset) :
- con_(&pset)
+ p_run_set<P>::p_run_set()
+ :
+ nsites_(0)
{
}
- template <typename P, typename E>
+ template <typename P>
inline
- p_runs_piter_<P, E>::p_runs_piter_() :
- con_(0)
+ bool
+ p_run_set<P>::has(const psite&) const
{
+ // FIXME
+ return true;
}
- template <typename P, typename E>
+ template <typename P>
inline
- p_runs_piter_<P, E>::operator P () const
+ bool
+ p_run_set<P>::is_valid() const
{
- return this->to_point();
+ // FIXME: A run of this set can be invalid...
+ return true;
}
- template <typename P, typename E>
+ template <typename P>
inline
- const P&
- p_runs_piter_<P, E>::to_point() const
+ const box<P>&
+ p_run_set<P>::bbox() const
{
- mln_precondition(exact(this)->is_valid());
- return p_;
+ return b_.to_result();
}
- template <typename P, typename E>
+ template <typename P>
inline
- mln_coord(P)
- p_runs_piter_<P, E>::operator[] (unsigned i) const
+ unsigned
+ p_run_set<P>::nsites() const
{
- mln_precondition(exact(this)->is_valid());
- return p_[i];
+ return nsites_;
}
- template <typename P, typename E>
+ template <typename P>
inline
void
- p_runs_piter_<P, E>::assign(const p_runs_<P>& pset)
+ p_run_set<P>::insert(const p_run_set<P>& other)
{
- con_ = &pset;
+ if (other.nsites() == 0)
+ // No-op.
+ return;
+ nsites_ += other.nsites();
+ b_.take(other.bbox());
+ run_.insert(other.run_);
}
-# endif // ! MLN_INCLUDE_ONLY
-
-
- /*! \brief Forward iterator on p_runs_ point set.
- *
- * Parameter \c P is the type of the point used in the point set.
- */
template <typename P>
- class p_runs_fwd_piter_ : public p_runs_piter_<P, p_runs_fwd_piter_<P> >
+ inline
+ void
+ p_run_set<P>::insert(const p_run<P>& r)
{
- typedef p_runs_piter_<P, p_runs_fwd_piter_<P> > super;
- public:
-
- p_runs_fwd_piter_();
- p_runs_fwd_piter_(const p_runs_<P>& pset);
-
- /// Test the iterator validity.
- bool is_valid() const;
-
- /// Invalidate the iterator.
- void invalidate();
-
- /// Start an iteration.
- void start();
-
- /// Go to the next point.
- void next_();
+ nsites_ += r.nsites();
+ b_.take(r.bbox());
+ run_.insert(r);
+ }
- /// Conversion into a point-site.
- operator runs_psite<P> () const;
- protected:
+// Previous code of 'insert' was:
+//
+// {
+// typename std::vector<p_run<P> >::const_iterator iter =
con_.vect().begin();
+// while (iter != con_.vect().end() && iter->first() < pr.first())
+// ++iter;
- unsigned i_;
+// if (iter != con_.vect().begin())
+// {
+// typename std::vector<p_run<P> >::const_iterator prec = iter;
+// --prec;
+// bool equal = true;
+// for (int i = P::dim - 2; i >= 0; --i)
+// if (!(equal = equal && (prec->first()[i] == pr.first()[i])))
+// break;
+// if (equal)
+// mln_assertion(prec->first()[P::dim - 1] + (signed)prec->length()
+// <= pr.first()[P::dim - 1]);
+// }
- p_run_fwd_piter_<P> it_;
- };
+// if (iter != con_.vect().end())
+// {
+// bool equal = true;
+// for (int i = P::dim - 2; i >= 0; --i)
+// if (!(equal = equal && ((*iter).first()[i] == pr.first()[i])))
+// break;
+// if (equal)
+// mln_assertion(pr.first()[P::dim - 1] + (signed)pr.length()
+// <= iter->first()[P::dim - 1]);
+// }
+// con_.insert(pr);
+// // update box
+// fb_.take(pr.bbox().pmin());
+// fb_.take(pr.bbox().pmax());
+// // update size
+// npoints_ += pr.npoints();
+// }
-# ifndef MLN_INCLUDE_ONLY
template <typename P>
inline
- p_runs_fwd_piter_<P>::p_runs_fwd_piter_()
+ void
+ p_run_set<P>::insert(const P& start, const P& end)
{
+ mln_precondition(cut_(end) == cut_(start));
+ mln_precondition(end.last_coord() >= start.last_coord());
+ p_run<P> r(start, end);
+ this->insert(r);
}
template <typename P>
inline
- p_runs_fwd_piter_<P>::p_runs_fwd_piter_(const p_runs_<P>& pset) :
- super(pset)
+ void
+ p_run_set<P>::insert(const P& start, unsigned short len)
{
- invalidate();
+ mln_precondition(len != 0);
+ p_run<P> r(start, len);
+ this->insert(r);
}
template <typename P>
inline
- bool
- p_runs_fwd_piter_<P>::is_valid() const
+ unsigned
+ p_run_set<P>::nruns() const
{
- return this->con_ != 0 && i_ < this->con_->nruns();
+ return run_.nelements();
}
template <typename P>
inline
- void
- p_runs_fwd_piter_<P>::invalidate()
+ const p_run<P>&
+ p_run_set<P>::run(unsigned i) const
{
- mln_precondition(this->con_ != 0);
-
- i_ = this->con_->nruns();
+ mln_precondition(i < nruns());
+ return run_[i];
}
template <typename P>
inline
- void
- p_runs_fwd_piter_<P>::start()
+ std::size_t
+ p_run_set<P>::memory_size() const
{
- mln_precondition(this->con_ != 0);
-
- i_ = 0;
- it_.assign_run((*this->con_)[i_]);
- it_.start();
- this->p_ = it_;
+ return run_.memory_size() + sizeof(nsites_) + sizeof(b_);
}
template <typename P>
inline
- void
- p_runs_fwd_piter_<P>::next_()
- {
- mln_precondition(this->is_valid());
- mln_precondition(this->con_ != 0);
-
- it_.next();
- if (!it_.is_valid())
- {
- ++i_;
- if (is_valid())
- {
- it_.assign_run( (*this->con_)[i_]);
- it_.start();
- }
- else
- return;
- }
- this->p_ = it_;
- }
-
- template <typename P>
- p_runs_fwd_piter_<P>::operator runs_psite<P> () const
+ float
+ p_run_set<P>::zratio() const
{
- mln_precondition(this->con_ != 0);
-
- return runs_psite<P>(*this->con_, it_.ind(), i_);
+ return
+ float(memory_size()) /
+ float(b_.to_result().nsites() * sizeof(P));
}
-# endif // ! MLN_INCLUDE_ONLY
-
-
- /*! \brief Backward iterator on p_runs_ point set.
- *
- * Parameter \c P is the type of the point used in the point set.
- */
- template <typename P>
- class p_runs_bkd_piter_ : public p_runs_piter_<P, p_runs_bkd_piter_<P> >
- {
- typedef p_runs_piter_<P, p_runs_bkd_piter_<P> > super;
- public:
-
- p_runs_bkd_piter_();
- p_runs_bkd_piter_(const p_runs_<P>& pset);
-
- /// Test the iterator validity.
- bool is_valid() const;
-
- /// Invalidate the iterator.
- void invalidate();
-
- /// Start an iteration.
- void start();
-
- /// Go to the next point.
- void next_();
-
- /// Conversion into a point-site.
- operator runs_psite<P> () const;
-
- protected:
-
- unsigned i_;
-
- p_run_bkd_piter_<P> it_;
-};
-
-
-
-# ifndef MLN_INCLUDE_ONLY
-
-
template <typename P>
inline
- p_runs_bkd_piter_<P>::p_runs_bkd_piter_()
+ const util::set< p_run<P> >&
+ p_run_set<P>::hook_() const
{
+ return run_;
}
template <typename P>
inline
- p_runs_bkd_piter_<P>::p_runs_bkd_piter_(const p_runs_<P>& pset) :
- super(pset)
+ const util::set< p_run<P> >&
+ p_run_set<P>::set_1_() const
{
- invalidate();
+ return run_;
}
template <typename P>
+ template <typename I>
inline
- bool
- p_runs_bkd_piter_<P>::is_valid() const
+ const p_run<P>&
+ p_run_set<P>::set_2_(const I& it) const
{
- return this->con_ != 0 &&i_ < this->con_->nruns();
+ return it.element();
}
- template <typename P>
- inline
- void
- p_runs_bkd_piter_<P>::invalidate()
- {
- mln_precondition(this->con_ != 0);
-
- i_ = this->con_->nruns();
- }
template <typename P>
- inline
- void
- p_runs_bkd_piter_<P>::start()
+ std::ostream& operator<<(std::ostream& ostr, const
p_run_set<P>& r)
{
- mln_precondition(this->con_ != 0);
-
- i_ = this->con_->nruns() - 1;
- it_.assign_run((*this->con_)[i_]);
- it_.start();
- this->p_ = it_;
+ return ostr << r.hook_();
}
- template <typename P>
- inline
- void
- p_runs_bkd_piter_<P>::next_()
- {
- mln_precondition(this->is_valid());
- mln_precondition(this->con_ != 0);
- it_.next();
- if (!it_.is_valid())
+ namespace util
{
- --i_;
- if (is_valid())
- {
- it_.assign_run((*this->con_)[i_]);
- it_.start();
- }
- else
- return;
- }
- this->p_ = it_;
- }
template <typename P>
- p_runs_bkd_piter_<P>::operator runs_psite<P> () const
+ inline
+ bool
+ less< p_run_set<P> >::operator()(const p_run_set<P>& lhs,
+ const p_run_set<P>& rhs) const
{
- mln_precondition(this->con_ != 0);
- return runs_psite<P>((*this->con_), it_.ind(), i_);
+ return op_less(lhs.run(0), rhs.run(0));
}
+ } // end of namespace mln::util
+
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln
-#endif // ! MLN_CORE_P_RUNS_HH
+#endif // ! MLN_CORE_P_RUN_SET_HH
Index: mln/core/image2d.hh
--- mln/core/image2d.hh (revision 2153)
+++ mln/core/image2d.hh (working copy)
@@ -43,12 +43,15 @@
// # include <mln/core/line_piter.hh> // FIXME
+
// FIXME:
// # include <mln/core/pixter2d.hh>
// # include <mln/core/dpoints_pixter.hh>
+
+
namespace mln
{
@@ -182,6 +185,25 @@
T& operator()(const point2d& p);
+ template <typename P>
+ T& alt(const P& p)
+ {
+ mln_precondition(this->has(p));
+
+// std::cout << (int*)(&p.p_hook_()) << ' '
+// << &(p.row()) << ' '
+// << &(p.get_subject()) << ' '
+// << &(p.to_site()) << std::endl;
+
+ // return this->data_->array_[p.to_site().row()][p.to_site().col()];
+ // return this->data_->array_[p.row()][p.col()];
+ // return this->data_->array_[p.get_subject().row()][p.get_subject().col()];
+ // return this->data_->array_ [*(int*)(&p.get_subject())]
[*((int*)(&p.get_subject()) + 1)];
+ return this->data_->array_ [*(int*)(&p.p_hook_())]
[*((int*)(&p.p_hook_()) + 1)];
+ // return this->data_->array_[0][0];;
+ }
+
+
// Specific methods:
// -----------------
Index: mln/metal/unqualif.hh
--- mln/metal/unqualif.hh (revision 2153)
+++ mln/metal/unqualif.hh (working copy)
@@ -33,6 +33,8 @@
*
* \brief Suppress possible 'const' and/or '&' (reference) from a
* qualified type.
+ *
+ * \todo Handle (or not) 'T*'.
*/
# include <mln/metal/unconst.hh>
Index: mln/metal/const.hh
--- mln/metal/const.hh (revision 2153)
+++ mln/metal/const.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -44,17 +44,16 @@
namespace metal
{
- template <typename T>
- struct const_
- {
- typedef const T ret;
- };
+ template <typename T> struct const_/* T */ { typedef const T ret;
};
+ template <typename T> struct const_< const T > { typedef const T
ret; };
- template <typename T>
- struct const_< const T >
- {
- typedef const T ret;
- };
+ template <typename T> struct const_< T& > { typedef const
T& ret; };
+ template <typename T> struct const_< const T& > { typedef const
T& ret; };
+
+ template <typename T> struct const_< T* > { typedef const T*
const ret; };
+ template <typename T> struct const_< const T* > { typedef const T*
const ret; };
+ template <typename T> struct const_< T* const > { typedef const T*
const ret; };
+ template <typename T> struct const_< const T* const > { typedef const T*
const ret; };
} // end of namespace mln::metal
Index: mln/metal/is_not_ref.hh
--- mln/metal/is_not_ref.hh (revision 0)
+++ mln/metal/is_not_ref.hh (revision 0)
@@ -0,0 +1,66 @@
+// Copyright (C) 2008 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 MLN_METAL_IS_NOT_REF_HH
+# define MLN_METAL_IS_NOT_REF_HH
+
+/*!
+ * \file mln/metal/is_not_ref.hh
+ *
+ * \brief FIXME.
+ */
+
+# include <mln/metal/bool.hh>
+
+
+# define mlc_is_not_ref(T) mln::metal::is_not_ref< T >
+
+
+namespace mln
+{
+
+ namespace metal
+ {
+
+ template <typename T>
+ struct is_not_ref : true_
+ {};
+
+ template <typename T>
+ struct is_not_ref< T& > : false_
+ {};
+
+ template <typename T>
+ struct is_not_ref< const T& > : false_
+ {};
+
+ } // end of namespace mln::metal
+
+} // end of namespace mln
+
+
+#endif // ! MLN_METAL_IS_NOT_REF_HH
Index: mln/metal/is_ref.hh
--- mln/metal/is_ref.hh (revision 0)
+++ mln/metal/is_ref.hh (revision 0)
@@ -0,0 +1,66 @@
+// Copyright (C) 2008 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 MLN_METAL_IS_REF_HH
+# define MLN_METAL_IS_REF_HH
+
+/*!
+ * \file mln/metal/is_ref.hh
+ *
+ * \brief FIXME.
+ */
+
+# include <mln/metal/bool.hh>
+
+
+# define mlc_is_ref(T) mln::metal::is_ref< T >
+
+
+namespace mln
+{
+
+ namespace metal
+ {
+
+ template <typename T>
+ struct is_ref : false_
+ {};
+
+ template <typename T>
+ struct is_ref< T& > : true_
+ {};
+
+ template <typename T>
+ struct is_ref< const T& > : true_
+ {};
+
+ } // end of namespace mln::metal
+
+} // end of namespace mln
+
+
+#endif // ! MLN_METAL_IS_REF_HH
Index: mln/metal/is_a.hh
--- mln/metal/is_a.hh (revision 2153)
+++ mln/metal/is_a.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -66,6 +66,12 @@
static T* ptr();
};
+ template <typename T>
+ struct make_< T& >
+ {
+ static T* ptr();
+ };
+
template <typename T, template <class> class U>
struct helper_is_a_
{
@@ -93,6 +99,14 @@
struct is_a< const T, U > : is_a< T, U >::eval
{};
+ template <typename T, template <class> class U>
+ struct is_a< T&, U > : is_a< T, U >::eval
+ {};
+
+ template <typename T, template <class> class U>
+ struct is_a< const T&, U > : is_a< T, U >::eval
+ {};
+
} // end of namespace mln::metal
Index: mln/metal/is.hh
--- mln/metal/is.hh (revision 2153)
+++ mln/metal/is.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -72,6 +72,10 @@
};
template <typename T, typename U>
+ struct is< const T, const U > : is<T, U>::eval
+ {};
+
+ template <typename T, typename U>
struct is< T*, U* > : is<T, U>::eval
{};
Index: mln/metal/ref.hh
--- mln/metal/ref.hh (revision 0)
+++ mln/metal/ref.hh (revision 0)
@@ -0,0 +1,64 @@
+// Copyright (C) 2008 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 MLN_METAL_REF_HH
+# define MLN_METAL_RFE_HH
+
+/*!
+ * \file mln/metal/ref.hh
+ *
+ * \brief FIXME.
+ */
+
+
+# define mlc_ref(T) typename mln::metal::ref< T >::ret
+
+
+namespace mln
+{
+
+ namespace metal
+ {
+
+ template <typename T>
+ struct ref
+ {
+ typedef T& ret;
+ };
+
+ template <typename T>
+ struct ref< T& >
+ {
+ typedef T& ret;
+ };
+
+ } // end of namespace mln::metal
+
+} // end of namespace mln
+
+
+#endif // ! MLN_METAL_REF_HH
Index: mln/metal/unref.hh
--- mln/metal/unref.hh (revision 2153)
+++ mln/metal/unref.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -35,6 +35,7 @@
*/
# define mlc_unref(T) typename mln::metal::unref< T >::ret
+# define mlc_unref_(T) mln::metal::unref< T >::ret
namespace mln
@@ -55,6 +56,12 @@
typedef T ret;
};
+ template <typename T>
+ struct unref< const T& >
+ {
+ typedef const T ret;
+ };
+
} // end of namespace mln::metal
} // end of namespace mln
Index: mln/level/fill_with_value.hh
--- mln/level/fill_with_value.hh (revision 2153)
+++ mln/level/fill_with_value.hh (working copy)
@@ -42,6 +42,7 @@
# include <mln/core/concept/image.hh>
# include <mln/core/inplace.hh>
+# include <mln/core/image/instant.hh>
namespace mln
@@ -63,6 +64,11 @@
void fill_with_value(Image<I>& ima, const V& val);
+ // Case of instant images.
+ template <typename I, typename V>
+ void fill_with_value(const Image< instant_<I> >& ima, const V&
val);
+
+
# ifndef MLN_INCLUDE_ONLY
@@ -200,6 +206,14 @@
}
+ // Un-instant.
+
+ template <typename I, typename V>
+ void fill_with_value(const Image< instant_<I> >& ima, const V&
val)
+ {
+ fill_with_value(exact(ima).un_instant_(), val);
+ }
+
# endif // ! MLN_INCLUDE_ONLY
Index: mln/accu/bbox.hh
--- mln/accu/bbox.hh (revision 2153)
+++ mln/accu/bbox.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -49,10 +49,10 @@
* The parameter \c P is the type of points.
*/
template <typename P>
- struct bbox : public mln::accu::internal::base_< const box_<P>& ,
bbox<P> >
+ struct bbox : public mln::accu::internal::base_< const box<P>& ,
bbox<P> >
{
typedef P argument;
- typedef const box_<P>& result;
+ typedef const box<P>& result;
bbox();
@@ -60,16 +60,16 @@
void take_as_init(const P& p);
void take(const P& p);
void take(const bbox<P>& other);
- void take(const box_<P>& other);
+ void take(const box<P>& b);
- const box_<P>& to_result() const;
+ const box<P>& to_result() const;
bool is_valid() const;
protected:
bool is_valid_;
- box_<P> b_;
+ box<P> b_;
};
@@ -138,7 +138,7 @@
return;
}
// both are valids so:
- const box_<P>& o_b = other.b_;
+ const box<P>& o_b = other.b_;
for (unsigned i = 0; i < P::dim; ++i)
{
if (o_b.pmin()[i] < b_.pmin()[i])
@@ -151,32 +151,32 @@
template <typename P>
inline
void
- bbox<P>::take(const box_<P>& other)
+ bbox<P>::take(const box<P>& b)
{
- if (other.npoints() == 0)
+ if (! b.is_valid())
{
// no-op
return;
}
if (! this->is_valid_)
{
- b_ = other;
+ b_ = b;
is_valid_ = true;
return;
}
// both are valids so:
for (unsigned i = 0; i < P::dim; ++i)
{
- if (other.pmin()[i] < b_.pmin()[i])
- b_.pmin()[i] = other.pmin()[i];
- if (other.pmax()[i] > b_.pmax()[i])
- b_.pmax()[i] = other.pmax()[i];
+ if (b.pmin()[i] < b_.pmin()[i])
+ b_.pmin()[i] = b.pmin()[i];
+ if (b.pmax()[i] > b_.pmax()[i])
+ b_.pmax()[i] = b.pmax()[i];
}
}
template <typename P>
inline
- const box_<P>&
+ const box<P>&
bbox<P>::to_result() const
{
mln_precondition(is_valid_);
Index: mln/accu/internal/base.hh
--- mln/accu/internal/base.hh (revision 2153)
+++ mln/accu/internal/base.hh (working copy)
@@ -32,15 +32,9 @@
*
* \brief Define a base class for implementation of accumulator
* classes.
- *
- * \todo Cf. mln/core/pseudo_site_base.hh we get some impl from
- * site_impl; we want here the same effect except that the subject is
- * not always a site. Maybe we actually need a more generic mechanism
- * s.a. subject_impl...
*/
# include <mln/core/concept/accumulator.hh>
-# include <mln/metal/unqualif.hh>
namespace mln
@@ -57,16 +51,12 @@
*/
template <typename R, typename E>
class base_ : public Accumulator<E>,
- public mln::internal::proxy_impl< mlc_unqualif(R), E >
+ public mln::internal::proxy_impl< R, E >
{
- typedef mlc_unconst(R) tmp_;
- typedef mlc_unref(tmp_) result_;
public:
// As a proxy:
- typedef R q_subject;
- typedef mlc_unqualif(R) subject;
- R unproxy() const;
+ R subj_();
// As an accumulator:
typedef R result;
@@ -87,7 +77,7 @@
template <typename R, typename E>
inline
R
- base_<R,E>::unproxy() const
+ base_<R,E>::subj_()
{
return exact(this)->to_result();
}
Index: mln/value/viter.hh
--- mln/value/viter.hh (revision 2153)
+++ mln/value/viter.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -31,6 +31,8 @@
/*! \file mln/value/viter.hh
*
* \brief Definition of iterators on value sets.
+ *
+ * \todo Proxify it!
*/
# include <mln/core/concept/value_iterator.hh>
@@ -54,11 +56,13 @@
/// Value associated type.
typedef mln_value(S) value;
+ /// Constructor without argument.
+ fwd_viter_();
+
/// Constructor.
fwd_viter_(const Value_Set<S>& s);
- /// Conversion into a value.
- operator mln_value(S) () const;
+ void change_target(const S& s);
/// Test if the iterator is valid.
bool is_valid() const;
@@ -72,10 +76,16 @@
/// Go to the next value.
void next_();
+ /// Conversion into a value.
+ operator mln_value(S) () const;
+
+ /// Give the current index.
+ unsigned index_() const;
+
private:
- const S& s_;
- std::size_t i_;
+ const S* s_;
+ unsigned i_;
};
@@ -91,11 +101,13 @@
/// Value associated type.
typedef mln_value(S) value;
+ /// Constructor without argument.
+ bkd_viter_();
+
/// Constructor.
bkd_viter_(const Value_Set<S>& s);
- /// Conversion into a value.
- operator mln_value(S) () const;
+ void change_target(const S& s);
/// Test if the iterator is valid.
bool is_valid() const;
@@ -109,10 +121,16 @@
/// Go to the next value.
void next_();
+ /// Conversion into a value.
+ operator mln_value(S) () const;
+
+ /// Give the current index.
+ unsigned index_() const;
+
private:
- const S& s_;
- std::size_t i_;
+ const S* s_;
+ unsigned i_;
};
@@ -124,18 +142,25 @@
template <typename S>
inline
+ fwd_viter_<S>::fwd_viter_()
+ : s_(0)
+ {
+ }
+
+ template <typename S>
+ inline
fwd_viter_<S>::fwd_viter_(const Value_Set<S>& s)
- : s_(exact(s))
{
- invalidate();
+ change_target(exact(s));
}
template <typename S>
inline
- fwd_viter_<S>::operator mln_value(S) () const
+ void
+ fwd_viter_<S>::change_target(const S& s)
{
- mln_precondition(is_valid());
- return s_[i_];
+ s_ = &s;
+ invalidate();
}
template <typename S>
@@ -143,7 +168,7 @@
bool
fwd_viter_<S>::is_valid() const
{
- return i_ < s_.nvalues();
+ return s_ != 0 && i_ < s_->nvalues();
}
template <typename S>
@@ -151,7 +176,7 @@
void
fwd_viter_<S>::invalidate()
{
- i_ = s_.nvalues();
+ i_ = s_->nvalues();
}
template <typename S>
@@ -170,23 +195,46 @@
++i_;
}
+ template <typename S>
+ inline
+ fwd_viter_<S>::operator mln_value(S) () const
+ {
+ mln_precondition(is_valid());
+ return (*s_)[i_];
+ }
+
+ template <typename S>
+ inline
+ unsigned
+ fwd_viter_<S>::index_() const
+ {
+ return i_;
+ }
+
// bkd_viter_<S>
template <typename S>
inline
+ bkd_viter_<S>::bkd_viter_()
+ : s_(0)
+ {
+ }
+
+ template <typename S>
+ inline
bkd_viter_<S>::bkd_viter_(const Value_Set<S>& s)
- : s_(exact(s))
{
- invalidate();
+ change_target(exact(s));
}
template <typename S>
inline
- bkd_viter_<S>::operator mln_value(S) () const
+ void
+ bkd_viter_<S>::change_target(const S& s)
{
- mln_precondition(is_valid());
- return s_[i_];
+ s_ = &s;
+ invalidate();
}
template <typename S>
@@ -194,7 +242,7 @@
bool
bkd_viter_<S>::is_valid() const
{
- return i_ != s_.nvalues();
+ return s_ != 0 && i_ != s_->nvalues();
}
template <typename S>
@@ -202,7 +250,7 @@
void
bkd_viter_<S>::invalidate()
{
- i_ = s_.nvalues();
+ i_ = s_->nvalues();
}
template <typename S>
@@ -210,7 +258,7 @@
void
bkd_viter_<S>::start()
{
- i_ = s_.nvalues() - 1;
+ i_ = s_->nvalues() - 1;
}
template <typename S>
@@ -226,6 +274,22 @@
--i_;
}
+ template <typename S>
+ inline
+ bkd_viter_<S>::operator mln_value(S) () const
+ {
+ mln_precondition(is_valid());
+ return (*s_)[i_];
+ }
+
+ template <typename S>
+ inline
+ unsigned
+ bkd_viter_<S>::index_() const
+ {
+ return i_;
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::value
Index: mln/value/builtin/symbolics.hh
--- mln/value/builtin/symbolics.hh (revision 2153)
+++ mln/value/builtin/symbolics.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -45,8 +45,7 @@
template <>
struct category< bool >
{
- typedef value::Built_In<void*> ret;
- typedef value::Symbolic<void> super;
+ typedef value::Built_In< value::Symbolic<void> > ret;
};
Index: mln/value/builtin/floatings.hh
--- mln/value/builtin/floatings.hh (revision 2153)
+++ mln/value/builtin/floatings.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -47,15 +47,13 @@
template <>
struct category< float >
{
- typedef value::Built_In<void*> ret;
- typedef value::Floating<void> super;
+ typedef value::Built_In< value::Floating<void> > ret;
};
template <>
struct category< double >
{
- typedef value::Built_In<void*> ret;
- typedef value::Floating<void> super;
+ typedef value::Built_In< value::Floating<void> > ret;
};
Index: mln/value/builtin/integers.hh
--- mln/value/builtin/integers.hh (revision 2153)
+++ mln/value/builtin/integers.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -47,14 +47,14 @@
namespace mln
{
- template <> struct category< unsigned char > { typedef
value::Built_In<void> ret; typedef value::Integer<void> super; };
- template <> struct category< signed char > { typedef
value::Built_In<void> ret; typedef value::Integer<void> super; };
- template <> struct category< unsigned short > { typedef
value::Built_In<void> ret; typedef value::Integer<void> super; };
- template <> struct category< signed short > { typedef
value::Built_In<void> ret; typedef value::Integer<void> super; };
- template <> struct category< unsigned int > { typedef
value::Built_In<void> ret; typedef value::Integer<void> super; };
- template <> struct category< signed int > { typedef
value::Built_In<void> ret; typedef value::Integer<void> super; };
- template <> struct category< unsigned long > { typedef
value::Built_In<void> ret; typedef value::Integer<void> super; };
- template <> struct category< signed long > { typedef
value::Built_In<void> ret; typedef value::Integer<void> super; };
+ template <> struct category< unsigned char > { typedef value::Built_In<
value::Integer<void> > ret; };
+ template <> struct category< signed char > { typedef value::Built_In<
value::Integer<void> > ret; };
+ template <> struct category< unsigned short > { typedef value::Built_In<
value::Integer<void> > ret; };
+ template <> struct category< signed short > { typedef value::Built_In<
value::Integer<void> > ret; };
+ template <> struct category< unsigned int > { typedef value::Built_In<
value::Integer<void> > ret; };
+ template <> struct category< signed int > { typedef value::Built_In<
value::Integer<void> > ret; };
+ template <> struct category< unsigned long > { typedef value::Built_In<
value::Integer<void> > ret; };
+ template <> struct category< signed long > { typedef value::Built_In<
value::Integer<void> > ret; };
namespace trait
Index: mln/make/dpoint1d.hh
--- mln/make/dpoint1d.hh (revision 2153)
+++ mln/make/dpoint1d.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -48,13 +48,13 @@
*
* \return A 1D dpoint.
*/
- mln::dpoint1d dpoint1d(int ind);
+ mln::dpoint1d dpoint1d(def::coord ind);
# ifndef MLN_INCLUDE_ONLY
inline
- mln::dpoint1d dpoint1d(int ind)
+ mln::dpoint1d dpoint1d(def::coord ind)
{
mln::dpoint1d tmp;
tmp[0] = ind;
Index: mln/make/dpoint2d.hh
--- mln/make/dpoint2d.hh (revision 2153)
+++ mln/make/dpoint2d.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -49,13 +49,13 @@
*
* \return A 2D dpoint.
*/
- mln::dpoint2d dpoint2d(int row, int col);
+ mln::dpoint2d dpoint2d(def::coord row, def::coord col);
# ifndef MLN_INCLUDE_ONLY
inline
- mln::dpoint2d dpoint2d(int row, int col)
+ mln::dpoint2d dpoint2d(def::coord row, def::coord col)
{
mln::dpoint2d tmp;
tmp[0] = row;
Index: mln/make/dpoint3d.hh
--- mln/make/dpoint3d.hh (revision 2153)
+++ mln/make/dpoint3d.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -50,13 +50,13 @@
*
* \return A 3D dpoint.
*/
- mln::dpoint3d dpoint3d(int sli, int row, int col);
+ mln::dpoint3d dpoint3d(def::coord sli, def::coord row, def::coord col);
# ifndef MLN_INCLUDE_ONLY
inline
- mln::dpoint3d dpoint3d(int sli, int row, int col)
+ mln::dpoint3d dpoint3d(def::coord sli, def::coord row, def::coord col)
{
mln::dpoint3d tmp;
tmp[0] = sli;
Index: mln/make/box1d.hh
--- mln/make/box1d.hh (revision 2153)
+++ mln/make/box1d.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -45,7 +45,7 @@
/*! \brief Create an mln::box1d.
*
- * \param[in] ninds Number of inds.
+ * \param[in] ninds Number of indices.
*
* \pre \p ninds != 0 and \p ncols != 0.
*
@@ -58,14 +58,14 @@
*
* \overload
*
- * \param[in] min_ind Index of the top most ind.
- * \param[in] max_ind Index of the botton most ind.
+ * \param[in] min_ind Minimum index.
+ * \param[in] max_ind Maximum index.
*
* \pre \p max_ind >= \p min_ind.
*
* \return A 1D box.
*/
- mln::box1d box1d(int min_ind, int max_ind);
+ mln::box1d box1d(def::coord min_ind, def::coord max_ind);
# ifndef MLN_INCLUDE_ONLY
@@ -80,7 +80,7 @@
}
inline
- mln::box1d box1d(int min_ind, int max_ind)
+ mln::box1d box1d(def::coord min_ind, def::coord max_ind)
{
mln_precondition(max_ind >= min_ind);
mln::box1d tmp(make::point1d(min_ind),
Index: mln/make/box2d.hh
--- mln/make/box2d.hh (revision 2153)
+++ mln/make/box2d.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -68,8 +68,8 @@
*
* \return A 2D box.
*/
- mln::box2d box2d(int min_row, int min_col,
- int max_row, int max_col);
+ mln::box2d box2d(def::coord min_row, def::coord min_col,
+ def::coord max_row, def::coord max_col);
# ifndef MLN_INCLUDE_ONLY
@@ -84,8 +84,8 @@
}
inline
- mln::box2d box2d(int min_row, int min_col,
- int max_row, int max_col)
+ mln::box2d box2d(def::coord min_row, def::coord min_col,
+ def::coord max_row, def::coord max_col)
{
mln_precondition(max_row >= min_row && max_col >= min_col);
mln::box2d tmp(make::point2d(min_row, min_col),
Index: mln/make/point1d.hh
--- mln/make/point1d.hh (revision 2153)
+++ mln/make/point1d.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -48,13 +48,13 @@
*
* \return A 1D point.
*/
- mln::point1d point1d(int ind);
+ mln::point1d point1d(def::coord ind);
# ifndef MLN_INCLUDE_ONLY
inline
- mln::point1d point1d(int ind)
+ mln::point1d point1d(def::coord ind)
{
mln::point1d tmp;
tmp[0] = ind;
Index: mln/make/point2d.hh
--- mln/make/point2d.hh (revision 2153)
+++ mln/make/point2d.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -49,13 +49,13 @@
*
* \return A 2D point.
*/
- mln::point2d point2d(int row, int col);
+ mln::point2d point2d(def::coord row, def::coord col);
# ifndef MLN_INCLUDE_ONLY
inline
- mln::point2d point2d(int row, int col)
+ mln::point2d point2d(def::coord row, def::coord col)
{
mln::point2d tmp;
tmp[0] = row;
Index: mln/make/box3d.hh
--- mln/make/box3d.hh (revision 2153)
+++ mln/make/box3d.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -45,9 +45,9 @@
/*! \brief Create an mln::box3d.
*
- * \param[in] nslis Number of slis.
+ * \param[in] nslis Number of slices.
* \param[in] nrows Number of rows.
- * \param[in] ncols Number of cols.
+ * \param[in] ncols Number of columns.
*
* \pre \p ninds != 0 and \p ncols != 0 and \p nslis != 0.
*
@@ -60,12 +60,12 @@
*
* \overload
*
- * \param[in] min_sli Sliex of the top most sli.
- * \param[in] max_sli Sliex of the botton most sli.
- * \param[in] min_row Rowex of the top most row.
- * \param[in] max_row Rowex of the botton most row.
- * \param[in] min_col Colex of the top most col.
- * \param[in] max_col Colex of the botton most col.
+ * \param[in] min_sli Index of the lowest slice.
+ * \param[in] max_sli Index of the highest slice.
+ * \param[in] min_row Index of the top most row.
+ * \param[in] max_row Index of the botton most row.
+ * \param[in] min_col Index of the left most column.
+ * \param[in] max_col Index of the right most column.
*
* \pre \p max_sli >= \p min_sli.
* \pre \p max_row >= \p min_row.
@@ -73,9 +73,9 @@
*
* \return A 3D box.
*/
- mln::box3d box3d(int min_sli, int max_sli,
- int min_row, int max_row,
- int min_col, int max_col);
+ mln::box3d box3d(def::coord min_sli, def::coord max_sli,
+ def::coord min_row, def::coord max_row,
+ def::coord min_col, def::coord max_col);
# ifndef MLN_INCLUDE_ONLY
@@ -90,9 +90,9 @@
}
inline
- mln::box3d box3d(int min_sli, int max_sli,
- int min_row, int max_row,
- int min_col, int max_col)
+ mln::box3d box3d(def::coord min_sli, def::coord max_sli,
+ def::coord min_row, def::coord max_row,
+ def::coord min_col, def::coord max_col)
{
mln_precondition(max_row >= min_row && max_sli >= min_sli &&
max_col >= min_col);
mln::box3d tmp(make::point3d(min_sli, min_row, min_col),
Index: mln/make/point3d.hh
--- mln/make/point3d.hh (revision 2153)
+++ mln/make/point3d.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
@@ -50,13 +50,13 @@
*
* \return A 3D point.
*/
- mln::point3d point3d(int sli, int row, int col);
+ mln::point3d point3d(def::coord sli, def::coord row, def::coord col);
# ifndef MLN_INCLUDE_ONLY
inline
- mln::point3d point3d(int sli, int row, int col)
+ mln::point3d point3d(def::coord sli, def::coord row, def::coord col)
{
mln::point3d tmp;
tmp[0] = sli;
Index: mln/convert/to_p_run_set.hh
--- mln/convert/to_p_run_set.hh (revision 0)
+++ mln/convert/to_p_run_set.hh (revision 0)
@@ -0,0 +1,138 @@
+// Copyright (C) 2008 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 MLN_CONVERT_TO_P_RUN_SET_HH
+# define MLN_CONVERT_TO_P_RUN_SET_HH
+
+/*! \file mln/convert/to_p_run_set.hh
+ *
+ * \brief Conversions to mln::p_run_set<P>.
+ *
+ * \todo Revamp!
+ */
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/p_runs.hh>
+# include <mln/literal/zero.hh>
+
+
+
+namespace mln
+{
+
+ namespace convert
+ {
+
+
+ /// Convert a binary image \p input into a set of runs.
+ template <typename I>
+ p_run_set<mln_site(I)> to_p_run_set(const Image<I>& input);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ template <typename I>
+ p_run_set<mln_site(I)> to_p_run_set_(const I& input)
+ {
+ typedef mln_site(I) P;
+ p_run_set<P> runs;
+ mln_fwd_piter(I) p(input.domain());
+ p.start();
+ for (;;)
+ {
+ // Skip background.
+ while (p.is_valid() && input(p) == false)
+ p.next();
+ if (! p.is_valid()) // The end.
+ break;
+ mln_invariant(input(p) == true);
+ P start = p, q;
+ // Go to run end.
+ do
+ {
+ q = p;
+ p.next();
+ }
+ while (p.is_valid() && input(p) == true && p == q + right);
+ runs.insert(start, q);
+ }
+ return runs;
+ }
+
+
+ template <typename S, typename I>
+ void fill_p_run_set_(S& s, const I& input)
+ {
+ mln_value(I) O = literal::zero;
+ typedef mln_site(I) P;
+ mln_fwd_piter(I) p(input.domain());
+ p.start();
+ for (;;)
+ {
+ // Skip background.
+ while (p.is_valid() && input(p) == O)
+ p.next();
+ if (! p.is_valid()) // The end.
+ break;
+ mln_invariant(input(p) != O);
+ mln_value(I) v = input(p);
+ P start = p, q;
+ // Go to run end.
+ do
+ {
+ q = p;
+ p.next();
+ }
+ while (p.is_valid() && input(p) == v && p == q + right);
+ s.insert(v, p_run<P>(start, q));
+ }
+ }
+
+ } // end of namespace mln::convert::impl
+
+
+ template <typename I>
+ p_run_set<mln_site(I)> to_p_run_set(const Image<I>& input_)
+ {
+ const I& input = exact(input_);
+ mln_precondition(input.has_data());
+ return impl::to_p_run_set_(input);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::convert
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CONVERT_TO_P_RUN_SET_HH
Index: mln/pw/image.hh
--- mln/pw/image.hh (revision 2153)
+++ mln/pw/image.hh (working copy)
@@ -85,7 +85,7 @@
{
// misc
typedef trait::image::category::primary category;
- typedef trait::image::speed::fastest speed;
+ typedef trait::image::speed::fast speed;
typedef trait::image::size::regular size;
// value
Index: mln/geom/bbox.hh
--- mln/geom/bbox.hh (revision 2153)
+++ mln/geom/bbox.hh (working copy)
@@ -59,7 +59,7 @@
{
template <typename S>
- box<mln_site(S)> bbox_(trait::site_set::bbox::known,
+ box<mln_site(S)> bbox_(const trait::site_set::bbox::known&,
const S& pset)
{
return pset.bbox();
Index: mln/fun/v2v/inc.hh
--- mln/fun/v2v/inc.hh (revision 0)
+++ mln/fun/v2v/inc.hh (revision 0)
@@ -0,0 +1,78 @@
+// Copyright (C) 2008 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 MLN_FUN_V2V_INC_HH
+# define MLN_FUN_V2V_INC_HH
+
+/*! \file mln/fun/v2v/inc.hh
+ *
+ * \brief Incrementation function.
+ */
+
+# include <mln/fun/internal/selector.hh>
+
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ namespace v2v
+ {
+
+ // FIXME: Doc!
+
+ template <typename T>
+ struct inc
+ : fun::internal::selector_<T, T, inc<T> >::ret
+ {
+ typedef T result;
+ T operator()(const T& t) const;
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename T>
+ inline
+ T
+ inc<T>::operator()(const T& t) const
+ {
+ return t + 1;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::fun::v2v
+
+ } // end of namespace mln::fun
+
+} // end of namespace mln
+
+
+#endif // ! MLN_FUN_V2V_INC_HH
Index: mln/fun/v2v/dec.hh
--- mln/fun/v2v/dec.hh (revision 0)
+++ mln/fun/v2v/dec.hh (revision 0)
@@ -0,0 +1,78 @@
+// Copyright (C) 2008 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 MLN_FUN_V2V_DEC_HH
+# define MLN_FUN_V2V_DEC_HH
+
+/*! \file mln/fun/v2v/dec.hh
+ *
+ * \brief Decrementation function.
+ */
+
+# include <mln/fun/internal/selector.hh>
+
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ namespace v2v
+ {
+
+ // FIXME: Doc!
+
+ template <typename T>
+ struct dec
+ : fun::internal::selector_<T, T, dec<T> >::ret
+ {
+ typedef T result;
+ T operator()(const T& t) const;
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename T>
+ inline
+ T
+ dec<T>::operator()(const T& t) const
+ {
+ return t - 1;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::fun::v2v
+
+ } // end of namespace mln::fun
+
+} // end of namespace mln
+
+
+#endif // ! MLN_FUN_V2V_DEC_HH
Index: mln/morpho/gradient_elementary.hh
--- mln/morpho/gradient_elementary.hh (revision 2153)
+++ mln/morpho/gradient_elementary.hh (working copy)
@@ -38,6 +38,8 @@
# include <mln/accu/min_max.hh>
# include <mln/level/fill.hh>
+# include <mln/morpho/internal/elementary.hh>
+
namespace mln
{
@@ -67,6 +69,14 @@
namespace generic
{
+ struct f_grad {
+ template <typename A, typename V>
+ V operator()(const A& a, const V&) const
+ {
+ return a.second() - a.first();
+ }
+ };
+
template <typename I, typename N>
mln_concrete(I)
gradient_elementary_on_function(const I& input, const N& nbh)
@@ -74,18 +84,7 @@
trace::entering("morpho::impl::generic::gradient_elementary_on_function");
mln_concrete(I) output;
- initialize(output, input);
-
- accu::min_max_<mln_value(I)> m;
- mln_piter(I) p(input.domain());
- mln_niter(N) n(nbh, p);
- for_all(p)
- {
- m.take_as_init(input(p));
- for_all(n) if (input.has(n))
- m.take(input(n));
- output(p) = m.second() - m.first();
- }
+ output = internal::elementary< accu::min_max >(input, nbh, f_grad());
trace::exiting("morpho::impl::generic::gradient_elementary_on_function");
return output;
Index: mln/morpho/dilation_elementary.hh
--- mln/morpho/dilation_elementary.hh (revision 2153)
+++ mln/morpho/dilation_elementary.hh (working copy)
@@ -25,15 +25,18 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_MORPHO_DILATION_ELEMENTARY_HH
-# define MLN_MORPHO_DILATION_ELEMENTARY_HH
+#ifndef MLN_MORPHO_GRADIENT_ELEMENTARY_HH
+# define MLN_MORPHO_GRADIENT_ELEMENTARY_HH
-/// \file mln/morpho/dilation_elementary.hh
-/// \brief Morphological elementary dilation.
+/// \file mln/morpho/gradient_elementary.hh
+/// \brief Morphological elementary gradient.
///
-/// \todo Write specific code.
+/// \todo Handle border + add fastest versions.
-# include <mln/morpho/dilation.hh>
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/accu/min_max.hh>
+# include <mln/level/fill.hh>
namespace mln
@@ -42,7 +45,7 @@
namespace morpho
{
- /// Morphological elementary dilation.
+ /// Morphological elementary gradient.
///
/// \param[in] input The image to be dilated.
/// \param[in] nbh The neighborhood to consider.
@@ -52,23 +55,123 @@
/// \{
template <typename I, typename N>
mln_concrete(I)
- dilation_elementary(const Image<I>& input, const Neighborhood<N>&
nbh);
+ gradient_elementary(const Image<I>& input, const Neighborhood<N>&
nbh);
/// \}
# ifndef MLN_INCLUDE_ONLY
+ namespace impl
+ {
+
+ namespace generic
+ {
+
+ template <typename I, typename N>
+ mln_concrete(I)
+ gradient_elementary_on_function(const I& input, const N& nbh)
+ {
+ trace::entering("morpho::impl::generic::gradient_elementary_on_function");
+
+ mln_concrete(I) output;
+ initialize(output, input);
+
+ accu::min_max_<mln_value(I)> m;
+ mln_piter(I) p(input.domain());
+ mln_niter(N) n(nbh, p);
+ for_all(p)
+ {
+ m.take_as_init(input(p));
+ for_all(n) if (input.has(n))
+ m.take(input(n));
+ output(p) = m.second() - m.first();
+ }
+
+ trace::exiting("morpho::impl::generic::gradient_elementary_on_function");
+ return output;
+ }
+
template <typename I, typename N>
mln_concrete(I)
- dilation_elementary(const Image<I>& input, const Neighborhood<N>&
nbh)
+ gradient_elementary_on_set(const I& input, const N& nbh)
+ {
+ trace::entering("morpho::impl::generic::gradient_elementary_on_set");
+
+ mln_concrete(I) output;
+ initialize(output, input);
+ level::fill(output, false);
+
+ mln_piter(I) p(input.domain());
+ mln_niter(N) n(nbh, p);
+ for_all(p)
{
- trace::entering("morpho::dilation_elementary");
- mln_precondition(exact(input).has_data());
- // FIXME: mln_precondition(! exact(nbh).is_empty());
+ bool b = input(p);
+ for_all(n) if (input.has(n))
+ if (input(n) != b)
+ {
+ output(p) = true;
+ break;
+ }
+ }
+
+ trace::exiting("morpho::impl::generic::gradient_elementary_on_set");
+ return output;
+ }
+
+ } // end of namespace mln::impl::generic
+
+
+ // Different cases.
+
+ template <typename I, typename N>
+ mln_concrete(I)
+ gradient_elementary_(const mln::trait::image::kind::any&,
+ const mln::trait::image::speed::any&,
+ const I& input, const N& nbh)
+ {
+ return generic::gradient_elementary_on_function(input, nbh);
+ }
+
+ template <typename I, typename N>
+ mln_concrete(I)
+ gradient_elementary_(const mln::trait::image::kind::logic&,
+ const mln::trait::image::speed::any&,
+ const I& input, const N& nbh)
+ {
+ return generic::gradient_elementary_on_set(input, nbh);
+ }
+
+
+ // Selector.
+
+ template <typename I, typename N>
+ mln_concrete(I)
+ gradient_elementary_(const I& input, const N& nbh)
+ {
+ return gradient_elementary_(mln_trait_image_kind(I)(),
+ mln_trait_image_speed(I)(),
+ input, nbh);
+ }
+
+ } // end of namespace mln::impl
+
+
+ // Facade.
+
+ template <typename I, typename N>
+ mln_concrete(I)
+ gradient_elementary(const Image<I>& input_, const
Neighborhood<N>& nbh_)
+ {
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+
+ trace::entering("morpho::gradient_elementary");
+ mln_precondition(input.has_data());
+ // FIXME: mln_precondition(! nbh.is_empty());
- mln_concrete(I) output = dilation(input, nbh.to_window());
+ mln_concrete(I) output = impl::gradient_elementary_(input, nbh);
- trace::exiting("morpho::dilation_elementary");
+ trace::exiting("morpho::gradient_elementary");
return output;
}
@@ -79,4 +182,4 @@
} // end of namespace mln
-#endif // ! MLN_MORPHO_DILATION_ELEMENTARY_HH
+#endif // ! MLN_MORPHO_GRADIENT_ELEMENTARY_HH
Index: mln/morpho/internal/elementary.hh
--- mln/morpho/internal/elementary.hh (revision 0)
+++ mln/morpho/internal/elementary.hh (revision 0)
@@ -0,0 +1,117 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+//
+// 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 MLN_MORPHO_INTERNAL_ELEMENTARY_HH
+# define MLN_MORPHO_INTERNAL_ELEMENTARY_HH
+
+/// \file mln/morpho/internal/elementary.hh
+/// \brief Morphological elementary operator.
+///
+/// \todo Add fastest version.
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/core/concept/accumulator.hh>
+
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+ namespace internal
+ {
+
+ /// Morphological elementary operator.
+ template <typename A, typename I, typename N, typename O>
+ mln_concrete(I)
+ elementary(const I& input, const N& nbh, O oper);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ // Different cases.
+
+ template <typename I, typename N, typename A, typename O>
+ mln_concrete(I)
+ elementary_(mln::trait::image::speed::any,
+ const I& input, const N& nbh, A accu, O oper)
+ {
+ mln_concrete(I) output;
+ initialize(output, input);
+
+ mln_piter(I) p(input.domain());
+ mln_niter(N) n(nbh, p);
+ for_all(p)
+ {
+ accu.take_as_init(input(p));
+ for_all(n) if (input.has(n))
+ accu.take(input(n));
+ output(p) = oper(accu, input(p));
+ }
+
+ return output;
+ }
+
+ // Selector.
+
+ template <typename A, typename I, typename N, typename O>
+ mln_concrete(I)
+ elementary_selector_(const I& input, const N& nbh, O oper)
+ {
+ mln_accu_with(A, mln_value(I)) accu;
+ return elementary_(mln_trait_image_speed(I)(),
+ input, nbh,
+ accu, oper);
+ }
+
+ } // end of namespace mln::morpho::internal::impl
+
+
+ // Facade.
+
+ template <typename A, typename I, typename N, typename O>
+ mln_concrete(I)
+ elementary(const I& input, const N& nbh, O oper)
+ {
+ return impl::elementary_selector_<A>(exact(input), exact(nbh), oper);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::morpho::internal
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MORPHO_INTERNAL_ELEMENTARY_HH
Index: mln/util/set.hh
--- mln/util/set.hh (revision 2153)
+++ mln/util/set.hh (working copy)
@@ -33,6 +33,8 @@
* \brief Definition of mln::util::set.
*
* \todo Clean code and test!
+ *
+ * \todo Zed: Group methods into 2 categories: when frozen, when not.
*/
# include <vector>
@@ -41,7 +43,7 @@
# include <algorithm>
# include <iostream>
-# include <mln/core/concept/object.hh>
+# include <mln/core/concept/proxy.hh>
# include <mln/util/less.hh>
@@ -51,6 +53,11 @@
namespace util
{
+ // Forward declarations.
+ template <typename T> class set_fwd_iter;
+ template <typename T> class set_bkd_iter;
+
+
/*! \brief An "efficient" mathematical set class.
*
* \internal
@@ -70,8 +77,6 @@
* The unicity of set elements is handled by the mln::util::less
* function-object.
*
- * \todo Add a remove method.
- *
* \see mln::util::less
*/
template <typename T>
@@ -79,16 +84,24 @@
{
public:
- /// Type of elements.
+ /// Element associated type.
typedef T element;
+ /// Forward iterator associated type.
+ typedef set_fwd_iter<T> fwd_iter;
+
+ /// Backward iterator associated type.
+ typedef set_bkd_iter<T> bkd_iter;
+
+ /// Iterator associated type.
+ typedef fwd_iter iter;
+
+
/*! \brief Insert an element \p elt into the set.
*
* \param[in] elt The element to be inserted.
*
- * \pre The set is not frozen.
- *
* If \p elt is already in the set, this method is a no-op.
*
* \return The set itself after insertion.
@@ -96,12 +109,20 @@
set<T>& insert(const T& elt);
+ /*! \brief Insert the elements of \p other into the set.
+ *
+ * \param[in] other The set containing the elements to be inserted.
+ *
+ * \return The set itself after insertion.
+ */
+ template <typename U>
+ set<T>& insert(const set<U>& other);
+
+
/*! \brief Remove an element \p elt into the set.
*
* \param[in] elt The element to be inserted.
*
- * \pre The set is not frozen.
- *
* If \p elt is already in the set, this method is a no-op.
*
* \return The set itself after suppression.
@@ -114,8 +135,6 @@
* All elements contained in the set are destroyed so the set is
* emptied.
*
- * \pre The set is not frozen.
- *
* \post is_empty() == true
*/
void clear();
@@ -142,6 +161,14 @@
*/
const T& operator[](unsigned i) const;
+ /// Return the first element of the set.
+ /// \pre not is_empty()
+ const T first_element() const;
+
+ /// Return the last element of the set.
+ /// \pre not is_empty()
+ const T last_element() const;
+
/*! \brief Test if the object \p elt belongs to the set.
*
@@ -160,13 +187,19 @@
*
* \return An array (std::vector) of elements.
*/
- const std::vector<T>& vect() const;
+ const std::vector<T>& std_vector() const;
/// Constructor without arguments.
set();
+ /// Return the size of this set in memory.
+ std::size_t memory_size() const;
+
+ /// Test if the set is frozen.
+ bool is_frozen_() const;
+
private:
/*! \brief Array of elements.
@@ -194,6 +227,11 @@
/// Tell if the set is frozen.
mutable bool frozen_;
+
+
+ // Used in method has(elt) when v_ holds data.
+ bool v_has_(const T& elt) const;
+ unsigned dicho_(const T& elt, unsigned beg, unsigned end) const;
};
@@ -210,8 +248,103 @@
+ // set_fwd_iter<T>
+
+ template <typename T>
+ class set_fwd_iter : public Proxy< set_fwd_iter<T> >,
+ public mln::internal::proxy_impl< const T&, set_fwd_iter<T> >
+ {
+ public:
+
+ /// Constructor without argument.
+ set_fwd_iter();
+
+ /// Constructor from a set \p s.
+ set_fwd_iter(const set<T>& s);
+
+ /// Change the set it iterates on to \p s.
+ void change_target(const set<T>& s);
+
+ /// Start an iteration.
+ void start();
+
+ /// Go to the next element.
+ void next();
+
+ /// Returns true if the iterator is valid.
+ bool is_valid() const;
+
+ /// Invalidate the iterator.
+ void invalidate();
+
+ /// Give the element the iterator designates.
+ const T& element() const;
+
+ // As a Proxy.
+ const T& subj_();
+
+ /// Give the current index.
+ unsigned index_() const;
+
+ protected:
+ unsigned i_;
+ const set<T>* s_;
+ };
+
+
+
+
+ // set_bkd_iter<T>
+
+ template <typename T>
+ class set_bkd_iter : public Proxy< set_bkd_iter<T> >,
+ public mln::internal::proxy_impl< const T&, set_bkd_iter<T> >
+ {
+ public:
+
+ /// Constructor without argument.
+ set_bkd_iter();
+
+ /// Constructor from a set \p s.
+ set_bkd_iter(const set<T>& s);
+
+ /// Change the set it iterates on to \p s.
+ void change_target(const set<T>& s);
+
+ /// Start an iteration.
+ void start();
+
+ /// Go to the next element.
+ void next();
+
+ /// Returns true if the iterator is valid.
+ bool is_valid() const;
+
+ /// Invalidate the iterator.
+ void invalidate();
+
+ /// Give the element the iterator designates.
+ const T& element() const;
+
+ // As a Proxy.
+ const T& subj_();
+
+ /// Give the current index.
+ unsigned index_() const;
+
+ protected:
+ unsigned i_;
+ const set<T>* s_;
+ };
+
+
+
# ifndef MLN_INCLUDE_ONLY
+
+ // util::set<T>
+
+
template <typename T>
inline
set<T>::set()
@@ -230,6 +363,20 @@
}
template <typename T>
+ template <typename U>
+ inline
+ set<T>&
+ set<T>::insert(const set<U>& other)
+ {
+ if (other.is_empty())
+ // No-op.
+ return *this;
+ if (frozen_) unfreeze_();
+ s_.insert(other.std_vector().begin(), other.std_vector().end());
+ return *this;
+ }
+
+ template <typename T>
inline
set<T>&
set<T>::remove(const T& elt)
@@ -278,12 +425,28 @@
template <typename T>
inline
+ const T
+ set<T>::first_element() const
+ {
+ mln_precondition(! is_empty());
+ return frozen_ ? *v_.begin() : *s_.begin();
+ }
+
+ template <typename T>
+ inline
+ const T
+ set<T>::last_element() const
+ {
+ mln_precondition(! is_empty());
+ return frozen_ ? *v_.rbegin() : *s_.rbegin();
+ }
+
+ template <typename T>
+ inline
bool
set<T>::has(const T& elt) const
{
- return frozen_
- ? std::find(v_.begin(), v_.end(), elt) != v_.end()
- : s_.find(elt) != s_.end();
+ return frozen_ ? v_has_(elt) : s_.find(elt) != s_.end();
}
template <typename T>
@@ -297,7 +460,7 @@
template <typename T>
inline
const std::vector<T>&
- set<T>::vect() const
+ set<T>::std_vector() const
{
if (! frozen_) freeze_();
return v_;
@@ -328,14 +491,246 @@
}
template <typename T>
+ inline
+ std::size_t
+ set<T>::memory_size() const
+ {
+ return nelements() * sizeof(T);
+ }
+
+ template <typename T>
+ inline
+ bool
+ set<T>::is_frozen_() const
+ {
+ return frozen_;
+ }
+
+ template <typename T>
+ inline
+ bool
+ set<T>::v_has_(const T& elt) const
+ {
+ mln_precondition(frozen_);
+ if (is_empty() || op_less(elt, v_[0]) || op_less(v_[nelements() - 1], elt))
+ return false;
+ return v_[dicho_(elt, 0, nelements())] == elt;
+ }
+
+ template <typename T>
+ inline
+ unsigned
+ set<T>::dicho_(const T& elt, unsigned beg, unsigned end) const
+ {
+ mln_precondition(frozen_);
+ mln_precondition(beg <= end);
+ if (end - beg <= 1)
+ return beg;
+ unsigned med = (beg + end) / 2;
+ return op_less(elt, v_[med]) ? dicho_(elt, beg, med) : dicho_(elt, med, end);
+ }
+
+
+
+ // util::set_fwd_iter<T>
+
+
+ template <typename T>
+ inline
+ set_fwd_iter<T>::set_fwd_iter()
+ {
+ s_ = 0;
+ }
+
+ template <typename T>
+ inline
+ set_fwd_iter<T>::set_fwd_iter(const set<T>& s)
+ {
+ change_target(s);
+ }
+
+ template <typename T>
+ inline
+ void
+ set_fwd_iter<T>::change_target(const set<T>& s)
+ {
+ s_ = &s;
+ invalidate();
+ }
+
+ template <typename T>
+ inline
+ void
+ set_fwd_iter<T>::start()
+ {
+ mln_precondition(s_ != 0);
+ i_ = 0;
+ }
+
+ template <typename T>
+ inline
+ void
+ set_fwd_iter<T>::next()
+ {
+ mln_precondition(is_valid());
+ ++i_;
+ }
+
+ template <typename T>
+ inline
+ bool
+ set_fwd_iter<T>::is_valid() const
+ {
+ return s_ != 0 && i_ != s_->nelements();
+ }
+
+ template <typename T>
+ inline
+ void
+ set_fwd_iter<T>::invalidate()
+ {
+ if (s_ != 0)
+ i_ = s_->nelements();
+ mln_postcondition(! is_valid());
+ }
+
+ template <typename T>
+ inline
+ const T&
+ set_fwd_iter<T>::element() const
+ {
+ mln_precondition(is_valid());
+ return s_->operator[](i_);
+ }
+
+ template <typename T>
+ inline
+ const T&
+ set_fwd_iter<T>::subj_()
+ {
+ mln_precondition(is_valid());
+ return s_->operator[](i_);
+ }
+
+ template <typename T>
+ inline
+ unsigned
+ set_fwd_iter<T>::index_() const
+ {
+ return i_;
+ }
+
+
+
+ // util::set_bkd_iter<T>
+
+
+ template <typename T>
+ inline
+ set_bkd_iter<T>::set_bkd_iter()
+ {
+ s_ = 0;
+ }
+
+ template <typename T>
+ inline
+ set_bkd_iter<T>::set_bkd_iter(const set<T>& s)
+ {
+ change_target(s);
+ }
+
+ template <typename T>
+ inline
+ void
+ set_bkd_iter<T>::change_target(const set<T>& s)
+ {
+ s_ = &s;
+ invalidate();
+ }
+
+ template <typename T>
+ inline
+ void
+ set_bkd_iter<T>::start()
+ {
+ mln_precondition(s_ != 0);
+ if (! s_->is_empty())
+ i_ = s_->nelements() - 1;
+ }
+
+ template <typename T>
+ inline
+ void
+ set_bkd_iter<T>::next()
+ {
+ mln_precondition(is_valid());
+ if (i_ == 0)
+ invalidate();
+ else
+ --i_;
+ }
+
+ template <typename T>
+ inline
+ bool
+ set_bkd_iter<T>::is_valid() const
+ {
+ return s_ != 0 && i_ != s_->nelements();
+ }
+
+ template <typename T>
+ inline
+ void
+ set_bkd_iter<T>::invalidate()
+ {
+ if (s_ != 0)
+ i_ = s_->nelements();
+ mln_postcondition(! is_valid());
+ }
+
+ template <typename T>
+ inline
+ const T&
+ set_bkd_iter<T>::element() const
+ {
+ mln_precondition(is_valid());
+ return s_->operator[](i_);
+ }
+
+ template <typename T>
+ inline
+ const T&
+ set_bkd_iter<T>::subj_()
+ {
+ mln_precondition(is_valid());
+ return s_->operator[](i_);
+ }
+
+ template <typename T>
+ inline
+ unsigned
+ set_bkd_iter<T>::index_() const
+ {
+ return i_;
+ }
+
+
+
+ // Operators.
+
+ template <typename T>
std::ostream& operator<<(std::ostream& ostr,
const mln::util::set<T>& s)
{
- ostr << '[';
+ ostr << '{';
const unsigned n = s.nelements();
for (unsigned i = 0; i < n; ++i)
- ostr << s[i]
- << (i == n - 1 ? ']' : ',');
+ {
+ ostr << s[i];
+ if (i != n - 1)
+ ostr << ", ";
+ }
+ ostr << '}';
return ostr;
}
Index: mln/util/yes.hh
--- mln/util/yes.hh (revision 2153)
+++ mln/util/yes.hh (working copy)
@@ -59,6 +59,12 @@
typedef util::yes ret;
};
+ template <template<class, class> class Op>
+ struct set_precise_binary_< Op, util::yes, util::yes >
+ {
+ typedef util::yes ret;
+ };
+
} // end of namespace mln::trait
@@ -83,9 +89,11 @@
// Equal.
util::yes operator == (const util::yes&, bool);
+ util::yes operator == (const util::yes&, const util::yes&);
// Not equal.
util::yes operator != (const util::yes&, bool);
+ util::yes operator != (const util::yes&, const util::yes&);
// And.
util::yes operator && (const util::yes&, bool);
@@ -136,12 +144,24 @@
}
inline
+ util::yes operator == (const util::yes&, const util::yes&)
+ {
+ return util::yes(true);
+ }
+
+ inline
util::yes operator != (const util::yes&, bool)
{
return util::yes(true);
}
inline
+ util::yes operator != (const util::yes&, const util::yes&)
+ {
+ return util::yes(true);
+ }
+
+ inline
util::yes operator && (const util::yes&, bool)
{
return util::yes(true);
Index: mln/util/less.hh
--- mln/util/less.hh (revision 2153)
+++ mln/util/less.hh (working copy)
@@ -32,7 +32,11 @@
*
* \brief Definition of a "less" function-object with one type (T).
*
- * \todo Use mln_trait_op_less as return type (?)
+ * \todo Zed: Revamp:
+ * \todo - Rename as something like ordering;
+ * \todo - Use the trait mechanism;
+ * \todo - Allow more general definitions based upon a category;
+ * \todo - Add deduced operators.
*/
# include <mln/util/less_than.hh>
@@ -59,6 +63,22 @@
};
+ // FIXME!!!
+
+ bool op_less(unsigned lhs, unsigned rhs)
+ {
+ return lhs < rhs;
+ }
+
+
+ template <typename T>
+ bool op_less(const Object<T>& lhs, const Object<T>& rhs);
+
+ template <typename T>
+ bool op_less_or_equal(const Object<T>& lhs, const Object<T>&
rhs);
+
+
+
# ifndef MLN_INCLUDE_ONLY
template <typename T>
@@ -70,6 +90,21 @@
return lt_(lhs, rhs);
}
+ template <typename T>
+ inline
+ bool op_less(const Object<T>& lhs, const Object<T>& rhs)
+ {
+ static const less<T> the_ = less<T>();
+ return the_(exact(lhs), exact(rhs));
+ }
+
+ template <typename T>
+ inline
+ bool op_less_or_equal(const Object<T>& lhs, const Object<T>&
rhs)
+ {
+ return op_less(lhs, rhs) || exact(lhs) == exact(rhs);
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::util
Index: mln/util/index.hh
--- mln/util/index.hh (revision 2153)
+++ mln/util/index.hh (working copy)
@@ -33,7 +33,8 @@
* \brief Definition of an "index" type.
*
* \todo Remove coord and dim, then make window<dindex> work.
-
+ *
+ * \todo Add inheritance to Object so add operators and traits.
*/
# include <mln/core/concept/object.hh>
@@ -65,6 +66,32 @@
index_() {}
index_(int i) : i_(i) {}
+ index_<Tag>& operator++()
+ {
+ ++i_; // Pre-inc.
+ return *this;
+ }
+
+ index_<Tag> operator++(int)
+ {
+ index_<Tag> cpy(i_ + 1);
+ ++i_; // Post-inc.
+ return cpy;
+ }
+
+ index_<Tag>& operator--()
+ {
+ --i_; // Pre-dec.
+ return *this;
+ }
+
+ index_<Tag> operator--(int)
+ {
+ index_<Tag> cpy(i_ + 1);
+ --i_; // Post-dec.
+ return cpy;
+ }
+
operator int() const { return i_; }
};
Index: mln/util/array.hh
--- mln/util/array.hh (revision 0)
+++ mln/util/array.hh (revision 0)
@@ -0,0 +1,559 @@
+// Copyright (C) 2008 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 MLN_UTIL_ARRAY_HH
+# define MLN_UTIL_ARRAY_HH
+
+/*! \file mln/util/array.hh
+ *
+ * \brief Definition of mln::util::array.
+ *
+ * \todo Zed: Add a lazy removal method (based on an extra attribute
+ * std::vector<bool> has_). Then add a purge/compress method.
+ */
+
+# include <vector>
+# include <iostream>
+
+# include <mln/core/concept/proxy.hh>
+# include <mln/core/concept/iterator.hh>
+
+
+
+namespace mln
+{
+
+ namespace util
+ {
+
+ // Forward declarations.
+ template <typename T> class array_fwd_iter;
+ template <typename T> class array_bkd_iter;
+
+
+ /*! \brief A dynamic array class.
+ *
+ * \internal
+ *
+ * Elements are stored by copy. Implementation is lazy.
+ *
+ * The parameter \c T is the element type, which shall not be
+ * const-qualified.
+ */
+ template <typename T>
+ class array : public Object< mln::util::array<T> >
+ {
+ public:
+
+ /// Element associated type.
+ typedef T element;
+
+
+ /// Forward iterator associated type.
+ typedef array_fwd_iter<T> fwd_iter;
+
+ /// Backward iterator associated type.
+ typedef array_bkd_iter<T> bkd_iter;
+
+ /// Iterator associated type.
+ typedef fwd_iter iter;
+
+
+ /// Constructor without arguments.
+ array();
+
+
+ /// Reserve memory for \p n elements.
+ void reserve(unsigned n);
+
+
+ /// Add the element \p elt at the end of this array.
+ array<T>& append(const T& elt);
+
+ /// Add the elements of \p other at the end of this array.
+ template <typename U>
+ array<T>& append(const array<U>& other);
+
+
+ /// Return the number of elements of the array.
+ unsigned nelements() const;
+
+ /// Test if the array is empty.
+ bool is_empty() const;
+
+
+ /// \brief Return the \p i-th element of the array.
+ /// \pre i < nelements()
+ const T& operator[](unsigned i) const;
+
+ /// \brief Return the \p i-th element of the array.
+ /// \pre i < nelements()
+ T& operator[](unsigned i);
+
+
+ /// Empty the array. All elements contained in the array are
+ /// destroyed. \post is_empty() == true
+ void clear();
+
+
+ /// Return the corresponding std::vector of elements.
+ const std::vector<T>& std_vector() const;
+
+ /// Hook to the mutable std::vector of elements.
+ std::vector<T>& hook_std_vector_();
+
+ /// Return the size of this array in memory.
+ std::size_t memory_size() const;
+
+ private:
+
+ std::vector<T> v_;
+ };
+
+
+ /// Operator<<.
+ template <typename T>
+ std::ostream& operator<<(std::ostream& ostr,
+ const mln::util::array<T>& a);
+
+
+
+ // array_fwd_iter<T>
+
+ template <typename T>
+ class array_fwd_iter : public Proxy< array_fwd_iter<T> >,
+ public mln::internal::proxy_impl< const T&,
+ array_fwd_iter<T> >
+ {
+ public:
+
+ /// Constructor without argument.
+ array_fwd_iter();
+
+ /// Constructor from an array \p a.
+ array_fwd_iter(const array<T>& a);
+
+ /// Change the array it iterates on to \p a.
+ void change_target(const array<T>& a);
+
+ /// Start an iteration.
+ void start();
+
+ /// Go to the next element.
+ void next();
+
+ /// Returns true if the iterator is valid.
+ bool is_valid() const;
+
+ /// Invalidate the iterator.
+ void invalidate();
+
+ /// Give the element the iterator designates.
+ const T& element() const;
+
+ // As a Proxy.
+ const T& subj_();
+
+ /// Give the current index.
+ unsigned index_() const;
+
+ protected:
+ unsigned i_;
+ const array<T>* a_;
+ };
+
+
+
+
+ // array_bkd_iter<T>
+
+ template <typename T>
+ class array_bkd_iter : public Proxy< array_bkd_iter<T> >,
+ public mln::internal::proxy_impl< const T&,
+ array_bkd_iter<T> >
+ {
+ public:
+
+ /// Constructor without argument.
+ array_bkd_iter();
+
+ /// Constructor from an array \p a.
+ array_bkd_iter(const array<T>& a);
+
+ /// Change the array it iterates on to \p a.
+ void change_target(const array<T>& a);
+
+ /// Start an iteration.
+ void start();
+
+ /// Go to the next element.
+ void next();
+
+ /// Returns true if the iterator is valid.
+ bool is_valid() const;
+
+ /// Invalidate the iterator.
+ void invalidate();
+
+ /// Give the element the iterator designates.
+ const T& element() const;
+
+ // As a Proxy.
+ const T& subj_();
+
+ /// Give the current index.
+ unsigned index_() const;
+
+ protected:
+ unsigned i_;
+ const array<T>* a_;
+ };
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // util::array<T>
+
+
+ template <typename T>
+ inline
+ array<T>::array()
+ {
+ }
+
+ template <typename T>
+ inline
+ void
+ array<T>::reserve(unsigned n)
+ {
+ v_.reserve(n);
+ }
+
+ template <typename T>
+ inline
+ array<T>&
+ array<T>::append(const T& elt)
+ {
+ v_.push_back(elt);
+ return *this;
+ }
+
+ template <typename T>
+ template <typename U>
+ inline
+ array<T>&
+ array<T>::append(const array<U>& other)
+ {
+ if (other.is_empty())
+ // No-op.
+ return *this;
+ v_.insert(v_.end(),
+ other.std_vector().begin(), other.std_vector().end());
+ return *this;
+ }
+
+ template <typename T>
+ inline
+ void
+ array<T>::clear()
+ {
+ v_.clear();
+ mln_postcondition(is_empty());
+ }
+
+ template <typename T>
+ inline
+ unsigned
+ array<T>::nelements() const
+ {
+ return v_.size();
+ }
+
+ template <typename T>
+ inline
+ const T&
+ array<T>::operator[](unsigned i) const
+ {
+ mln_precondition(i < nelements());
+ return v_[i];
+ }
+
+ template <typename T>
+ inline
+ T&
+ array<T>::operator[](unsigned i)
+ {
+ mln_precondition(i < nelements());
+ return v_[i];
+ }
+
+ template <typename T>
+ inline
+ bool
+ array<T>::is_empty() const
+ {
+ return nelements() == 0;
+ }
+
+ template <typename T>
+ inline
+ const std::vector<T>&
+ array<T>::std_vector() const
+ {
+ return v_;
+ }
+
+ template <typename T>
+ inline
+ std::vector<T>&
+ array<T>::hook_std_vector_()
+ {
+ return v_;
+ }
+
+ template <typename T>
+ inline
+ std::size_t
+ array<T>::memory_size() const
+ {
+ return sizeof(*this) + nelements() * sizeof(T);
+ }
+
+
+
+ // util::array_fwd_iter<T>
+
+
+ template <typename T>
+ inline
+ array_fwd_iter<T>::array_fwd_iter()
+ {
+ a_ = 0;
+ }
+
+ template <typename T>
+ inline
+ array_fwd_iter<T>::array_fwd_iter(const array<T>& a)
+ {
+ change_target(a);
+ }
+
+ template <typename T>
+ inline
+ void
+ array_fwd_iter<T>::change_target(const array<T>& a)
+ {
+ a_ = &a;
+ invalidate();
+ }
+
+ template <typename T>
+ inline
+ void
+ array_fwd_iter<T>::start()
+ {
+ mln_precondition(a_ != 0);
+ i_ = 0;
+ }
+
+ template <typename T>
+ inline
+ void
+ array_fwd_iter<T>::next()
+ {
+ mln_precondition(is_valid());
+ ++i_;
+ }
+
+ template <typename T>
+ inline
+ bool
+ array_fwd_iter<T>::is_valid() const
+ {
+ return a_ != 0 && i_ != a_->nelements();
+ }
+
+ template <typename T>
+ inline
+ void
+ array_fwd_iter<T>::invalidate()
+ {
+ if (a_ != 0)
+ i_ = a_->nelements();
+ mln_postcondition(! is_valid());
+ }
+
+ template <typename T>
+ inline
+ const T&
+ array_fwd_iter<T>::element() const
+ {
+ mln_precondition(is_valid());
+ return a_->operator[](i_);
+ }
+
+ template <typename T>
+ inline
+ const T&
+ array_fwd_iter<T>::subj_()
+ {
+ mln_precondition(is_valid());
+ return a_->operator[](i_);
+ }
+
+ template <typename T>
+ inline
+ unsigned
+ array_fwd_iter<T>::index_() const
+ {
+ return i_;
+ }
+
+
+
+ // util::array_bkd_iter<T>
+
+
+ template <typename T>
+ inline
+ array_bkd_iter<T>::array_bkd_iter()
+ {
+ a_ = 0;
+ }
+
+ template <typename T>
+ inline
+ array_bkd_iter<T>::array_bkd_iter(const array<T>& a)
+ {
+ change_target(a);
+ }
+
+ template <typename T>
+ inline
+ void
+ array_bkd_iter<T>::change_target(const array<T>& a)
+ {
+ a_ = &a;
+ invalidate();
+ }
+
+ template <typename T>
+ inline
+ void
+ array_bkd_iter<T>::start()
+ {
+ mln_precondition(a_ != 0);
+ if (! a_->is_empty())
+ i_ = a_->nelements() - 1;
+ }
+
+ template <typename T>
+ inline
+ void
+ array_bkd_iter<T>::next()
+ {
+ mln_precondition(is_valid());
+ if (i_ == 0)
+ invalidate();
+ else
+ --i_;
+ }
+
+ template <typename T>
+ inline
+ bool
+ array_bkd_iter<T>::is_valid() const
+ {
+ return a_ != 0 && i_ != a_->nelements();
+ }
+
+ template <typename T>
+ inline
+ void
+ array_bkd_iter<T>::invalidate()
+ {
+ if (a_ != 0)
+ i_ = a_->nelements();
+ mln_postcondition(! is_valid());
+ }
+
+ template <typename T>
+ inline
+ const T&
+ array_bkd_iter<T>::element() const
+ {
+ mln_precondition(is_valid());
+ return a_->operator[](i_);
+ }
+
+ template <typename T>
+ inline
+ const T&
+ array_bkd_iter<T>::subj_()
+ {
+ mln_precondition(is_valid());
+ return a_->operator[](i_);
+ }
+
+ template <typename T>
+ inline
+ unsigned
+ array_bkd_iter<T>::index_() const
+ {
+ return i_;
+ }
+
+
+
+ // Operator <<.
+
+ template <typename T>
+ std::ostream& operator<<(std::ostream& ostr,
+ const mln::util::array<T>& a)
+ {
+ ostr << '[';
+ const unsigned n = a.nelements();
+ for (unsigned i = 0; i < n; ++i)
+ {
+ ostr << a[i];
+ if (i != n - 1)
+ ostr << ", ";
+ }
+ ostr << ']';
+ return ostr;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::util
+
+} // end of namespace mln
+
+
+#endif // ! MLN_UTIL_ARRAY_HH
Index: mln/util/timer.hh
--- mln/util/timer.hh (revision 0)
+++ mln/util/timer.hh (revision 0)
@@ -0,0 +1,181 @@
+// Copyright (C) 2008 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 MLN_UTIL_TIMER_HH
+# define MLN_UTIL_TIMER_HH
+
+/*! \file mln/util/timer.hh
+ *
+ * \brief Definition of a timer.
+ */
+
+# include <mln/core/concept/proxy.hh>
+# include <ctime>
+
+
+namespace mln
+{
+
+ namespace util
+ {
+
+ /*! \brief Timer structure.
+ *
+ */
+ class timer : public Proxy< timer >,
+ public internal::proxy_impl<float, timer>
+ {
+ public:
+
+ timer();
+
+ // Without impl.
+ timer(const timer&);
+ void operator=(const timer&);
+
+ ~timer();
+
+ void start();
+
+ float stop();
+
+ void resume();
+
+ void reset();
+
+ // Restart is equivalent to reset then start.
+ void restart();
+
+ float read() const;
+
+ // As a proxy:
+ float subj_();
+
+// void print() const
+// {
+// std::cout << running_ << ' '
+// << start_ << ' '
+// << std::clock() << ' '
+// << float(std::clock()) / CLOCKS_PER_SEC << ' '
+// << time_ << std::endl;
+// }
+
+ private:
+
+ bool running_;
+ float start_;
+ float time_;
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ inline
+ timer::timer()
+ {
+ reset();
+ }
+
+ inline
+ timer::~timer()
+ {
+ reset();
+ }
+
+ inline
+ void
+ timer::start()
+ {
+ mln_precondition(running_ == false);
+ start_ = float(std::clock()) / CLOCKS_PER_SEC;
+ time_ = 0;
+ running_ = true;
+ }
+
+ inline
+ float
+ timer::stop()
+ {
+ mln_precondition(running_ == true);
+ time_ += float(std::clock()) / CLOCKS_PER_SEC - start_;
+ running_ = false;
+ return time_;
+ }
+
+ inline
+ void
+ timer::resume()
+ {
+ mln_precondition(running_ == false);
+ start_ = float(std::clock()) / CLOCKS_PER_SEC;
+ running_ = true;
+ }
+
+ inline
+ void
+ timer::reset()
+ {
+ running_ = false;
+ start_ = -1;
+ time_ = 0;
+ }
+
+ inline
+ void
+ timer::restart()
+ {
+ reset();
+ start();
+ }
+
+
+ inline
+ float
+ timer::read() const
+ {
+ mln_precondition(start_ != -1);
+ return running_ ?
+ time_ + float(std::clock()) / CLOCKS_PER_SEC - start_ :
+ time_;
+ }
+
+ inline
+ float
+ timer::subj_()
+ {
+ mln_precondition(start_ != -1);
+ return read();
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::util
+
+} // end of namespace mln
+
+
+#endif // ! MLN_UTIL_TIMER_HH
Index: mln/labeling/blobs.hh
--- mln/labeling/blobs.hh (revision 2153)
+++ mln/labeling/blobs.hh (working copy)
@@ -1,4 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -60,10 +61,10 @@
* A fast queue is used so that the algorithm is not recursive and
* can handle large binary objects (blobs).
*/
- template <typename I, typename N>
- mln_ch_value(I, unsigned)
+ template <typename I, typename N, typename L>
+ mln_ch_value(I, L)
blobs(const Image<I>& input, const Neighborhood<N>& nbh,
- unsigned& nlabels);
+ L& nlabels);
# ifndef MLN_INCLUDE_ONLY
@@ -74,9 +75,9 @@
namespace generic
{
- template <typename I, typename N>
- mln_ch_value(I, unsigned)
- blobs_(const I& input, const N& nbh, unsigned& nlabels)
+ template <typename I, typename N, typename L>
+ mln_ch_value(I, L)
+ blobs_(const I& input, const N& nbh, L& nlabels)
{
typedef mln_psite(I) P;
@@ -86,7 +87,7 @@
// Initialization.
nlabels = 0;
- mln_ch_value(I, unsigned) output;
+ mln_ch_value(I, L) output;
initialize(output, input);
level::fill(output, 0);
@@ -107,7 +108,7 @@
for_all(n) if (input.has(n))
if (input(n) && ! output(n))
{
- mln_invariant(! qu.has(n));
+ mln_invariant(! qu.compute_has(n));
qu.push(n);
output(n) = nlabels;
}
@@ -121,9 +122,9 @@
} // end of namespace mln::labeling::impl::generic
- template <typename I, typename N>
- mln_ch_value(I, unsigned)
- blobs_(const I& input, const N& nbh, unsigned& nlabels)
+ template <typename I, typename N, typename L>
+ mln_ch_value(I, L)
+ blobs_(const I& input, const N& nbh, L& nlabels)
{
// The only implementation is the generic one.
return generic::blobs_(input, nbh, nlabels);
@@ -134,11 +135,11 @@
// Facade.
- template <typename I, typename N>
+ template <typename I, typename N, typename L>
inline
- mln_ch_value(I, unsigned)
+ mln_ch_value(I, L)
blobs(const Image<I>& input_, const Neighborhood<N>& nbh_,
- unsigned& nlabels)
+ L& nlabels)
{
trace::entering("labeling::blobs");
mlc_equal(mln_trait_image_kind(I),
@@ -147,7 +148,7 @@
const N& nbh = exact(nbh_);
mln_precondition(input.has_data());
- mln_ch_value(I, unsigned) output = impl::blobs_(input, nbh, nlabels);
+ mln_ch_value(I, L) output = impl::blobs_(input, nbh, nlabels);
trace::exiting("labeling::blobs");
return output;
Index: sandbox/geraud/p_runs__with_dedicated_piter.hh
--- sandbox/geraud/p_runs__with_dedicated_piter.hh (revision 0)
+++ sandbox/geraud/p_runs__with_dedicated_piter.hh (revision 0)
@@ -0,0 +1,748 @@
+// Copyright (C) 2007, 2008 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 MLN_CORE_P_RUNS_HH
+# define MLN_CORE_P_RUNS_HH
+
+/*! \file mln/core/p_runs.hh
+ *
+ * \brief Definition of a set of point runs.
+ *
+ * \todo Zed: Use p_double* stuff.
+ *
+ * \todo Zed: Test for unicity (see FIXMEs).
+ */
+
+# include <mln/accu/bbox.hh>
+# include <mln/core/p_run.hh>
+# include <mln/core/p_double.hh>
+# include <mln/core/internal/piter_adaptor.hh>
+# include <mln/util/set.hh>
+
+
+
+namespace mln
+{
+
+ // Forward declarations.
+ template <typename P> class p_runs;
+ template <typename P> class p_runs_piste;
+ template <typename P> class p_runs_fwd_piter_;
+ template <typename P> class p_runs_bkd_piter_;
+
+
+ namespace trait
+ {
+
+ template <typename P>
+ struct site_set_< p_runs<P> >
+ {
+ typedef trait::site_set::nsites::known nsites;
+ typedef trait::site_set::bbox::known bbox;
+ typedef trait::site_set::contents::growing contents;
+ typedef trait::site_set::arity::unique arity;
+ };
+
+ } // end of namespace trait
+
+
+
+ /*! \brief p_runs is a site set composed of runs.
+ *
+ * Parameter \c P is the type of the image point.
+ */
+ template <typename P>
+ class p_runs : public internal::site_set_base_< P, p_runs<P> >
+ {
+ typedef p_runs<P> self_;
+ public:
+
+ /// Element associated type.
+ typedef p_run<P> element;
+
+
+ /// Psite associated type.
+ typedef p_runs_psite<P> psite;
+
+ /// Forward Site_Iterator associated type.
+ typedef p_runs_fwd_piter_<P> fwd_piter;
+
+ /// Backward Site_Iterator associated type.
+ typedef p_runs_bkd_piter_<P> bkd_piter;
+
+ /// Site_Iterator associated type.
+ typedef fwd_piter piter;
+
+
+ /// Constructor without arguments.
+ p_runs();
+
+
+ /// Test if \p p belongs to this point set.
+ bool has(const psite&) const;
+
+ /// Test if this set of runs is valid.
+ bool is_valid() const;
+
+
+ /// Box associated type.
+ typedef const mln::box<P>& q_box;
+
+ /// Give the exact bounding box.
+ const box<P>& bbox() const;
+
+
+ /// Give the number of points.
+ unsigned nsites() const;
+
+ /// Give the number of runs.
+ unsigned nruns() const;
+
+ /// Give the compression ratio: FIXME: explain...
+ float zratio() const;
+
+
+ /// Insertion element associated type.
+ typedef p_run<P> i_element;
+
+ /// Insert a run \p r.
+ void insert(const p_run<P>& r);
+
+ /// Insert a run from \p start to \p end.
+ void insert(const P& start, const P& end);
+
+ /// Insert a run defined by \p start with length \p len.
+ void insert(const P& start, unsigned short len);
+
+ /// Insert another set of runs.
+ void insert(const p_runs<P>& other);
+
+
+ /// Return the i-th run.
+ const p_run<P>& run(unsigned i) const;
+
+ /// Return the size of this site set in memory.
+ std::size_t memory_size() const;
+
+ /// Hook to the set of runs.
+ const util::set< p_run<P> >& hook_() const;
+
+
+ protected:
+
+ /// Number of points.
+ unsigned nsites_;
+
+ /// Bounding box accumulator.
+ accu::bbox<P> b_;
+
+ /// Set of runs.
+ util::set< p_run<P> > run_;
+ };
+
+
+
+ template <typename P>
+ std::ostream& operator<<(std::ostream& ostr, const p_runs<P>&
r);
+
+
+ namespace util
+ {
+
+ template <typename P>
+ struct less< p_runs<P> >
+ {
+ bool operator()(const p_runs<P>& lhs,
+ const p_runs<P>& rhs) const;
+ };
+
+ } // end of namespace mln::util
+
+
+
+ // p_runs_psite<P>
+
+ template <typename P>
+ class p_runs_psite : public internal::pseudo_site_base_< const P&,
+ p_runs_psite<P> >
+ {
+ typedef p_runs_psite<P> self;
+ typedef internal::pseudo_site_base_<const P&, self> super;
+
+ public:
+
+ // This associated type is important to know that this particular
+ // pseudo site knows the site set it refers to.
+ typedef p_runs<P> target;
+
+ p_runs_psite();
+
+ // As a Proxy:
+ const P& subj_();
+
+ const p_runs<P>* target_() const;
+ void change_target(const p_runs<P>& new_target);
+
+ bool is_valid() const;
+
+ short index_in_run() const;
+ void set_index_in_run(short i);
+ void inc_index_in_run();
+ void dec_index_in_run();
+
+ unsigned run_index() const;
+ void goto_run_start(unsigned r);
+ void goto_run_end(unsigned r);
+
+ unsigned run_length() const;
+
+ private:
+
+ const p_runs<P>* s_;
+ unsigned r_;
+ short i_;
+ mutable P p_;
+ };
+
+
+ // p_runs_fwd_piter_
+
+ template <typename P>
+ class p_runs_fwd_piter_
+ :
+ public internal::site_set_iterator_base< p_runs<P>,
+ p_runs_fwd_piter_<P> >
+ {
+ typedef p_runs_fwd_piter_<P> self_;
+ typedef internal::site_set_iterator_base< p_runs<P>, self_ > super_;
+ public:
+
+ /// Constructor without arguments.
+ p_runs_fwd_piter_();
+
+ /// Constructor.
+ p_runs_fwd_piter_(const p_runs<P>& r);
+
+ /// Test if the iterator is valid.
+ bool is_valid_() const;
+
+ /// Invalidate the iterator.
+ void invalidate_();
+
+ /// Start an iteration.
+ void start_();
+
+ /// Go to the next point.
+ void next_();
+
+ protected:
+ using super_::p_;
+ using super_::s_;
+ unsigned short len_;
+ };
+
+
+
+ // p_runs_bkd_piter_
+
+ template <typename P>
+ class p_runs_bkd_piter_
+ :
+ public internal::site_set_iterator_base< p_runs<P>,
+ p_runs_bkd_piter_<P> >
+ {
+ typedef p_runs_bkd_piter_<P> self_;
+ typedef internal::site_set_iterator_base< p_runs<P>, self_ > super_;
+ public:
+
+ /// Constructor without arguments.
+ p_runs_bkd_piter_();
+
+ /// Constructor.
+ p_runs_bkd_piter_(const p_runs<P>& r);
+
+ /// Test if the iterator is valid.
+ bool is_valid_() const;
+
+ /// Invalidate the iterator.
+ void invalidate_();
+
+ /// Start an iteration.
+ void start_();
+
+ /// Go to the next point.
+ void next_();
+
+ protected:
+ using super_::p_;
+ using super_::s_;
+ };
+
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // p_runs
+
+ template <typename P>
+ inline
+ p_runs<P>::p_runs()
+ :
+ nsites_(0)
+ {
+ }
+
+ template <typename P>
+ inline
+ bool
+ p_runs<P>::has(const p_runs_psite<P>& p) const
+ {
+ mln_precondition(p.target_() == this); // FIXME: Refine.
+ if (p.run_index() >= nruns() ||
+ p.index_in_run() < 0 ||
+ p.index_in_run() >= run_[p.run_index()].length())
+ return false;
+ // The type of rhs below is mln_site(p_run<P>).
+ mln_invariant(p.to_site() == run_[p.run_index()][p.index_in_run()]);
+ return true;
+ }
+
+ template <typename P>
+ inline
+ bool
+ p_runs<P>::is_valid() const
+ {
+ // FIXME: A run of this set can be invalid...
+ return true;
+ }
+
+ template <typename P>
+ inline
+ const box<P>&
+ p_runs<P>::bbox() const
+ {
+ return b_.to_result();
+ }
+
+ template <typename P>
+ inline
+ unsigned
+ p_runs<P>::nsites() const
+ {
+ return nsites_;
+ }
+
+ template <typename P>
+ inline
+ void
+ p_runs<P>::insert(const p_runs<P>& other)
+ {
+ if (other.nsites() == 0)
+ // No-op.
+ return;
+ nsites_ += other.nsites();
+ b_.take(other.bbox());
+ run_.insert(other.run_);
+ }
+
+ template <typename P>
+ inline
+ void
+ p_runs<P>::insert(const p_run<P>& r)
+ {
+ nsites_ += r.nsites();
+ b_.take(r.bbox());
+ run_.insert(r);
+ }
+
+
+// Previous code of 'insert' was:
+//
+// {
+// typename std::vector<p_run<P> >::const_iterator iter =
con_.vect().begin();
+// while (iter != con_.vect().end() && iter->first() < pr.first())
+// ++iter;
+
+// if (iter != con_.vect().begin())
+// {
+// typename std::vector<p_run<P> >::const_iterator prec = iter;
+// --prec;
+// bool equal = true;
+// for (int i = P::dim - 2; i >= 0; --i)
+// if (!(equal = equal && (prec->first()[i] == pr.first()[i])))
+// break;
+// if (equal)
+// mln_assertion(prec->first()[P::dim - 1] + (signed)prec->length()
+// <= pr.first()[P::dim - 1]);
+// }
+
+// if (iter != con_.vect().end())
+// {
+// bool equal = true;
+// for (int i = P::dim - 2; i >= 0; --i)
+// if (!(equal = equal && ((*iter).first()[i] == pr.first()[i])))
+// break;
+// if (equal)
+// mln_assertion(pr.first()[P::dim - 1] + (signed)pr.length()
+// <= iter->first()[P::dim - 1]);
+// }
+// con_.insert(pr);
+
+// // update box
+// fb_.take(pr.bbox().pmin());
+// fb_.take(pr.bbox().pmax());
+// // update size
+// npoints_ += pr.npoints();
+// }
+
+
+ template <typename P>
+ inline
+ void
+ p_runs<P>::insert(const P& start, const P& end)
+ {
+ mln_precondition(cut_(end) == cut_(start));
+ mln_precondition(end.last_coord() >= start.last_coord());
+ p_run<P> r(start, end);
+ this->insert(r);
+ }
+
+ template <typename P>
+ inline
+ void
+ p_runs<P>::insert(const P& start, unsigned short len)
+ {
+ mln_precondition(len != 0);
+ p_run<P> r(start, len);
+ this->insert(r);
+ }
+
+ template <typename P>
+ inline
+ unsigned
+ p_runs<P>::nruns() const
+ {
+ return run_.nelements();
+ }
+
+ template <typename P>
+ inline
+ const p_run<P>&
+ p_runs<P>::run(unsigned i) const
+ {
+ mln_precondition(i < nruns());
+ return run_[i];
+ }
+
+ template <typename P>
+ inline
+ std::size_t
+ p_runs<P>::memory_size() const
+ {
+ return run_.memory_size() + sizeof(nsites_) + sizeof(b_);
+ }
+
+ template <typename P>
+ inline
+ float
+ p_runs<P>::zratio() const
+ {
+ return
+ float(memory_size()) /
+ float(b_.to_result().nsites() * sizeof(P));
+ }
+
+ template <typename P>
+ inline
+ const util::set< p_run<P> >&
+ p_runs<P>::hook_() const
+ {
+ return run_;
+ }
+
+
+ template <typename P>
+ std::ostream& operator<<(std::ostream& ostr, const p_runs<P>&
r)
+ {
+ return ostr << r.hook_();
+ }
+
+
+ namespace util
+ {
+
+ template <typename P>
+ inline
+ bool
+ less< p_runs<P> >::operator()(const p_runs<P>& lhs,
+ const p_runs<P>& rhs) const
+ {
+ return op_less(lhs.run(0), rhs.run(0));
+ }
+
+ } // end of namespace mln::util
+
+
+
+ // p_runs_psite<P>
+
+ template <typename P>
+ inline
+ p_runs_psite<P>::p_runs_psite()
+ {
+ s_ = 0;
+ }
+
+ template <typename P>
+ inline
+ const P&
+ p_runs_psite<P>::subj_()
+ {
+ return p_;
+ }
+
+ template <typename P>
+ inline
+ const p_runs<P>*
+ p_runs_psite<P>::target_() const
+ {
+ return s_;
+ }
+
+ template <typename P>
+ inline
+ void
+ p_runs_psite<P>::change_target(const p_runs<P>& new_target)
+ {
+ s_ = & new_target;
+ goto_run_start(0);
+ }
+
+ template <typename P>
+ inline
+ bool
+ p_runs_psite<P>::is_valid() const
+ {
+ return
+ s_ != 0 &&
+ r_ < s_->nruns() &&
+ i_ >= 0 && i_ < s_->run(r_).length();
+ }
+
+ template <typename P>
+ inline
+ short
+ p_runs_psite<P>::index_in_run() const
+ {
+ return i_;
+ }
+
+ template <typename P>
+ inline
+ void
+ p_runs_psite<P>::set_index_in_run(short i)
+ {
+ p_.last_coord() += (i - i_);
+ i_ = i;
+ }
+
+ template <typename P>
+ inline
+ void
+ p_runs_psite<P>::inc_index_in_run()
+ {
+ ++i_;
+ p_.last_coord() += 1;
+ }
+
+ template <typename P>
+ inline
+ void
+ p_runs_psite<P>::dec_index_in_run()
+ {
+ --i_;
+ p_.last_coord() -= 1;
+ }
+
+ template <typename P>
+ inline
+ unsigned
+ p_runs_psite<P>::run_index() const
+ {
+ return r_;
+ }
+
+ template <typename P>
+ inline
+ void
+ p_runs_psite<P>::goto_run_start(unsigned r)
+ {
+ r_ = r;
+ if (r_ < s_->nruns())
+ {
+ i_ = 0;
+ p_ = s_->run(r).start();
+ }
+ }
+
+ template <typename P>
+ inline
+ void
+ p_runs_psite<P>::goto_run_end(unsigned r)
+ {
+ r_ = r;
+ if (r_ < s_->nruns())
+ {
+ i_ = s_->run(r).length() - 1;
+ p_ = s_->run(r).end();
+ }
+ }
+
+ template <typename P>
+ inline
+ unsigned
+ p_runs_psite<P>::run_length() const
+ {
+ if (s_ == 0 || r_ >= s_->nruns())
+ return 0;
+ else
+ return s_->run(r_).length();
+ }
+
+
+ // p_runs_fwd_piter_<P>
+
+ template <typename P>
+ inline
+ p_runs_fwd_piter_<P>::p_runs_fwd_piter_()
+ {
+ }
+
+ template <typename P>
+ inline
+ p_runs_fwd_piter_<P>::p_runs_fwd_piter_(const p_runs<P>& r)
+ {
+ this->change_target(r);
+ }
+
+ template <typename P>
+ inline
+ bool
+ p_runs_fwd_piter_<P>::is_valid_() const
+ {
+ return len_ != 0;
+ }
+
+ template <typename P>
+ inline
+ void
+ p_runs_fwd_piter_<P>::invalidate_()
+ {
+ len_ = 0;
+ }
+
+ template <typename P>
+ inline
+ void
+ p_runs_fwd_piter_<P>::start_()
+ {
+ p_.goto_run_start(0);
+ len_ = p_.run_length();
+ }
+
+ template <typename P>
+ inline
+ void
+ p_runs_fwd_piter_<P>::next_()
+ {
+ p_.inc_index_in_run();
+ if (p_.index_in_run() == short(len_))
+ {
+ p_.goto_run_start(p_.run_index() + 1);
+ len_ = p_.run_length();
+ // len_ is null when p_ is invalid.
+ }
+ }
+
+
+ // p_runs_bkd_piter_<P>
+
+ template <typename P>
+ inline
+ p_runs_bkd_piter_<P>::p_runs_bkd_piter_()
+ {
+ }
+
+ template <typename P>
+ inline
+ p_runs_bkd_piter_<P>::p_runs_bkd_piter_(const p_runs<P>& r)
+ {
+ this->change_target(r);
+ }
+
+ template <typename P>
+ inline
+ bool
+ p_runs_bkd_piter_<P>::is_valid_() const
+ {
+ return p_.index_in_run() != -1;
+ }
+
+ template <typename P>
+ inline
+ void
+ p_runs_bkd_piter_<P>::invalidate_()
+ {
+ p_.set_index_in_run(-1);
+ }
+
+ template <typename P>
+ inline
+ void
+ p_runs_bkd_piter_<P>::start_()
+ {
+ p_.goto_run_end(s_->nruns() - 1);
+ }
+
+ template <typename P>
+ inline
+ void
+ p_runs_bkd_piter_<P>::next_()
+ {
+ p_.dec_index_in_run();
+ if (p_.index_in_run() == -1)
+ p_.goto_run_end(p_.run_index() - 1);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_P_RUNS_HH