Skip to content

Instantly share code, notes, and snippets.

@shortthefomo
Created November 27, 2025 12:36
Show Gist options
  • Select an option

  • Save shortthefomo/ccf5282137a9183e292a46014df27b0e to your computer and use it in GitHub Desktop.

Select an option

Save shortthefomo/ccf5282137a9183e292a46014df27b0e to your computer and use it in GitHub Desktop.
Generate all possible combinations of composable flags
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <math.h>
/**
* @brief Generate all possible combinations of composable flags
*
* @param flags Array of flag values to combine
* @param flag_count Number of flags in the input array
* @param output_combinations Pointer to store the resulting combinations array
* @param output_count Pointer to store the number of combinations generated
* @return int 0 on success, -1 on failure
*/
int xrpl_generate_flag_combinations(
const uint32_t* flags,
size_t flag_count,
uint32_t** output_combinations,
size_t* output_count
) {
if (flags == NULL || output_combinations == NULL || output_count == NULL) {
return -1;
}
// Calculate total combinations: 2^flag_count
size_t total_combinations = (size_t)pow(2, flag_count);
// Allocate memory for output array
*output_combinations = (uint32_t*)malloc(total_combinations * sizeof(uint32_t));
if (*output_combinations == NULL) {
return -1;
}
// Generate all combinations using bitwise operations
for (size_t i = 0; i < total_combinations; i++) {
uint32_t combination = 0;
// Check each bit position
for (size_t j = 0; j < flag_count; j++) {
// If bit j is set in i, include flag j in the combination
if (i & (1 << j)) {
combination |= flags[j];
}
}
(*output_combinations)[i] = combination;
}
*output_count = total_combinations;
return 0;
}
/**
* @brief Filter combinations by a specific flag presence
*
* @param combinations Array of all combinations
* @param combination_count Number of combinations
* @param required_flag Flag that must be present
* @param output_filtered Pointer to store filtered combinations
* @param output_filtered_count Pointer to store count of filtered combinations
* @return int 0 on success, -1 on failure
*/
int xrpl_filter_flag_combinations(
const uint32_t* combinations,
size_t combination_count,
uint32_t required_flag,
uint32_t** output_filtered,
size_t* output_filtered_count
) {
if (combinations == NULL || output_filtered == NULL || output_filtered_count == NULL) {
return -1;
}
// First pass: count matching combinations
size_t match_count = 0;
for (size_t i = 0; i < combination_count; i++) {
if (combinations[i] & required_flag) {
match_count++;
}
}
// Allocate memory for filtered results
*output_filtered = (uint32_t*)malloc(match_count * sizeof(uint32_t));
if (*output_filtered == NULL && match_count > 0) {
return -1;
}
// Second pass: copy matching combinations
size_t index = 0;
for (size_t i = 0; i < combination_count; i++) {
if (combinations[i] & required_flag) {
(*output_filtered)[index++] = combinations[i];
}
}
*output_filtered_count = match_count;
return 0;
}
/**
* @brief Check if a combination contains a specific flag
*
* @param combination The combined flag value
* @param flag The flag to check for
* @return int 1 if flag is present, 0 otherwise
*/
int xrpl_has_flag(uint32_t combination, uint32_t flag) {
return (combination & flag) == flag;
}
// Example usage and test function
#ifdef XRPL_FLAG_COMBINATIONS_TEST
int main(void) {
// XRPL Payment flags (excluding deprecated tfFullyCanonicalSig)
uint32_t payment_flags[] = {
0x00010000, // tfNoDirectRipple (65536)
0x00020000, // tfPartialPayment (131072)
0x00040000 // tfLimitQuality (262144)
};
size_t flag_count = sizeof(payment_flags) / sizeof(payment_flags[0]);
uint32_t* combinations = NULL;
size_t combination_count = 0;
// Generate all combinations
if (xrpl_generate_flag_combinations(payment_flags, flag_count, &combinations, &combination_count) != 0) {
fprintf(stderr, "Error generating flag combinations\n");
return 1;
}
printf("Generated %zu flag combinations:\n", combination_count);
for (size_t i = 0; i < combination_count; i++) {
printf(" [%zu] = %u (0x%08X)\n", i, combinations[i], combinations[i]);
}
// Filter for combinations that include tfPartialPayment
uint32_t* partial_combinations = NULL;
size_t partial_count = 0;
if (xrpl_filter_flag_combinations(combinations, combination_count, 0x00020000, &partial_combinations, &partial_count) == 0) {
printf("\nCombinations with tfPartialPayment (%zu):\n", partial_count);
for (size_t i = 0; i < partial_count; i++) {
printf(" %u (0x%08X)\n", partial_combinations[i], partial_combinations[i]);
}
free(partial_combinations);
}
free(combinations);
return 0;
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment