Skip to content

Latest commit

 

History

History
386 lines (257 loc) · 9.06 KB

ARCHITECTURE.md

File metadata and controls

386 lines (257 loc) · 9.06 KB

Architecture

This document aims to describe the file structure and contents of this project.

Root

The root directory contains the itplus.h header file, which is a single header version of the full library. It contains every header present in include.

include

The include directory contains all the header files for the iterplus interface library.

File Description

itplus_chain.h

Macros for implementing the chain abstraction using the IterChain struct.

An IterChain struct is a struct that stores 2 iterables, and starts consuming from the other one once one of them has been fully consumed. Essentially chaining together the 2 iterables.

itplus_collect.h

Macros for implementing the collect abstraction.

Note: Rust's collect has a polymorphic return type. The collect here just turns an iterable into an array.

itplus_defn.h

Helpers for implementing all iterplus utilities at once, for given type.

itplus_drop.h

Macros for implementing the drop abstraction using the IterDrop struct.

An IterDrop struct is a struct that keeps track of how many elements have been dropped out of an iterator as well as a limit to start extracting the elements at - the iterator impl for this struct will keep dropping from an iterator until it hits that limit, or until the source iterable gets exhausted, whichever comes first. Once enough elements have been dropped, it'll start extracting and returning the rest of the elements.

itplus_dropwhile.h

Macros for implementing the dropWhile abstraction using the IterDropWhile struct.

An IterDropWhile struct is a struct that stores a source iterable, a predicate function, and a flag to indicate when to stop testing with the predicate function. It keeps dropping from the source iterable until the predicate returns false, and starts returning the elements from the iterators from there on.

itplus_enumerate.h

Macros for implementing the enumerate abstraction using the IterEnumr struct.

An IterEnumr struct is a struct that stores an iterable, and its iteration index. Its next function implementation that returns a Pair of 2 elements, first being the index, and second being an element from the source iterable.

itplus_filter.h

Macros for implementing the filter abstraction using the IterFilt struct.

An IterFilt struct is a struct that stores a filtering function within it, as well as the source iterable.

itplus_filtermap.h

Macros for implementing the filter_map abstraction using the IterFiltMap struct.

An IterFiltMap struct is a struct that stores a filter-mapping function within it, as well as the source iterable. The filter-mapping function is just a function that returns a Maybe(T). A Just value indicates that the raw value should be kept, a Nothing value indicates it should be filtered out.

itplus_fold.h

Macros for implementing the foldl abstraction.

itplus_foreach.h

Definition of the foreach macro. Used to iterate through an Iterable.

itplus_iterator.h

Utilities to define and implement an Iterable.

itplus_macro_utils.h

General utility macros.

itplus_map.h

Macros for implementing the map abstraction using the IterMap struct.

An IterMap struct is a struct that stores a mapping function within it, as well as the source iterable.

itplus_maybe.h

Utilities to define and use a Maybe type.

An IterMap struct is a struct that stores a mapping function within it, as well as the source iterable.

itplus_pair.h

Utilities to define and use a Pair type. A Tuple of 2 elements.

itplus_reduce.h

Macros for implementing the reduce/foldl1 abstraction.

itplus_take.h

Macros for implementing the take abstraction using the IterTake struct.

An IterTake struct is a struct that keeps track of how many elements have been extracted out of an iterator as well as a limit to stop at - the iterator impl for this struct will keep consuming from an iterator until it hits that limit, or until the source iterable gets exhausted, whichever comes first.

itplus_takewhile.h

Macros for implementing the takeWhile abstraction using the IterTakeWhile struct.

An IterTakeWhile struct is a struct that stores a source iterable, a predicate function, and a flag to indicate when to stop testing with the predicate function. It keeps consuming from the source iterable, and stops once the predicate returns false.

itplus_typeclass.h

Utilities to define a typeclass and its instance.

itplus_zip.h

Macros for implementing the zip abstraction using the IterZip struct.

An IterZip struct is a struct that stores 2 iterables, and has a next function implementation that returns a Pair of 2 elements, each from the 2 iterables.

tests

The tests/ directory contains usage tests (essentially examples) for the library.

File Description

common.h

Declarations of iterator and iterplus structs used in the test executable.

impls.h

Declarations of utilities, structs, and functions for which iterator and iterplus utilities have been implemented.

impls.c

Implementations of iterables and iterplus utilities.

main.c

The main test executable using all the iterplus utilities.

preproc_map.h

Macro to map over a given function/macro over VA_ARGS - supports upto 8 arguments.

sugar.h

"Syntactic sugar". Convenience macros for using the iterplus utilities.

The examples use C11's _Generic to statically dispatch to the correct functions based on the type of the iterplus structs. Syntax sugar, as you may know them. These are the definitions of those sugar macros.

Essentially, wrapper functions are defined, which take a pre-allocated iterplus struct (of a specific type), the iterable to put into said struct (and other stuff if necessary), and return an Iterable corresponding to that iterplus struct. _Generic then statically dispatches to these functions.

These wrapper functions are defined in sugar.c.

The structure pre-allocation and passing to this functions is done in the _Generic macros by taking the address of a compound literal. The iterable struct, and other such members that have a varying type cannot be filled up inside the _Generic assoc list expressions, which is why the functions need to do it for us.

sugar.c

Wrapper functions to fill pre-allocated iterplus structs of specific types, and turn them into Iterables.

samples

This is more or less a subset of tests. It contains examples of solving 2 problems-

  • Finding longest common prefix of a string array
  • Calculating the dot product of 2 arrays and then summing it.