<commit_before>#ifndef __QUADSET_H__
#define __QUADSET_H__ 1
#include <iostream>
#include <sstream>

// bit_mask returns a uint64 value with nonzero bits from m to n, inclusive.
// Note that is is a different convention from most other interfaces dealing
// with ranges, because it INCLUDES m.
// Requires 0 ≤ m ≤ n < 64.
inline constexpr uint64_t bit_mask(int m, int n) {
  //static_assert(0 <= m, "bit_mask(m,n) requires 0 <= m");
  //static_assert(m <= n, "bit_mask(m,n) requires m <= n");
  //static_assert(n < 64, "bit_mask(m,n) requires n < 64");
  return (~0ULL >> (63+m-n)) << m;
}
    

// quadset is a "set of integer" type similar to std::bitset, but instead of
// being infinitely variable in size, it is restricted to 256 bits at most.
//
// A quadset inherits from one of four template specializations, having
// capacities of 1, 2, 3, or 4 quadwords (i.e., 64, 128, 192, or 256 bits).
//
// All non-lvalue methods pass quadsets by value. If your set is too
// big to be passed by value, consider using std::bitset instead.


// Since the elements of quadsets are constrained to the range [0..255],
// uint8_t would be large enough to store any element. However, -1 and 256 are
// useful as off-the-end inputs, even though they can't be stored in a quadset.
// So instead, we use the next-larger signed type instead.
typedef int_fast16_t bitpos;


// The inheritance hierarchy for quadset<BITS> is as follows (arrows point
// from subclass to superclass):
//<commit_msg>Add comment summarizing the requirements of constexpr functions.<commit_after>#ifndef __QUADSET_H__
#define __QUADSET_H__ 1
#include <iostream>
#include <sstream>

// bit_mask returns a uint64 value with nonzero bits from m to n, inclusive.
// Note that is is a different convention from most other interfaces dealing
// with ranges, because it INCLUDES m.
// Requires 0 ≤ m ≤ n < 64.
inline constexpr uint64_t bit_mask(int m, int n) {
  //static_assert(0 <= m, "bit_mask(m,n) requires 0 <= m");
  //static_assert(m <= n, "bit_mask(m,n) requires m <= n");
  //static_assert(n < 64, "bit_mask(m,n) requires n < 64");
  return (~0ULL >> (63+m-n)) << m;
}
    
// quadset is a "set of [0..n]" type similar to std::bitset, but instead of
// being infinitely variable in size, it is restricted to 256 bits at most.
//
// It is intended that quadsets be constexpr constructible, so that
// methods like left_column() can be evaluated at compile time.
// constexpr is a feature that was added in C++11. For a function to be
// constexpr, the following requirements must be met:
//   1.  The function must have non-void return type. This requirement is
//       trivially met in the case of a constructor.
//   2.  The funciton body canot declare variables or define new types.
//   3.  The body may only contain declarations, null statements, and a single
//       return statement.
//   4a. [non-constructor] There must exist argument values such that, after
//       argument substitution, the expression in the return statement produces
//       a constant expression.
//   4b. [constructor] There must exist argument values such that, after
//       argument substitution, it initializes the class's members with
//       constant expressions.
//   5.  [constructor] The destructors for the types must be trivial.
// Constexpr member functions are implicitly const (relative to ‹this›).
//
// C++14 relaxed some of the constexpr constraints.
//   1.  Declarations are now permitted, except for ‹static› or ‹thread_local›
//       variables, and variable declarations without intializers.
//   2.  ‹goto› statements are forbidden.
//   3.  ‹if› and ‹switch› are permitted.
//   3.  All looping statements are permitted, including range-based ‹for›.
//   4.  Expressions may change the value of an object if the lifetime of that
//       object began within the constant expression function. This includes
//       calls to any non-‹const› ‹constexpr›-declared non-static member
//       functions.
// In C++14, constexpr member functions can be non-‹const› (relative to ‹this›).
// However, a non-‹const› ‹constexpr› member function can only modify a class
// member if that object's lifetime began within the constant expression
// evaluation.

// A quadset inherits from one of four template specializations, having
// capacities of 1, 2, 3, or 4 quadwords (i.e., 64, 128, 192, or 256 bits).
//
// All non-lvalue methods pass quadsets by value. If your set is too
// big to be passed by value, consider using std::bitset instead.


// Since the elements of quadsets are constrained to the range [0..255],
// uint8_t would be large enough to store any element. However, -1 and 256 are
// useful as off-the-end inputs, even though they can't be stored in a quadset.
// So instead, we use the next-larger signed type instead.
typedef int_fast16_t bitpos;


// The inheritance hierarchy for quadset<BITS> is as follows (arrows point
// from subclass to superclass):
//
{'fraction_non_alphanumeric': 0.10048524059846341, 'fraction_numerical': 0.022240194096239386, 'mean_word_length': 3.3471001757469243, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1953450', 'n_tokens_mistral': 1538, 'n_tokens_neox': 1432, 'n_words': 685}