content: package com.annimon.stream.function;
  
  import com.annimon.stream.Objects;
  import org.jetbrains.annotations.NotNull;
  
  /**
   * Represents a {@code boolean}-valued predicate (function with boolean type result).
   *
   * @since 1.1.8
   * @see Predicate
   * @see UnaryOperator
   */
  public interface BooleanPredicate {
  
      /**
       * Tests the value for satisfying predicate.
       *
       * @param value  the value to be tested
       * @return {@code true} if the value matches the predicate, otherwise {@code false}
       */
      boolean test(boolean value);
  
      class Util {
  
          private Util() { }
  
          /**
           * Returns a predicate that always returns its input argument.
           *
           * @return a predicate that always returns its input argument
           */
          public static BooleanPredicate identity() {
              return new BooleanPredicate() {
                  @Override
                  public boolean test(boolean operand) {
                      return operand;
                  }
              };
          }
  
          /**
           * Applies logical AND to predicates.
           *
           * @param p1  the first predicate
           * @param p2  the second predicate
           * @return a composed {@code BooleanPredicate}
           * @throws NullPointerException if {@code p1} or {@code p2} is null
           */
          public static BooleanPredicate and(
                  @NotNull final BooleanPredicate p1,
                  @NotNull final BooleanPredicate p2) {
              Objects.requireNonNull(p1, "predicate1");
              Objects.requireNonNull(p2, "predicate2");
              return new BooleanPredicate() {
                  @Override
                  public boolean test(boolean value) {
                      return p1.test(value) && p2.test(value);
                  }
              };
          }
  
          /**
           * Applies logical OR to predicates.
           *
           * @param p1  the first predicate
           * @param p2  the second predicate
           * @return a composed {@code BooleanPredicate}
           * @throws NullPointerException if {@code p1} or {@code p2} is null
           */
          public static BooleanPredicate or(
                  @NotNull final BooleanPredicate p1,
                  @NotNull final BooleanPredicate p2) {
              Objects.requireNonNull(p1, "predicate1");
              Objects.requireNonNull(p2, "predicate2");
              return new BooleanPredicate() {
                  @Override
                  public boolean test(boolean value) {
                      return p1.test(value) || p2.test(value);
                  }
              };
          }
  
          /**
           * Applies logical XOR to predicates.
           *
           * @param p1  the first predicate
           * @param p2  the second predicate
           * @return a composed {@code BooleanPredicate}
           * @throws NullPointerException if {@code p1} or {@code p2} is null
           */
          public static BooleanPredicate xor(
                  @NotNull final BooleanPredicate p1,
                  @NotNull final BooleanPredicate p2) {
              Objects.requireNonNull(p1, "predicate1");
              Objects.requireNonNull(p2, "predicate2");
              return new BooleanPredicate() {
                  @Override
                  public boolean test(boolean value) {
                      return p1.test(value) ^ p2.test(value);
                  }
              };
          }
  
          /**
           * Applies logical negation to predicate.
           *
           * @param p1  the predicate to be negated
           * @return a composed {@code BooleanPredicate}
           * @throws NullPointerException if {@code p1} is null
           */
          public static BooleanPredicate negate(@NotNull final BooleanPredicate p1) {
              Objects.requireNonNull(p1);
              return new BooleanPredicate() {
                  @Override
                  public boolean test(boolean value) {
                      return !p1.test(value);
                  }
              };
          }
  
      }
  }
  