digits.h

View source code here on GitHub!

Includes

type digit_counter

Implements the Iterator API and yields successive decimal digits of a given number.

uint8_t (*iterator_function)(digit_counter *dc)

The function to advance the iterator and return the next element.

bool exhausted : 1

An indicator that tells you if the iterator is exhausted.

bool started : 1

An indicator that tells you if the interator has moved at all.

bool phase : 1

An indicator that flips every time the iterator moves.

uint8_t *digits

This array holds the individual digits of a parsed integer.

size_t idx

This represents the current position in digits.

digit_counter digits(uintmax_t n)
void free_digit_counter(digit_counter dc)
 1#pragma once
 2
 3#include <stdint.h>
 4#include "macros.h"
 5#include "iterator.h"
 6
 7#if !PCC_COMPILER
 8    #include <stdlib.h>
 9    #include <math.h>
10#else
11    #include "math.h"
12#endif
13
14typedef struct digit_counter digit_counter;
15struct digit_counter    {
16    IteratorHead(uint8_t, digit_counter);
17    uint8_t *digits;
18    size_t idx;
19};
20
21uint8_t advance_digit_counter(digit_counter *dc) {
22    IterationHead(dc);
23    uint8_t ret = dc->digits[dc->idx--];
24    dc->exhausted = (dc->idx == -1);
25    return ret;
26}
27
28digit_counter digits(uintmax_t n) {
29    digit_counter ret;
30    IteratorInitHead(ret, advance_digit_counter);
31#if !PCC_COMPILER
32    size_t digit_len = ceil(log10(n + 1));
33#else
34    size_t digit_len = imprecise_log10(n + 1);
35#endif
36    ret.digits = (uint8_t *) malloc(digit_len * sizeof(uint8_t));
37    for (size_t i = 0; i < digit_len; i++) {
38        ret.digits[i] = n % 10;
39        n /= 10;
40    }
41    ret.idx = digit_len - 1;
42    return ret;
43}
44
45void free_digit_counter(digit_counter dc) {
46    if (dc.digits != NULL)
47        free(dc.digits);
48}

Tags: c-iterator