Sha256: a5bda5e7602dc3a79368e9ce5fae6df3579961359d9f9e1e3f65498e80d2212f

Contents?: true

Size: 1.36 KB

Versions: 2

Compression:

Stored size: 1.36 KB

Contents

#include "just_all_the_same.h"

VALUE rb_mJustAllTheSame;
#define SWITCH_TO_LINER 300

static VALUE
all_same_p(VALUE ary, VALUE target)
{
  long size = RARRAY_LEN(ary);

  if (size == 0) return Qtrue;

  VALUE *forward_p = RARRAY_PTR(ary);

  if (forward_p[0] != target) return Qfalse;

  VALUE *backward_p;

  long s = size;      // size of foward_ary + backward_aray
  long v = size / 2;  // splitting index

  /* split algorithm */
  while (v >= SWITCH_TO_LINER / 2)
  {
    backward_p = forward_p + v;

    /* check last of array nil? if size is not odd? */
    if (s%2 && forward_p[s-1] != target) return Qfalse;

    /* check quick same back and fowerd */
    if (memcmp(forward_p, backward_p, sizeof(VALUE) * v)) return Qfalse;

    s = v;
    v /= 2;
  }

  /* liner algorithm */
  for (long i = 1; i < s; i++) if (forward_p[i] != target) return Qfalse;

  return Qtrue;
}

static VALUE
all_nil_p(VALUE ary)
{
  return all_same_p(ary, Qnil);
}

static VALUE
all_true_p(VALUE ary)
{
  return all_same_p(ary, Qtrue);
}

static VALUE
all_false_p(VALUE ary)
{
  return all_same_p(ary, Qfalse);
}

void
Init_just_all_the_same(void)
{
  rb_define_method(rb_cArray, "all_nil?"   , all_nil_p   , 0);
  rb_define_method(rb_cArray, "all_true?"  , all_true_p  , 0);
  rb_define_method(rb_cArray, "all_false?" , all_false_p , 0);
  rb_define_method(rb_cArray, "all_same?"  , all_same_p  , 1);
}

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
just_all_the_same-0.1.1 ext/just_all_the_same/just_all_the_same.c
just_all_the_same-0.1.0 ext/just_all_the_same/just_all_the_same.c