/* This is -*- C -*- */
/* $Id: guppi-seq-boolean.c,v 1.26 2002/01/14 05:01:17 trow Exp $ */
/*
* guppi-seq-boolean.c
*
* Copyright (C) 2000 EMC Capital Management, Inc.
* Copyright (C) 2001 The Free Software Foundation
*
* Developed by Jon Trowbridge <trow@gnu.org> and
* Havoc Pennington <hp@pobox.com>.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program 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 program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
#include <config.h>
#include "guppi-seq-boolean.h"
/* #include <gnome.h> */
#include <string.h>
#include <libgnome/gnome-defs.h>
#include <libgnome/gnome-config.h>
#include <libgnome/gnome-i18n.h>
#include <guppi-memory.h>
static GtkObjectClass *parent_class = NULL;
static void
guppi_seq_boolean_finalize (GtkObject * obj)
{
if (parent_class->finalize)
parent_class->finalize (obj);
}
static xmlNodePtr
export_xml_element (GuppiSeq *seq, gint i, GuppiXMLDocument *doc)
{
gboolean x = guppi_seq_boolean_get (GUPPI_SEQ_BOOLEAN (seq), i);
return xmlNewNode (doc->ns, x ? "true" : "false");
}
static gboolean
import_xml_element (GuppiSeq *seq, GuppiXMLDocument *doc, xmlNodePtr node)
{
if (!strcmp (node->name, "true"))
guppi_seq_boolean_append ((GuppiSeqBoolean *) seq, TRUE);
else if (!strcmp (node->name, "false"))
guppi_seq_boolean_append ((GuppiSeqBoolean *) seq, FALSE);
else {
g_warning ("Bad boolean node: \"%s\"", node->name);
return FALSE;
}
return TRUE;
}
/***************************************************************************/
typedef struct _GuppiDataOp_Boolean GuppiDataOp_Boolean;
struct _GuppiDataOp_Boolean {
GuppiDataOp op;
gint i;
gsize N;
gboolean x;
const gint *iptr;
const GuppiSeqBoolean *other;
};
static void
op_set (GuppiData *d, GuppiDataOp *op)
{
GuppiDataOp_Boolean *bop = (GuppiDataOp_Boolean *) op;
GuppiSeqBoolean *seq;
GuppiSeqBooleanClass *klass;
seq = GUPPI_SEQ_BOOLEAN (d);
klass = GUPPI_SEQ_BOOLEAN_CLASS (GTK_OBJECT (d)->klass);
g_assert (klass->set);
klass->set (seq, bop->i, bop->x);
}
static void
op_set_all (GuppiData *d, GuppiDataOp *op)
{
GuppiDataOp_Boolean *bop = (GuppiDataOp_Boolean *) op;
GuppiSeqBoolean *seq;
GuppiSeqBooleanClass *klass;
seq = GUPPI_SEQ_BOOLEAN (d);
klass = GUPPI_SEQ_BOOLEAN_CLASS (GTK_OBJECT (d)->klass);
g_assert (klass->set_all);
klass->set_all (seq, bop->x);
}
static void
op_set_many (GuppiData *d, GuppiDataOp *op)
{
GuppiDataOp_Boolean *bop = (GuppiDataOp_Boolean *) op;
GuppiSeqBoolean *seq;
GuppiSeqBooleanClass *klass;
seq = GUPPI_SEQ_BOOLEAN (d);
klass = GUPPI_SEQ_BOOLEAN_CLASS (GTK_OBJECT (d)->klass);
if (klass->set_many) {
klass->set_many (seq, bop->iptr, bop->N, bop->x);
} else {
gint i = 0, i0, i1;
guppi_seq_bounds (GUPPI_SEQ (d), &i0, &i1);
g_assert (klass->set);
for (i = 0; i < bop->N; ++i) {
gint j = bop->iptr[i];
if (i0 <= j && j <= i1)
klass->set (seq, j, bop->x);
}
}
/* FIXME missing values! */
}
static void
op_insert (GuppiData *d, GuppiDataOp *op)
{
GuppiDataOp_Boolean *bop = (GuppiDataOp_Boolean *) op;
GuppiSeqBoolean *seq;
GuppiSeqBooleanClass *klass;
seq = GUPPI_SEQ_BOOLEAN (d);
klass = GUPPI_SEQ_BOOLEAN_CLASS (GTK_OBJECT (d)->klass);
if (klass->insert)
klass->insert (seq, bop->i, bop->x);
else if (klass->insert_many)
klass->insert_many (seq, bop->i, bop->x, 1);
else
g_assert_not_reached ();
}
static void
op_insert_many (GuppiData *d, GuppiDataOp *op)
{
GuppiDataOp_Boolean *bop = (GuppiDataOp_Boolean *) op;
GuppiSeqBoolean *seq;
GuppiSeqBooleanClass *klass;
seq = GUPPI_SEQ_BOOLEAN (d);
klass = GUPPI_SEQ_BOOLEAN_CLASS (GTK_OBJECT (d)->klass);
g_assert (klass->insert_many);
klass->insert_many (seq, bop->i, bop->x, bop->N);
}
static void
op_and (GuppiData *d, GuppiDataOp *op)
{
GuppiDataOp_Boolean *bop = (GuppiDataOp_Boolean *) op;
GuppiSeqBoolean *seq;
GuppiSeqBoolean *other_seq;
GuppiSeqBooleanClass *klass;
seq = GUPPI_SEQ_BOOLEAN (d);
klass = GUPPI_SEQ_BOOLEAN_CLASS (GTK_OBJECT (d)->klass);
other_seq = GUPPI_SEQ_BOOLEAN (bop->other);
g_assert (klass->bitwise_and);
klass->bitwise_and (seq, other_seq);
}
static void
op_or (GuppiData *d, GuppiDataOp *op)
{
GuppiDataOp_Boolean *bop = (GuppiDataOp_Boolean *) op;
GuppiSeqBoolean *seq;
GuppiSeqBoolean *other_seq;
GuppiSeqBooleanClass *klass;
seq = GUPPI_SEQ_BOOLEAN (d);
klass = GUPPI_SEQ_BOOLEAN_CLASS (GTK_OBJECT (d)->klass);
other_seq = GUPPI_SEQ_BOOLEAN (bop->other);
g_assert (klass->bitwise_or);
klass->bitwise_or (seq, other_seq);
}
static void
op_xor (GuppiData *d, GuppiDataOp *op)
{
GuppiDataOp_Boolean *bop = (GuppiDataOp_Boolean *) op;
GuppiSeqBoolean *seq;
GuppiSeqBoolean *other_seq;
GuppiSeqBooleanClass *klass;
seq = GUPPI_SEQ_BOOLEAN (d);
klass = GUPPI_SEQ_BOOLEAN_CLASS (GTK_OBJECT (d)->klass);
other_seq = GUPPI_SEQ_BOOLEAN (bop->other);
g_assert (klass->bitwise_xor);
klass->bitwise_xor (seq, other_seq);
}
static void
op_not (GuppiData *d, GuppiDataOp *op)
{
GuppiSeqBoolean *seq;
GuppiSeqBooleanClass *klass;
seq = GUPPI_SEQ_BOOLEAN (d);
klass = GUPPI_SEQ_BOOLEAN_CLASS (GTK_OBJECT (d)->klass);
g_assert (klass->bitwise_not);
klass->bitwise_not (seq);
}
/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
/* Default implementations, mostly to deal with missing values. */
static void
v_set (GuppiSeqBoolean *sb, gint i, gboolean x)
{
GUPPI_SEQ_CLASS (GTK_OBJECT (sb)->klass)->set_missing (GUPPI_SEQ (sb), i, FALSE);
}
static void
v_set_all (GuppiSeqBoolean *sb, gboolean x)
{
GUPPI_SEQ_CLASS (GTK_OBJECT (sb)->klass)->set_all_missing (GUPPI_SEQ (sb), FALSE);
}
static void
v_set_many (GuppiSeqBoolean *sb, const gint *indices, gsize N, gboolean x)
{
GuppiSeqClass *seq_class = GUPPI_SEQ_CLASS (GTK_OBJECT (sb)->klass);
GuppiSeq *seq = GUPPI_SEQ (sb);
gint i;
/* This is a candidate for obvious optimization */
for (i = 0; i < (gint) N; ++i) {
seq_class->set_missing (seq, indices[i], FALSE);
}
}
static void
v_insert (GuppiSeqBoolean *sb, gint i, gboolean x)
{
GUPPI_SEQ_CLASS (GTK_OBJECT (sb)->klass)->insert_missing (GUPPI_SEQ (sb), i, FALSE, 1);
}
static void
v_insert_many (GuppiSeqBoolean *sb, gint i, gboolean x, gsize N)
{
GUPPI_SEQ_CLASS (GTK_OBJECT (sb)->klass)->insert_missing (GUPPI_SEQ (sb), i, FALSE, N);
}
/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
#if 0
/**
* guppi_seq_boolean_new_aligned
* @seq: A sequence
*
* Allocates a new boolean sequence whose index bounds are the same as @seq.
* All the elements of the new sequence are initially set to %FALSE.
* A default implementation is used.
*
* Returns: The newly-allocated sequence
*/
GuppiData *
guppi_seq_boolean_new_aligned (const GuppiSeq *seq)
{
GuppiSeqBoolean *aligned;
if (seq == NULL)
return NULL;
aligned = GUPPI_SEQ_BOOLEAN (guppi_seq_boolean_new ());
guppi_seq_boolean_append_many (aligned, FALSE, guppi_seq_size (seq));
guppi_seq_set_min_index (GUPPI_SEQ (aligned), guppi_seq_min_index (seq));
return GUPPI_DATA (aligned);
}
#endif
/**
* guppi_seq_boolean_get
* @seq: A boolean sequence
* @i: A position index
*
* Returns: The boolean value of the @i-th element of @seq.
* @i must lie within @seq's bounds.
*/
gboolean
guppi_seq_boolean_get (const GuppiSeqBoolean *seq, gint i)
{
GuppiSeqBooleanClass *klass;
g_return_val_if_fail (seq != NULL, FALSE);
g_return_val_if_fail (guppi_seq_in_bounds (GUPPI_SEQ (seq), i), FALSE);
klass = GUPPI_SEQ_BOOLEAN_CLASS (GTK_OBJECT (seq)->klass);
g_assert (klass->get);
return klass->get ((GuppiSeqBoolean *) seq, i);
}
/**
* guppi_seq_boolean_set
* @seq: A boolean sequence
* @i: A position impl
* @x: A boolean value
*
* Sets the @i-th element of the sequence @seq to @x.
* @seq must be writeable, and @i must lie within @seq's bounds.
*/
void
guppi_seq_boolean_set (GuppiSeqBoolean *seq, gint i, gboolean x)
{
g_return_if_fail (seq != NULL && GUPPI_IS_SEQ_BOOLEAN (seq));
g_return_if_fail (guppi_data_can_change (GUPPI_DATA (seq)));
g_return_if_fail (guppi_seq_in_bounds (GUPPI_SEQ (seq), i));
if (guppi_seq_boolean_get (seq, i) != x) {
GuppiDataOp_Boolean op;
op.op.op = op_set;
op.i = i;
op.x = x;
guppi_seq_changed_set (GUPPI_SEQ (seq), i, i, (GuppiDataOp *) & op);
}
}
/**
* guppi_seq_boolean_set_all
* @seq: A boolean sequence
* @x: A boolean value
*
* Sets all of the elements of @seq to @x.
*/
void
guppi_seq_boolean_set_all (GuppiSeqBoolean *seq, gboolean x)
{
GuppiDataOp_Boolean op;
gint i0, i1;
g_return_if_fail (seq != NULL && GUPPI_IS_SEQ_BOOLEAN (seq));
g_return_if_fail (guppi_data_can_change (GUPPI_DATA (seq)));
guppi_seq_bounds (GUPPI_SEQ (seq), &i0, &i1);
op.op.op = op_set_all;
op.x = x;
guppi_seq_changed_set (GUPPI_SEQ (seq), i0, i1, (GuppiDataOp *) & op);
}
/**
* guppi_seq_boolean_set_many
* @seq: A boolean sequence
* @indices: An array of position indices
* @N: The length of array @indices
* @x: A boolean value
*
* Iterates across the array @indices, reading the position indices
* contained in that array and setting the corresponding entries of
* @seq equal to @x.
*/
void
guppi_seq_boolean_set_many (GuppiSeqBoolean *seq,
gint *indices, gsize N, gboolean x)
{
GuppiDataOp_Boolean op;
gint i, i0, i1;
g_return_if_fail (seq != NULL && GUPPI_IS_SEQ_BOOLEAN (seq));
g_return_if_fail (guppi_data_can_change (GUPPI_DATA (seq)));
if (N == 0)
return;
g_return_if_fail (indices != NULL);
i0 = i1 = indices[0];
for (i = 1; i < N; ++i) {
if (indices[i] < i0)
i0 = indices[i];
if (indices[i] > i1)
i1 = indices[i];
}
op.op.op = op_set_many;
op.iptr = indices;
op.N = N;
op.x = x;
guppi_seq_changed_set (GUPPI_SEQ (seq), i0, i1, (GuppiDataOp *) & op);
}
/**
* guppi_seq_boolean_clear
* @seq: A boolean sequence
*
* Set all of the elements of @seq equal to %FALSE.
*/
void
guppi_seq_boolean_clear (GuppiSeqBoolean *seq)
{
guppi_seq_boolean_set_all (seq, FALSE);
}
/**
* guppi_seq_boolean_prepend
* @seq: A boolean sequence
* @x: A boolean value
*
* Prepend the boolean value @x to the sequence @seq.
* @seq must be writeable.
*/
void
guppi_seq_boolean_prepend (GuppiSeqBoolean *seq, gboolean x)
{
gint i;
g_return_if_fail (seq != NULL);
g_return_if_fail (guppi_data_can_change (GUPPI_DATA (seq)));
i = guppi_seq_min_index (GUPPI_SEQ (seq));
guppi_seq_boolean_insert (seq, i, x);
}
/**
* guppi_seq_boolean_prepend_many
* @seq: A boolean sequence
* @x: A boolean value
* @N: A count
*
* Prepend @N instances of the boolean value @x to the sequence @seq.
* @seq must be writeable.
*/
void
guppi_seq_boolean_prepend_many (GuppiSeqBoolean *seq, gboolean x, gsize N)
{
gint i;
g_return_if_fail (seq != NULL);
g_return_if_fail (guppi_data_can_change (GUPPI_DATA (seq)));
if (N == 0)
return;
i = guppi_seq_min_index (GUPPI_SEQ (seq));
guppi_seq_boolean_insert_many (seq, i, x, N);
}
/**
* guppi_seq_boolean_append
* @seq: A boolean sequence
* @x: A boolean value
*
* Append the boolean value @x to the sequence @seq.
* @seq must be writeable.
*/
void
guppi_seq_boolean_append (GuppiSeqBoolean *seq, gboolean x)
{
gint i;
g_return_if_fail (seq != NULL);
g_return_if_fail (guppi_data_can_change (GUPPI_DATA (seq)));
i = guppi_seq_max_index (GUPPI_SEQ (seq));
guppi_seq_boolean_insert (seq, i + 1, x);
}
/**
* guppi_seq_boolean_append_many
* @seq: A boolean sequence
* @x: A boolean value
* @N: A count
*
* Append @N instances of the boolean value @x to the sequence @seq.
* @seq must be writeable.
*/
void
guppi_seq_boolean_append_many (GuppiSeqBoolean *seq, gboolean x, gsize N)
{
gint i;
g_return_if_fail (seq != NULL);
g_return_if_fail (guppi_data_can_change (GUPPI_DATA (seq)));
if (N == 0)
return;
i = guppi_seq_max_index (GUPPI_SEQ (seq));
guppi_seq_boolean_insert_many (seq, i + 1, x, N);
}
/**
* guppi_seq_boolean_insert
* @seq: A boolean sequence
* @i: A position index
* @x: A boolean value
*
* Insert the boolean value @x into the sequence @seq at position @i.
* @seq must be writeable.
*/
void
guppi_seq_boolean_insert (GuppiSeqBoolean *seq, gint i, gboolean x)
{
GuppiDataOp_Boolean op;
g_return_if_fail (seq != NULL && GUPPI_IS_SEQ_BOOLEAN (seq));
g_return_if_fail (guppi_data_can_change (GUPPI_DATA (seq)));
op.op.op = op_insert;
op.i = i;
op.x = x;
guppi_seq_changed_insert (GUPPI_SEQ (seq), i, i, (GuppiDataOp *) & op);
}
/**
* guppi_seq_boolean_insert_many
* @seq: A boolean sequence
* @i: A position index
* @x: A boolean value
* @N: A count
*
* Insert @N instances of the boolean value @x into the sequence @seq
* at position @i.
* @seq must be writeable.
*/
void
guppi_seq_boolean_insert_many (GuppiSeqBoolean *seq, gint i, gboolean x,
gsize N)
{
GuppiDataOp_Boolean op;
g_return_if_fail (seq != NULL && GUPPI_IS_SEQ_BOOLEAN (seq));
g_return_if_fail (guppi_data_can_change (GUPPI_DATA (seq)));
if (N == 0)
return;
op.op.op = op_insert_many;
op.i = i;
op.x = x;
op.N = N;
guppi_seq_changed_insert (GUPPI_SEQ (seq), i, N, (GuppiDataOp *) & op);
}
/**
* guppi_seq_boolean_bitwise_and
* @seq: A boolean sequence
* @other: Another boolean sequence
*
* Set each element of @seq equal to the logical AND of that
* element and the corresponding element in @other.
* Only the section of @seq whose indices overlap those of @other
* are affected.
* @seq must be writeable.
*/
void
guppi_seq_boolean_bitwise_and (GuppiSeqBoolean *seq,
const GuppiSeqBoolean *other)
{
GuppiDataOp_Boolean op;
gint i0, i1;
g_return_if_fail (seq != NULL && GUPPI_IS_SEQ_BOOLEAN (seq));
g_return_if_fail (guppi_data_can_change (GUPPI_DATA (seq)));
guppi_seq_common_bounds (GUPPI_SEQ (seq), GUPPI_SEQ (other), &i0, &i1);
op.op.op = op_and;
op.other = other;
guppi_seq_changed_set (GUPPI_SEQ (seq), i0, i1, (GuppiDataOp *) & op);
}
/**
* guppi_seq_boolean_bitwise_or
* @seq: A boolean sequence
* @other: Another boolean sequence
*
* Set each element of @seq equal to the logical %OR of that
* element and the corresponding element in @other.
* Only the section of @seq whose indices overlap those of @other
* are affected.
* @seq must be writeable.
*/
void
guppi_seq_boolean_bitwise_or (GuppiSeqBoolean *seq,
const GuppiSeqBoolean *other)
{
GuppiDataOp_Boolean op;
gint i0, i1;
g_return_if_fail (seq != NULL && GUPPI_IS_SEQ_BOOLEAN (seq));
g_return_if_fail (guppi_data_can_change (GUPPI_DATA (seq)));
guppi_seq_common_bounds (GUPPI_SEQ (seq), GUPPI_SEQ (other), &i0, &i1);
op.op.op = op_or;
op.other = other;
guppi_seq_changed_set (GUPPI_SEQ (seq), i0, i1, (GuppiDataOp *) & op);
}
/**
* guppi_seq_boolean_bitwise_xor
* @seq: A boolean sequence
* @other: Another boolean sequence
*
* Set each element of @seq equal to the logical %XOR of that
* element and the corresponding element in @other.
* Only the section of @seq whose indices overlap those of @other
* are affected.
* @seq must be writeable.
*/
void
guppi_seq_boolean_bitwise_xor (GuppiSeqBoolean *seq,
const GuppiSeqBoolean *other)
{
GuppiDataOp_Boolean op;
gint i0, i1;
g_return_if_fail (seq != NULL && GUPPI_IS_SEQ_BOOLEAN (seq));
g_return_if_fail (guppi_data_can_change (GUPPI_DATA (seq)));
guppi_seq_common_bounds (GUPPI_SEQ (seq), GUPPI_SEQ (other), &i0, &i1);
op.op.op = op_xor;
op.other = other;
guppi_seq_changed_set (GUPPI_SEQ (seq), i0, i1, (GuppiDataOp *) & op);
}
/**
* guppi_seq_boolean_bitwise_not
* @seq: A boolean sequence
*
* Set each element of @seq equal to the logical %NOT of that
* element.
* @seq must be writeable.
*/
void
guppi_seq_boolean_bitwise_not (GuppiSeqBoolean *seq)
{
GuppiDataOp_Boolean op;
gint i0, i1;
g_return_if_fail (seq != NULL && GUPPI_IS_SEQ_BOOLEAN (seq));
g_return_if_fail (guppi_data_can_change (GUPPI_DATA (seq)));
guppi_seq_bounds (GUPPI_SEQ (seq), &i0, &i1);
op.op.op = op_not;
guppi_seq_changed_set (GUPPI_SEQ (seq), i0, i1, (GuppiDataOp *) & op);
}
/**
* guppi_seq_boolean_first_true
* @seq: A boolean sequence
*
* Finds the first %TRUE element of @seq. If @seq contains only
* %FALSE values, an out-of-bounds index is returned.
*
* Returns: The index of the lowest-numbered position in @seq
* whose value is %TRUE.
*/
gint
guppi_seq_boolean_first_true (const GuppiSeqBoolean *seq)
{
GuppiSeqBooleanClass *klass;
gint i, i0, i1;
g_return_val_if_fail (seq != NULL, 1);
klass = GUPPI_SEQ_BOOLEAN_CLASS (GTK_OBJECT (seq)->klass);
i0 = guppi_seq_min_index (GUPPI_SEQ (seq));
if (klass->next_true) {
return klass->next_true ((GuppiSeqBoolean *) seq, i0 - 1);
}
g_assert (klass->get);
i1 = guppi_seq_max_index (GUPPI_SEQ (seq));
for (i = i0; i <= i1 && klass->get ((GuppiSeqBoolean *) seq, i); ++i);
return i;
}
/**
* guppi_seq_boolean_next_true
* @seq: A boolean sequence
* @i: A position index
*
* Finds the first %TRUE element of @seq whose index is greater
* that @i. If no such element exists, an out-of-bounds index
* value is returned.
*
* Returns: The index of the next %TRUE value in @seq.
*/
gint
guppi_seq_boolean_next_true (const GuppiSeqBoolean *seq, gint i)
{
GuppiSeqBooleanClass *klass;
gint i1;
g_return_val_if_fail (seq != NULL, 1);
klass = GUPPI_SEQ_BOOLEAN_CLASS (GTK_OBJECT (seq)->klass);
i1 = guppi_seq_max_index (GUPPI_SEQ (seq));
if (i1 < i)
return i;
if (klass->next_true) {
return klass->next_true ((GuppiSeqBoolean *) seq, i);
}
g_assert (klass->get);
while (i < i1) {
++i;
if (klass->get ((GuppiSeqBoolean *) seq, i))
return i;
}
return i;
}
/**
* guppi_seq_boolean_first_jointly_true
* @a: A boolean sequence
* @b: Another boolean sequence
*
* Finds the lowest-valued index value which is common to
* both @a and @b, and for which both sequences contain %TRUE.
* If no such element exists, an out-of-bounds index is
* returned.
*
* Returns: The index of the lowest-numbered position
* whose value is %TRUE for both @a and @b.
*/
gint
guppi_seq_boolean_first_jointly_true (const GuppiSeqBoolean *a,
const GuppiSeqBoolean *b)
{
gint i, i0, i1;
g_return_val_if_fail (GUPPI_IS_SEQ_BOOLEAN (a), 0);
g_return_val_if_fail (GUPPI_IS_SEQ_BOOLEAN (b), 0);
guppi_seq_common_bounds (GUPPI_SEQ (a), GUPPI_SEQ (b), &i0, &i1);
i = i0;
if (!guppi_seq_boolean_get (a, i))
i = guppi_seq_boolean_next_true (a, i);
while (i <= i1 && !guppi_seq_boolean_get (b, i))
i = guppi_seq_boolean_next_true (a, i);
return i;
}
/**
* guppi_seq_boolean_next_jointly_true
* @a: A boolean sequences
* @b: Another boolean sequences
* @i: A position index
*
* Finds the index value of the next element beyond index @i which is
* %TRUE for both @a and @b. If no such element exists, an out-of-bounds
* value is returned.
*
* Returns: The next index value that is %TRUE for both @a and @b.
*/
gint
guppi_seq_boolean_next_jointly_true (const GuppiSeqBoolean *a,
const GuppiSeqBoolean *b, gint i)
{
gint i0, i1;
gint ia, ib;
g_return_val_if_fail (GUPPI_IS_SEQ_BOOLEAN (a), 0);
g_return_val_if_fail (GUPPI_IS_SEQ_BOOLEAN (b), 0);
guppi_seq_common_bounds (GUPPI_SEQ (a), GUPPI_SEQ (b), &i0, &i1);
while (i <= i1) {
ia = guppi_seq_boolean_next_true (a, i);
ib = guppi_seq_boolean_next_true (b, i);
if (ia <= i1 && ib <= i1) {
if (ia == ib)
return ia;
else if (ia < ib && guppi_seq_boolean_get (a, ib))
return ib;
else if (ia > ib && guppi_seq_boolean_get (b, ia))
return ia;
}
i = MAX (ia, ib);
}
return i;
}
/**
* guppi_seq_boolean_true_count
* @seq: A boolean sequences
*
* Returns: The number of elements of the sequence @seq
* that are equal to %TRUE.
*/
gsize
guppi_seq_boolean_true_count (const GuppiSeqBoolean *seq)
{
GuppiSeqBooleanClass *klass;
gint i, i0, i1;
gsize count = 0;
g_return_val_if_fail (seq != NULL, 0);
klass = GUPPI_SEQ_BOOLEAN_CLASS (GTK_OBJECT (seq)->klass);
if (klass->true_count) {
return klass->true_count ((GuppiSeqBoolean *) seq);
}
g_assert (klass->get);
guppi_seq_indices (GUPPI_SEQ (seq), &i0, &i1);
for (i = i0; i <= i1; ++i) {
if (klass->get ((GuppiSeqBoolean *) seq, i))
++count;
}
return count;
}
/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
static void
guppi_seq_boolean_class_init (GuppiSeqBooleanClass *klass)
{
GtkObjectClass *object_class = (GtkObjectClass *) klass;
GuppiSeqClass *seq_class = GUPPI_SEQ_CLASS (klass);
parent_class = gtk_type_class (GUPPI_TYPE_SEQ);
klass->set = v_set;
klass->set_all = v_set_all;
klass->set_many = v_set_many;
klass->insert = v_insert;
klass->insert_many = v_insert_many;
seq_class->export_xml_element = export_xml_element;
seq_class->import_xml_element = import_xml_element;
object_class->finalize = guppi_seq_boolean_finalize;
}
static void
guppi_seq_boolean_init (GuppiSeqBoolean * obj)
{
}
GtkType guppi_seq_boolean_get_type (void)
{
static GtkType guppi_seq_boolean_type = 0;
if (!guppi_seq_boolean_type) {
static const GtkTypeInfo guppi_seq_boolean_info = {
"GuppiSeqBoolean",
sizeof (GuppiSeqBoolean),
sizeof (GuppiSeqBooleanClass),
(GtkClassInitFunc) guppi_seq_boolean_class_init,
(GtkObjectInitFunc) guppi_seq_boolean_init,
NULL, NULL, (GtkClassInitFunc) NULL
};
guppi_seq_boolean_type =
gtk_type_unique (GUPPI_TYPE_SEQ, &guppi_seq_boolean_info);
}
return guppi_seq_boolean_type;
}
/* $Id: guppi-seq-boolean.c,v 1.26 2002/01/14 05:01:17 trow Exp $ */
syntax highlighted by Code2HTML, v. 0.9.1