octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

stem series objects


From: David Bateman
Subject: stem series objects
Date: Sun, 24 Aug 2008 00:10:09 +0200
User-agent: Thunderbird 2.0.0.16 (X11/20080725)

Now that Michael and Shai have added listeners, hggroups and the ability to add properties dynamically to objects we should use these abilities to make stem, bar, contour series objects and use the callback capability of the listeners to fix the plotyy function, and I think this should be done before 3.2 is released. With that in mind find attached a changeset that adds the stem series objects that I used as a test case to try and see how all this stuffed worked. So Michael/Shai, please have a look at this and see if there is anything I missed in the implementation of this function.

The patch also addresses three issues in the current graphics code that I noticed.

* In __go_draw_axes__.m respect the "visible" property of graphics objects and don't draw objects that aren't visible
* Fix an off by one error in gh_manager::do_execute_callback
* In the graphics base property class add a caseless comparison functor and use it in the property map to ensure that the get/set functions find properties in a case insensitive manner.

Regards
David
# HG changeset patch
# User David Bateman <address@hidden>
# Date 1219528612 -7200
# Node ID 6373ce5f378928a5196fd5d82c902083dc4dca10
# Parent  1c1ccdca06bba063615ddae50b275c26807bb081
Convert stem and stem3 to use stem series objects

diff --git a/scripts/ChangeLog b/scripts/ChangeLog
--- a/scripts/ChangeLog
+++ b/scripts/ChangeLog
@@ -1,3 +1,13 @@ 2008-08-20  David Bateman  <address@hidden
+2008-08-23  David Bateman  <address@hidden>
+
+       * __go_draw_axes__.m: Respect the "visible" property of object and
+       don't draw them if the object is not visible.
+
+       * __stem__.m: Convert to use stem series object.
+       * stem.m, stem3.m: Update documentation to correpsond to the stem
+       series usage.
+
+
 2008-08-20  David Bateman  <address@hidden>
 
        * plot/ezplot.m : New function.
diff --git a/scripts/plot/__go_draw_axes__.m b/scripts/plot/__go_draw_axes__.m
--- a/scripts/plot/__go_draw_axes__.m
+++ b/scripts/plot/__go_draw_axes__.m
@@ -330,6 +330,10 @@ function __go_draw_axes__ (h, plot_strea
 
       obj = get (kids(1));
       kids = kids(2:end);
+
+      if (strcmp (obj.visible, "off"))
+       continue;
+      endif
 
       switch (obj.type)
        case "image"
diff --git a/scripts/plot/__stem__.m b/scripts/plot/__stem__.m
--- a/scripts/plot/__stem__.m
+++ b/scripts/plot/__stem__.m
@@ -31,54 +31,122 @@ function h = __stem__ (have_z, varargin)
 
   [ax, varargin, nargin] = __plt_get_axis_arg__ (caller, varargin{:});
 
-  [x, y, z, dofill, lc, ls, mc, ms] = check_stem_arg (have_z, varargin{:});
-
-  if (dofill)
-    fc = mc;
-  else
-    fc = "none";
-  endif
-
-  newplot ();
-  nx = numel (x);
-  xt = x(:)';
-  xt = [xt; xt; NaN(1, nx)](:);
-  if (have_z)
-    yt = y(:)';
-    yt = [yt; yt; NaN(1, nx)](:);
-    zt = z(:)';
-    zt = [zeros(1, nx); zt; NaN(1, nx)](:);
-  else
-    yt = y(:)';
-    yt = [zeros(1, nx); yt; NaN(1, nx)](:);
-  endif
+  [x, y, z, dofill, llc, ls, mmc, ms] = check_stem_arg (have_z, varargin{:});
 
   oldax = gca ();
   unwind_protect
     axes (ax);
-
-    if (have_z)
-      h_stems = plot3 (xt, yt, zt, "color", lc, "linestyle", ls,
-                     x, y, z, "color", mc, "marker", ms, "linestyle", "",
-                     "markerfacecolor", fc);
-
-      h_baseline = [];
-    else
-      h_stems = plot (xt, yt, "color", lc, "linestyle", ls,
-                     x, y, "color", mc, "marker", ms, "linestyle", "",
-                     "markerfacecolor", fc);
-
-      ## Must draw the plot first to get proper x limits.
-      drawnow();
-      x_axis_range = get (gca, "xlim");
-      h_baseline = line (x_axis_range, [0, 0], "color", [0, 0, 0]);
-    endif
+    hold_state = get (ax, "nextplot");
+    newplot ();
+    h = [];
+
+    nx = rows (x);
+    for i = 1: columns (x)
+      if (have_z)
+       xt = x(:)';
+       xt = [xt; xt; NaN(1, nx)](:);
+       yt = y(:)';
+       yt = [yt; yt; NaN(1, nx)](:);
+       zt = z(:)';
+       zt = [zeros(1, nx); zt; NaN(1, nx)](:);
+      else
+       xt = x(:, i)';
+       xt = [xt; xt; NaN(1, nx)](:);
+       yt = y(:, i)';
+       yt = [zeros(1, nx); yt; NaN(1, nx)](:);
+      endif
+
+      hg  = hggroup ();
+      h = [h; hg];
+      if (i == 1)
+       set (ax, "nextplot", "add");
+      endif
+
+      if (isempty (llc))
+       lc = __next_line_color__ ();
+      else
+       lc = llc;
+      endif
+
+      if (isempty (mmc))
+       mc = lc;
+      else
+       mc = mmc;
+      endif
+
+      if (dofill)
+       fc = mc;
+      else
+       fc = "none";
+      endif
+
+      if (have_z)
+       h_stems = plot3 (xt, yt, zt, "color", lc, "linestyle", ls, 
+                        "parent", hg, x, y, z, "color", mc,
+                        "marker",  ms, "linestyle", "none",
+                        "markerfacecolor", fc, "parent", hg);
+
+       h_baseline = [];
+      else
+       h_stems = plot (xt, yt, "color", lc, "linestyle", ls,
+                       "parent", hg, x(:,i), y(:, i), "color", mc, "marker",
+                       ms, "linestyle", "none", "markerfacecolor",
+                       fc, "parent", hg); 
+
+       if (i == 1)
+         ## Must draw the plot first to get proper x limits for the baseline.
+         drawnow();
+         x_axis_range = get (ax, "xlim");
+         h_baseline = line (x_axis_range, [0, 0], "color", [0, 0, 0]);
+         set (h_baseline, "handlevisibility", "off");
+         addlistener (ax, "xlim", @update_xlim);
+         addlistener (h_baseline, "ydata", @update_baseline);
+         addlistener (h_baseline, "visible", @update_baseline);
+       endif
+      endif
+
+      ## Setup the hggroup and listeners
+      addproperty ("showbaseline", hg, "radio", "{on}|off");
+      addproperty ("basevalue", hg, "data", 0);
+      addproperty ("baseline", hg, "data", h_baseline);
+
+      if (!have_z)
+       addlistener (hg, "showbaseline", @show_baseline);
+       addlistener (hg, "basevalue", @move_baseline); 
+      endif
+
+      addproperty ("color", hg, "color", lc);
+      addproperty ("linewidth", hg, "double", 0.5);
+      addproperty ("linestyle", hg, "radio", "{-}|--|:|-.|none");
+      addproperty ("marker", hg, "radio", 
+                  "{none}|s|o|x|+|.|*|<|>|v|^|d|p|h", "o");
+      addproperty ("markerfacecolor", hg, "color", fc, "{none}|auto");
+      addproperty ("markersize", hg, "double", 6);
+
+      addlistener (hg, "color", @update_props);
+      addlistener (hg, "linewidth", @update_props); 
+      addlistener (hg, "linestyle", @update_props); 
+      addlistener (hg, "marker", @update_props); 
+      addlistener (hg, "markerfacecolor", @update_props); 
+      addlistener (hg, "markersize", @update_props);
+
+      addproperty ("xdata", hg, "data", x(:, i));
+      addproperty ("ydata", hg, "data", y(:, i));
+      if (have_z)
+       addproperty ("zdata", hg, "data", z(:, i));
+      else
+       addproperty ("zdata", hg, "data", []);
+      endif
+
+      addlistener (hg, "xdata", @update_data);
+      addlistener (hg, "ydata", @update_data);
+      addlistener (hg, "zdata", @update_data);
+    endfor
+
   unwind_protect_cleanup
+    set (ax, "nextplot", hold_state);
     axes (oldax);
   end_unwind_protect
-
-  h = [h_stems; h_baseline];
-
 endfunction
 
 function [x, y, z, dofill, lc, ls, mc, ms] = check_stem_arg (have_z, varargin)
@@ -115,11 +183,11 @@ function [x, y, z, dofill, lc, ls, mc, m
   elseif (nargin == 3)
     ## several possibilities
     ## 1. the real y data
-    ## 2. 'fill'
+    ## 2. 'filled'
     ## 3. line spec
     if (ischar (varargin{2}))
       ## only 2. or 3. possible
-      if (strcmp ("fill", varargin{2}))
+      if (strcmpi ("fill", varargin{2}) || strcmpi ("filled", varargin{2}))
        dofill = 1;
       else
        ## parse the linespec
@@ -154,12 +222,12 @@ function [x, y, z, dofill, lc, ls, mc, m
   elseif (nargin == 4)
     ## again several possibilities
     ## arg2 1. real y
-    ## arg2 2. 'fill' or linespec
+    ## arg2 2. 'filled' or linespec
     ## arg3 1. real z
-    ## arg3 2. 'fill' or linespec
+    ## arg3 2. 'filled' or linespec
     if (ischar (varargin{2}))
       ## only arg2 2. / arg3 1. & arg3 3. are possible
-      if (strcmp ("fill", varargin{2}))
+      if (strcmpi ("fill", varargin{2}) || strcmpi ("filled", varargin{2}))
        dofill = 1;
        fill_2 = 1; # be sure, no second "fill" is in the arguments
       else
@@ -200,14 +268,16 @@ function [x, y, z, dofill, lc, ls, mc, m
     endif # if ischar(varargin{2})
     if (! have_z)
       ## varargin{3} must be char
-      ## check for "fill"
-      if (strcmp ("fill", varargin{3}) && fill_2)
+      ## check for "fill
+      if ((strcmpi ("fill", varargin{3}) || strcmpi ("filled", varargin{3}))
+         && fill_2)
        error ("stem: duplicate fill argument");
       elseif (strcmp("fill", varargin{3}) && linespec_2)
        ## must be "fill"
        dofill = 1;
        fill_2 = 1;
-      elseif (strcmp ("fill", varargin{3}) && ! linespec_2)
+      elseif ((strcmpi ("fill", varargin{3}) || strcmpi ("filled", 
varargin{3}))
+         && !linespec_2)
        ## must be "fill"
        dofill = 1;
        fill_2 = 1;
@@ -234,7 +304,7 @@ function [x, y, z, dofill, lc, ls, mc, m
     endif
 
     if (! have_z)
-      if (strcmp ("fill", varargin{3}))
+      if (strcmpi ("fill", varargin{3}) || strcmpi ("filled", varargin{3}))
        dofill = 1;
        fill_2 = 1; # be sure, no second "fill" is in the arguments
       else
@@ -245,13 +315,16 @@ function [x, y, z, dofill, lc, ls, mc, m
     endif
 
     ## check for "fill" ..
-    if (strcmp ("fill", varargin{4}) && fill_2)
+    if ((strcmpi ("fill", varargin{4}) || strcmpi ("filled", varargin{4}))
+       && fill_2)
       error ("%s: duplicate fill argument", caller);
-    elseif (strcmp ("fill", varargin{4}) && linespec_2)
+    elseif ((strcmpi ("fill", varargin{4}) || strcmpi ("filled", varargin{4}))
+       && linespec_2)
       ## must be "fill"
       dofill = 1;
       fill_2 = 1;
-    elseif (! strcmp ("fill", varargin{4}) && ! linespec_2)
+    elseif (!strcmpi ("fill", varargin{4}) && !strcmpi ("filled", varargin{4})
+       && !linespec_2)
       ## must be linespec
       [lc, ls, mc, ms] = stem_line_spec (caller, varargin{4});
       linespec_2 = 1;
@@ -264,7 +337,7 @@ function [x, y, z, dofill, lc, ls, mc, m
       error ("stem3: X, Y and Z must be matrices");
     endif
 
-    if (strcmp ("fill", varargin{4}))
+    if (strcmpi ("fill", varargin{4}) || strcmpi ("filled", varargin{4}))
       dofill = 1;
       fill_2 = 1; # be sure, no second "fill" is in the arguments
     else
@@ -274,19 +347,52 @@ function [x, y, z, dofill, lc, ls, mc, m
     endif
 
     ## check for "fill" ..
-    if (strcmp ("fill", varargin{5}) && fill_2)
+    if ((strcmpi ("fill", varargin{5}) || strcmpi ("filled", varargin{5}))
+       && fill_2)
       error ("stem3: duplicate fill argument");
-    elseif (strcmp ("fill", varargin{5}) && linespec_2)
+    elseif ((strcmpi ("fill", varargin{5}) || strcmpi ("filled", varargin{5}))
+       && linespec_2)
       ## must be "fill"
       dofill = 1;
       fill_2 = 1;
-    elseif (! strcmp ("fill", varargin{5}) && ! linespec_2)
+    elseif (!strcmpi ("fill", varargin{5}) && !strcmpi ("filled", varargin{5})
+       && !linespec_2)
       ## must be linespec
       [lc, ls, mc, ms] = stem_line_spec (caller, varargin{5});
       linespec_2 = 1;
     endif
   else
     error ("%s: incorrect number of arguments", caller);
+  endif
+
+  ## Check sizes of x, y and z
+  if (have_z)
+    if (!size_equal (x, y, z))
+      error ("stem3: inconsistent size of x, y and z");
+    else
+      x = x(:);
+      y = y(:);
+      z = z(:);
+    endif
+  else
+    if (isvector (x))
+      x = x(:);
+      if (isvector (y))
+       if (length (x) != length (y))
+         error ("stem: inconsistent size of x and y");
+       else
+         y = y(:);
+       endif
+      else
+       if (length (x) == rows (y))
+         x = repmat (x(:), 1, columns (y));
+       else
+         error ("stem: inconsistent size of x and y");
+       endif
+      endif
+    elseif (!size_equal (x, y ))
+      error ("stem: inconsistent size of x and y");
+    endif
   endif
 
 endfunction
@@ -312,8 +418,103 @@ endfunction
 
 function [lc, ls, mc, ms] = set_default_values ()
   ## set default values
-  mc = [1, 0, 0];
-  lc = [1, 0, 0];
+  mc = [];
+  lc = [];
   ls = "-";
   ms = "o";
 endfunction
+
+function update_xlim (h, d)
+  kids = get (h, "children");
+  xlim = get (h, "xlim");
+
+  for i = 1 : length (kids)
+    obj = get (kids (i));
+    if (strcmp (obj.type, "hggroup") && isfield (obj, "baseline"))
+      if (get (obj.baseline, "xdata") != xlim)
+       set (obj.baseline, "xdata", xlim);
+      endif
+    endif
+  endfor
+endfunction
+
+function update_baseline (h, d)
+  visible = get (h, "visible");
+  ydata = get (h, "ydata")(1);
+
+  kids = get (get (h, "parent"), "children");
+  for i = 1 : length (kids)
+    obj = get (kids (i));
+    if (strcmp (obj.type, "hggroup") && isfield (obj, "baseline") 
+       && obj.baseline == h)
+      ## Only alter if changed to avoid recursion of the listener functions
+      if (! strcmp (get (kids(i), "showbaseline"), visible))
+       set (kids (i), "showbaseline", visible);
+      endif
+      if (! strcmp (get (kids(i), "basevalue"), visible))
+       set (kids (i), "basevalue", ydata);
+      endif
+    endif
+  endfor
+endfunction
+
+function show_baseline (h, d)
+  set (get (h, "baseline"), "visible", get (h, "showbaseline"));
+endfunction
+
+function move_baseline (h, d)
+  b0 = get (h, "basevalue");
+  bl = get (h, "baseline");
+
+  if (get (bl, "ydata") != [b0, b0])
+    set (bl, "ydata", [b0, b0]);
+  endif
+
+  kids = get (h, "children");
+  yt = get(h, "ydata")(:)';
+  ny = length (yt);
+  yt = [b0 * ones(1, ny); yt; NaN(1, ny)](:);
+  set (kids(1), "ydata", yt);
+endfunction
+
+function update_props (h, d)
+  kids = get (h, "children");
+  set (kids(1), "color", get (h, "color"), 
+       "linewidth", get (h, "linewidth"),
+       "linestyle", get (h, "linestyle"));
+  set (kids(2), "color", get (h, "color"), 
+       "marker", get (h, "marker"),
+       "markerfacecolor", get (h, "markerfacecolor"),
+       "markersize", get (h, "markersize"));
+endfunction
+
+function update_data (h, d)
+  x = get (h, "xdata");
+  y = get (h, "ydata");
+  z = get (h, "zdata");
+
+  if (!isempty (z) && size_equal (x, y, z))
+    error ("stem3: inconsistent size of x, y and z");
+  elseif (numel(x) != numel (y))
+    error ("stem: inconsistent size of x and y");
+  else
+    bl = get (h, "basevalue");
+    nx = numel (x);
+    x = x(:)';
+    xt = [x; x; NaN(1, nx)](:);
+    if (! isempty (z))
+      y = y(:)';
+      yt = [y; y; NaN(1, nx)](:);
+      z = z(:)';
+      zt = [bl * ones(1, nx); z; NaN(1, nx)](:);
+    else
+      y = y(:)';
+      yt = [bl * ones(1, nx); y; NaN(1, nx)](:);
+      zt = [];
+    endif
+
+    kids = get (h, "children");
+    set (kids(1), "xdata", xt, "ydata", yt, "zdata", zt)
+    set (kids(2), "xdata", x, "ydata", y, "zdata", z)
+  endif
+endfunction
diff --git a/scripts/plot/stem.m b/scripts/plot/stem.m
--- a/scripts/plot/stem.m
+++ b/scripts/plot/stem.m
@@ -18,74 +18,51 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {Function File} address@hidden =} stem (@var{x}, @var{y}, 
@var{linespec})
-## Plot a stem graph and return the handles of the line and marker
-## objects used to draw the stems.  The default color is @code{"r"}
-## (red).  The default line style is @code{"-"} and the default marker is
-## @code{"o"}.
+## @deftypefnx {Function File} address@hidden =} stem (@dots{}, "filled")
+## Plot a stem graph from two vectors of x-y data. If only one argument
+## is given, it is taken as the y-values and the x coordinates are taken
+## from the indicies of the elements.
 ##
-## For example,
-## @example
-## x = 1:10;
-## stem (x);
-## @end example
-## @noindent
-## plots 10 stems with heights from 1 to 10;
+## If @var{y} is a matrix, then each column of the matrix is plotted as
+## a separate stem graph. In this case @var{x} can either be a vector,
+## the same length as the number of rows in @var{y}, or it can be a
+## matrix of the same size as @var{y}.
+##
+## The default color is @code{"r"} (red). The default line style is
+## @code{"-"} and the default marker is @code{"o"}. The line style can
+## be altered by the @code{linespec} argument in the same manner as the
+## @code{plot} command. For example
 ##
 ## @example
+## @group
 ## x = 1:10;
 ## y = ones (1, length (x))*2.*x;
-## stem (x, y);
+## stem (x, y, "b");
+## @end group
 ## @end example
+##
 ## @noindent
-## plots 10 stems with heights from 2 to 20;
+## plots 10 stems with heights from 2 to 20 in blue;
 ## 
-## @example
-## x = 1:10;
-## y = ones (size (x))*2.*x;
-## h = stem (x, y, "b");
-## @end example
-## @noindent
-## plots 10 bars with heights from 2 to 20
-## (the color is blue, and @var{h} is a 2-by-10 array of handles in
-## which the first row holds the line handles and
-## the second row holds the marker handles);
+## The return value of @code{stem} is a vector if "stem series" graphics
+## handles, with one handle per column of the variable @var{y}. This
+## handle regroups the elements of the stem graph together as the
+## children of the "stem series" handle, allowing them to be altered
+## together. For example
 ##
 ## @example
-## x = 1:10;
-## y = ones (size (x))*2.*x;
-## h = stem (x, y, "-.k");
+## @group
+## x = [0 : 10].';
+## y = [sin(x), cos(x)]
+## h = stem (x, y);
+## set (h(2), "color", "g");
+## set (h(1), "basevalue", -1)
+## @end group
 ## @end example
+##
 ## @noindent
-## plots 10 stems with heights from 2 to 20
-## (the color is black, line style is @code{"-."}, and @var{h} is a 2-by-10
-## array of handles in which the first row holds the line handles and
-## the second row holds the marker handles);
-##
-## @example
-## x = 1:10;
-## y = ones (size (x))*2.*x;
-## h = stem (x, y, "-.k.");
-## @end example
-## @noindent
-## plots 10 stems with heights from 2 to 20
-## (the color is black, line style is @code{"-."} and the marker style
-## is @code{"."}, and @var{h} is a 2-by-10 array of handles in which the
-## first row holds the line handles and the second row holds the marker
-## handles);
-##
-## @example
-## x = 1:10;
-## y = ones (size (x))*2.*x;
-## h = stem (x, y, "fill");
-## @end example
-## @noindent
-## plots 10 stems with heights from 2 to 20
-## (the color is rgb-triple defined, the line style is @code{"-"},
-## the marker style is @code{"o"}, and @var{h} is a 2-by-10 array of
-## handles in which the first row holds the line handles and the second
-## row holds the marker handles).
-##
-## Color definitions with rgb-triples are not valid!
+## changes the color of the second "stem series"  and moves the base line
+## of the first.
 ## @seealso{bar, barh, plot}
 ## @end deftypefn
 
@@ -134,3 +111,10 @@ endfunction
 %! x = 1:10;
 %! y = ones (size (x))*2.*x;
 %! h = stem (x, y, "fill");
+
+%!demo
+%! x = [0 : 10].';
+%! y = [sin(x), cos(x)];
+%! h = stem (x, y);
+%! set (h(2), "color", "g");
+%! set (h(1), "basevalue", -1)
diff --git a/scripts/plot/stem3.m b/scripts/plot/stem3.m
--- a/scripts/plot/stem3.m
+++ b/scripts/plot/stem3.m
@@ -19,9 +19,9 @@
 ## -*- texinfo -*-
 ## @deftypefn {Function File} address@hidden =} stem3 (@var{x}, @var{y}, 
@var{z}, @var{linespec})
 ## Plot a three-dimensional stem graph and return the handles of the line
-## and marker objects used to draw the stems.  The default color is @code{"r"}
-## (red).  The default line style is @code{"-"} and the default marker is
-## @code{"o"}.
+## and marker objects used to draw the stems as "stem series" object.
+## The default color is @code{"r"} (red).  The default line style is
+## @code{"-"} and the default marker is @code{"o"}.
 ##
 ## For example,
 ## @example
diff --git a/src/ChangeLog b/src/ChangeLog
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,14 @@ 2008-08-19  David Bateman  <address@hidden
+2008-08-23  David Bateman  <address@hidden>
+
+       * graphics.cc (void gh_manager::do_execute_callback 
+       (const graphics_handle&, const octave_value&, const
+       octave_value&)): Don't pass the function handle as first arg of
+       property listener functions
+
+       * graphics.h.in (class base_properties): Add functor for caseless
+       string comparison. Use it in the property map, so that user added
+       properties are found in a case insensitive fashion.
+
 2008-08-19  David Bateman  <address@hidden>
 
        * load-path.cc (load-path::do_find_dir (const std:string&) const)):
diff --git a/src/graphics.cc b/src/graphics.cc
--- a/src/graphics.cc
+++ b/src/graphics.cc
@@ -3743,8 +3743,8 @@ gh_manager::do_execute_callback (const g
       fcn = c(0).function_value ();
       if (! error_state)
         {
-          for (int i = 0; i < c.length () ; i++)
-            args(2+i) = c(i);
+          for (int i = 1; i < c.length () ; i++)
+            args(1+i) = c(i);
         }
     }
   else
diff --git a/src/graphics.h.in b/src/graphics.h.in
--- a/src/graphics.h.in
+++ b/src/graphics.h.in
@@ -1793,7 +1793,20 @@ protected:
   handle_property uicontextmenu;
 
 protected:
-  std::map<caseless_str, property> all_props;
+  struct cmp_caseless_str 
+    {
+      bool operator () (const caseless_str &a, const caseless_str &b) const
+        {
+         std::string a1 = a;
+         std::transform (a1.begin (), a1.end (), a1.begin (), tolower);
+         std::string b1 = b;
+         std::transform (b1.begin (), b1.end (), b1.begin (), tolower);
+
+          return a1 < b1;
+        }
+    };
+
+  std::map<caseless_str, property, cmp_caseless_str> all_props;
 
 protected:
   void insert_static_property (const std::string& name, base_property& p)

reply via email to

[Prev in Thread] Current Thread [Next in Thread]