// Copyright 2020 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "absl/base/optimization.h"

#include <optional>

#include "gtest/gtest.h"

namespace {

// Tests for the ABSL_PREDICT_TRUE and ABSL_PREDICT_FALSE macros.
// The tests only verify that the macros are functionally correct - i.e. code
// behaves as if they weren't used. They don't try to check their impact on
// optimization.

TEST(PredictTest, PredictTrue) {
  EXPECT_TRUE(ABSL_PREDICT_TRUE(true));
  EXPECT_FALSE(ABSL_PREDICT_TRUE(false));
  EXPECT_TRUE(ABSL_PREDICT_TRUE(1 == 1));
  EXPECT_FALSE(ABSL_PREDICT_TRUE(1 == 2));

  if (ABSL_PREDICT_TRUE(false)) ADD_FAILURE();
  if (!ABSL_PREDICT_TRUE(true)) ADD_FAILURE();

  EXPECT_TRUE(ABSL_PREDICT_TRUE(true) && true);
  EXPECT_TRUE(ABSL_PREDICT_TRUE(true) || false);
}

TEST(PredictTest, PredictFalse) {
  EXPECT_TRUE(ABSL_PREDICT_FALSE(true));
  EXPECT_FALSE(ABSL_PREDICT_FALSE(false));
  EXPECT_TRUE(ABSL_PREDICT_FALSE(1 == 1));
  EXPECT_FALSE(ABSL_PREDICT_FALSE(1 == 2));

  if (ABSL_PREDICT_FALSE(false)) ADD_FAILURE();
  if (!ABSL_PREDICT_FALSE(true)) ADD_FAILURE();

  EXPECT_TRUE(ABSL_PREDICT_FALSE(true) && true);
  EXPECT_TRUE(ABSL_PREDICT_FALSE(true) || false);
}

TEST(PredictTest, OneEvaluation) {
  // Verify that the expression is only evaluated once.
  int x = 0;
  if (ABSL_PREDICT_TRUE((++x) == 0)) ADD_FAILURE();
  EXPECT_EQ(x, 1);
  if (ABSL_PREDICT_FALSE((++x) == 0)) ADD_FAILURE();
  EXPECT_EQ(x, 2);
}

TEST(PredictTest, OperatorOrder) {
  // Verify that operator order inside and outside the macro behaves well.
  // These would fail for a naive '#define ABSL_PREDICT_TRUE(x) x'
  EXPECT_TRUE(ABSL_PREDICT_TRUE(1 && 2) == true);
  EXPECT_TRUE(ABSL_PREDICT_FALSE(1 && 2) == true);
  EXPECT_TRUE(!ABSL_PREDICT_TRUE(1 == 2));
  EXPECT_TRUE(!ABSL_PREDICT_FALSE(1 == 2));
}

TEST(PredictTest, Pointer) {
  const int x = 3;
  const int *good_intptr = &x;
  const int *null_intptr = nullptr;
  EXPECT_TRUE(ABSL_PREDICT_TRUE(good_intptr));
  EXPECT_FALSE(ABSL_PREDICT_TRUE(null_intptr));
  EXPECT_TRUE(ABSL_PREDICT_FALSE(good_intptr));
  EXPECT_FALSE(ABSL_PREDICT_FALSE(null_intptr));
}

TEST(PredictTest, Optional) {
  // Note: An optional's truth value is the value's existence, not its truth.
  std::optional<bool> has_value(false);
  std::optional<bool> no_value;
  EXPECT_TRUE(ABSL_PREDICT_TRUE(has_value));
  EXPECT_FALSE(ABSL_PREDICT_TRUE(no_value));
  EXPECT_TRUE(ABSL_PREDICT_FALSE(has_value));
  EXPECT_FALSE(ABSL_PREDICT_FALSE(no_value));
}

class ImplicitlyConvertibleToBool {
 public:
  explicit ImplicitlyConvertibleToBool(bool value) : value_(value) {}
  operator bool() const {  // NOLINT(google-explicit-constructor)
    return value_;
  }

 private:
  bool value_;
};

TEST(PredictTest, ImplicitBoolConversion) {
  const ImplicitlyConvertibleToBool is_true(true);
  const ImplicitlyConvertibleToBool is_false(false);
  if (!ABSL_PREDICT_TRUE(is_true)) ADD_FAILURE();
  if (ABSL_PREDICT_TRUE(is_false)) ADD_FAILURE();
  if (!ABSL_PREDICT_FALSE(is_true)) ADD_FAILURE();
  if (ABSL_PREDICT_FALSE(is_false)) ADD_FAILURE();
}

class ExplicitlyConvertibleToBool {
 public:
  explicit ExplicitlyConvertibleToBool(bool value) : value_(value) {}
  explicit operator bool() const { return value_; }

 private:
  bool value_;
};

TEST(PredictTest, ExplicitBoolConversion) {
  const ExplicitlyConvertibleToBool is_true(true);
  const ExplicitlyConvertibleToBool is_false(false);
  if (!ABSL_PREDICT_TRUE(is_true)) ADD_FAILURE();
  if (ABSL_PREDICT_TRUE(is_false)) ADD_FAILURE();
  if (!ABSL_PREDICT_FALSE(is_true)) ADD_FAILURE();
  if (ABSL_PREDICT_FALSE(is_false)) ADD_FAILURE();
}

// This verifies that ABSL_ASSUME compiles in a variety of contexts.
// It does not test optimization.
TEST(AbslAssume, Compiles) {
  int x = 0;
  ABSL_ASSUME(x >= 0);
  EXPECT_EQ(x, 0);

  // https://github.com/abseil/abseil-cpp/issues/1814
  ABSL_ASSUME(x >= 0), (x >= 0) ? ++x : --x;
  EXPECT_EQ(x, 1);
}

}  // namespace
