فهرست منبع

Added Float boxing class

- implemented Float boxing class for wrapping primitive float data
type.
- added tests for Float class
pcmattulat 4 سال پیش
والد
کامیت
264d307e4c
4فایلهای تغییر یافته به همراه586 افزوده شده و 2 حذف شده
  1. 4 2
      CMakeLists.txt
  2. 181 0
      source/boxing/Float.cpp
  3. 93 0
      source/boxing/Float.hpp
  4. 308 0
      test/cases/boxing/FloatTest.cpp

+ 4 - 2
CMakeLists.txt

@@ -41,11 +41,13 @@ set(SOURCE_FILES
         ${CMAKE_CURRENT_SOURCE_DIR}/source/base/Types.hpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/boxing/Boolean.hpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/boxing/Boolean.cpp
-        ${CMAKE_CURRENT_SOURCE_DIR}/source/exception/IllegalArgumentException.hpp)
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/exception/IllegalArgumentException.hpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/boxing/Float.hpp source/boxing/Float.cpp)
 
 set(TEST_FILES
         ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/boxing/IntegerTest.cpp
-        ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/boxing/BooleanTest.cpp)
+        ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/boxing/BooleanTest.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/boxing/FloatTest.cpp)
 
 ##########################################################
 # Build

+ 181 - 0
source/boxing/Float.cpp

@@ -0,0 +1,181 @@
+/*
+ * Author:          Patrick-Christopher Mattulat
+ * Company:         Lynar Studios
+ * E-Mail:          webmaster@lynarstudios.com
+ * Created:         2020-08-14
+ * Changed:         2020-08-14
+ *
+ * */
+
+#include <cmath>
+#include "Float.hpp"
+
+ls_std::Float::Float() : Class("Float"),
+epsilon(0.00001f)
+{}
+
+ls_std::Float::Float(float _value) : Class("Float"),
+epsilon(0.00001f),
+value(_value)
+{}
+
+ls_std::Float::operator float() const {
+  return this->value;
+}
+
+ls_std::Float & ls_std::Float::operator=(float _value) {
+  this->value = _value;
+  return *this;
+}
+
+float ls_std::Float::operator-() const {
+  return -this->value;
+}
+
+float ls_std::Float::operator+(const Float &_float) const {
+  return this->value + _float;
+}
+
+float ls_std::Float::operator+(float _value) const {
+  return this->value + _value;
+}
+
+float ls_std::Float::operator*(const Float &_float) const {
+  return this->value * _float;
+}
+
+float ls_std::Float::operator*(float _value) const {
+  return this->value * _value;
+}
+
+float ls_std::Float::operator-(const Float &_float) const {
+  return this->value - _float;
+}
+
+float ls_std::Float::operator-(float _value) const {
+  return this->value - _value;
+}
+
+float ls_std::Float::operator/(const Float &_float) const {
+  return this->value / _float;
+}
+
+float ls_std::Float::operator/(float _value) const {
+  return this->value / _value;
+}
+
+ls_std::Float & ls_std::Float::operator+=(const Float &_float) {
+  this->value += _float;
+  return *this;
+}
+
+ls_std::Float & ls_std::Float::operator+=(float _value) {
+  this->value += _value;
+  return *this;
+}
+
+ls_std::Float & ls_std::Float::operator-=(const Float &_float) {
+  this->value -= _float;
+  return *this;
+}
+
+ls_std::Float & ls_std::Float::operator-=(float _value) {
+  this->value -= _value;
+  return *this;
+}
+
+ls_std::Float & ls_std::Float::operator*=(const Float &_float) {
+  this->value *= _float;
+  return *this;
+}
+
+ls_std::Float & ls_std::Float::operator*=(float _value) {
+  this->value *= _value;
+  return *this;
+}
+
+ls_std::Float & ls_std::Float::operator/=(const Float &_float) {
+  this->value /= _float;
+  return *this;
+}
+
+ls_std::Float & ls_std::Float::operator/=(float _value) {
+  this->value /= _value;
+  return *this;
+}
+
+bool ls_std::Float::operator==(const Float &_float) const {
+  return std::fabs(this->value - _float) < this->epsilon;
+}
+
+bool ls_std::Float::operator==(float _value) const {
+  return std::fabs(this->value - _value) < this->epsilon;
+}
+
+bool ls_std::Float::operator!=(const Float &_float) const {
+  return std::fabs(this->value - _float) >= this->epsilon;
+}
+
+bool ls_std::Float::operator!=(float _value) const {
+  return std::fabs(this->value - _value) >= this->epsilon;
+}
+
+bool ls_std::Float::operator>(const Float &_float) const {
+  return this->value > _float;
+}
+
+bool ls_std::Float::operator>(float _value) const {
+  return this->value > _value;
+}
+
+bool ls_std::Float::operator>=(const Float &_float) const {
+  return this->value >= _float;
+}
+
+bool ls_std::Float::operator>=(float _value) const {
+  return this->value >= _value;
+}
+
+bool ls_std::Float::operator<(const Float &_float) const {
+  return this->value < _float;
+}
+
+bool ls_std::Float::operator<(float _value) const {
+  return this->value < _value;
+}
+
+bool ls_std::Float::operator<=(const Float &_float) const {
+  return this->value <= _float;
+}
+
+bool ls_std::Float::operator<=(float _value) const {
+  return this->value <= _value;
+}
+
+void ls_std::Float::operator++() {
+  this->value += 1.0f;
+}
+
+void ls_std::Float::operator--() {
+  this->value -= 1.0f;
+}
+
+void ls_std::Float::parse(std::string parseText) {
+  this->value = std::stof(parseText);
+}
+
+std::string ls_std::Float::toString() {
+  return std::to_string(this->value);
+}
+
+float ls_std::Float::getEpsilon() {
+  return this->epsilon;
+}
+
+float ls_std::Float::getValue() {
+  return this->value;
+}
+
+void ls_std::Float::setEpsilon(float _epsilon) {
+  this->epsilon = _epsilon;
+}

+ 93 - 0
source/boxing/Float.hpp

@@ -0,0 +1,93 @@
+/*
+ * Author:          Patrick-Christopher Mattulat
+ * Company:         Lynar Studios
+ * E-Mail:          webmaster@lynarstudios.com
+ * Created:         2020-08-14
+ * Changed:         2020-08-14
+ *
+ * */
+
+#ifndef FLOAT_HPP
+#define FLOAT_HPP
+
+#include "../base/Class.hpp"
+#include "IBoxing.hpp"
+
+namespace ls_std {
+  class Float : public Class, IBoxing {
+    public:
+
+      Float();
+      explicit Float(float _value);
+      ~Float() = default;
+
+      // conversion operator
+
+      operator float() const; // do not make explicit!
+
+      // assignment operators
+
+      Float& operator=(float _value);
+
+      // arithmetic operators
+
+      float operator-() const;
+      float operator+(const Float& _float) const;
+      float operator+(float _value) const;
+      float operator*(const Float& _float) const;
+      float operator*(float _value) const;
+      float operator-(const Float& _float) const;
+      float operator-(float _value) const;
+      float operator/(const Float& _float) const;
+      float operator/(float _value) const;
+
+      // compound operators
+
+      Float& operator+=(const Float& _float);
+      Float& operator+=(float _value);
+      Float& operator-=(const Float& _float);
+      Float& operator-=(float _value);
+      Float& operator*=(const Float& _float);
+      Float& operator*=(float _value);
+      Float& operator/=(const Float& _float);
+      Float& operator/=(float _value);
+
+      // comparison operators
+
+      bool operator==(const Float& _float) const;
+      bool operator==(float _value) const;
+      bool operator!=(const Float& _float) const;
+      bool operator!=(float _value) const;
+      bool operator>(const Float& _float) const;
+      bool operator>(float _value) const;
+      bool operator>=(const Float& _float) const;
+      bool operator>=(float _value) const;
+      bool operator<(const Float& _float) const;
+      bool operator<(float _value) const;
+      bool operator<=(const Float& _float) const;
+      bool operator<=(float _value) const;
+
+      // increment / decrement operator
+
+      void operator++();
+      void operator--();
+
+      // implementation
+
+      void parse(std::string parseText) override;
+      std::string toString() override;
+
+      // additional functionality
+
+      float getEpsilon();
+      float getValue();
+      void setEpsilon(float _epsilon);
+
+    private:
+
+      float value {};
+      float epsilon {};
+  };
+}
+
+#endif

+ 308 - 0
test/cases/boxing/FloatTest.cpp

@@ -0,0 +1,308 @@
+/*
+ * Author:          Patrick-Christopher Mattulat
+ * Company:         Lynar Studios
+ * E-Mail:          webmaster@lynarstudios.com
+ * Created:         2020-08-14
+ * Changed:         2020-08-14
+ *
+ * */
+
+#include <gtest/gtest.h>
+#include "../../../source/boxing/Float.hpp"
+
+namespace {
+  class FloatTest : public ::testing::Test {
+    protected:
+
+      FloatTest() = default;
+      ~FloatTest() override = default;
+
+      void SetUp() override {}
+      void TearDown() override {}
+  };
+
+  // assignment operators
+
+  TEST_F(FloatTest, operatorAssignment)
+  {
+    ls_std::Float x {13.023f};
+    ASSERT_EQ(13.023f, x);
+
+    x = 44.22f;
+    ASSERT_EQ(44.22f, x);
+
+    ls_std::Float y {3.0f};
+    x = y;
+    ASSERT_EQ(3.0f, x);
+  }
+
+  // arithmetic operators
+
+  TEST_F(FloatTest, operatorHyphen)
+  {
+    ls_std::Float x {3.25f};
+    ASSERT_FLOAT_EQ(-3.25f, -x);
+  }
+
+  TEST_F(FloatTest, operatorAddition)
+  {
+    ls_std::Float x {3.1415f};
+    ls_std::Float y {2.223f};
+    ls_std::Float z {x + y};
+
+    ASSERT_FLOAT_EQ(5.3645f, z);
+    ASSERT_FLOAT_EQ(5.3645f, x + 2.223f);
+  }
+
+  TEST_F(FloatTest, operatorMultiplication)
+  {
+    ls_std::Float x {3.14f};
+    ls_std::Float y {2.22f};
+    ls_std::Float z {x * y};
+
+    ASSERT_FLOAT_EQ(6.9708f, z);
+    ASSERT_FLOAT_EQ(6.9708f, x * 2.22f);
+  }
+
+  TEST_F(FloatTest, operatorSubstraction)
+  {
+    ls_std::Float x {3.1415f};
+    ls_std::Float y {2.225f};
+    ls_std::Float z {x - y};
+
+    ASSERT_FLOAT_EQ(0.9165f, z);
+    ASSERT_FLOAT_EQ(0.9165f, x - 2.225f);
+  }
+
+  TEST_F(FloatTest, operatorDivision)
+  {
+    ls_std::Float x {2.25f};
+    ls_std::Float y {0.5f};
+    ls_std::Float z {x / y};
+
+    ASSERT_FLOAT_EQ(4.5f, z);
+    ASSERT_FLOAT_EQ(4.5f, x / 0.5f);
+  }
+
+  // compound operators
+
+  TEST_F(FloatTest, operatorAddEqual)
+  {
+    ls_std::Float x {2.25f};
+    ls_std::Float y {-0.39f};
+    ASSERT_FLOAT_EQ(2.25f, x);
+
+    x += 3.14f;
+    ASSERT_FLOAT_EQ(5.39f, x);
+
+    x += y;
+    ASSERT_FLOAT_EQ(5.0f, x);
+  }
+
+  TEST_F(FloatTest, operatorSubEqual)
+  {
+    ls_std::Float x {2.25f};
+    ls_std::Float y {-0.04f};
+    ASSERT_FLOAT_EQ(2.25f, x);
+
+    x -= 1.14f;
+    ASSERT_FLOAT_EQ(1.11f, x);
+
+    x -= y;
+    ASSERT_FLOAT_EQ(1.15f, x);
+  }
+
+  TEST_F(FloatTest, operatorMulEqual)
+  {
+    ls_std::Float x {2.25f};
+    ls_std::Float y {0.04f};
+    ASSERT_FLOAT_EQ(2.25f, x);
+
+    x *= 1.14f;
+    ASSERT_FLOAT_EQ(2.565f, x);
+
+    x *= y;
+    ASSERT_FLOAT_EQ(0.1026f, x);
+  }
+
+  TEST_F(FloatTest, operatorDivEqual)
+  {
+    ls_std::Float x {2.25f};
+    ls_std::Float y {1.5f};
+    ASSERT_FLOAT_EQ(2.25f, x);
+
+    x /= 0.05f;
+    ASSERT_FLOAT_EQ(45.0f, x);
+
+    x /= y;
+    ASSERT_FLOAT_EQ(30.0f, x);
+  }
+
+  // comparison operators
+
+  TEST_F(FloatTest, operatorEqual)
+  {
+    ls_std::Float x {3.14159f};
+    ls_std::Float y {3.14159f};
+
+    ASSERT_TRUE(x == y);
+    ASSERT_TRUE(y == x);
+    ASSERT_TRUE(x == 3.14159f);
+    ASSERT_TRUE(3.14159f == x);
+  }
+
+  TEST_F(FloatTest, operatorNotEqual)
+  {
+    ls_std::Float x {3.1415f};
+    ls_std::Float y {3.1414f};
+
+    ASSERT_TRUE(x != y);
+    ASSERT_TRUE(y != x);
+    ASSERT_TRUE(x != 3.1414f);
+    ASSERT_TRUE(3.1414 != x);
+  }
+
+  TEST_F(FloatTest, operatorGreaterThan)
+  {
+    ls_std::Float x {3.1415f};
+    ls_std::Float y {3.1414f};
+
+    ASSERT_TRUE(x > y);
+    ASSERT_TRUE(x > 3.1414f);
+  }
+
+  TEST_F(FloatTest, operatorGreaterThanNegative)
+  {
+    ls_std::Float x {3.1414f};
+    ls_std::Float y {3.1414f};
+
+    ASSERT_FALSE(x > y);
+    ASSERT_FALSE(x > 3.1414f);
+  }
+
+  TEST_F(FloatTest, operatorGreaterThanEqual)
+  {
+    ls_std::Float x {3.1414f};
+    ls_std::Float y {3.1414f};
+    ls_std::Float z {3.1415f};
+
+    ASSERT_TRUE(x >= y);
+    ASSERT_TRUE(z >= y);
+    ASSERT_TRUE(x >= 3.1414f);
+    ASSERT_TRUE(z >= 3.1414f);
+  }
+
+  TEST_F(FloatTest, operatorGreaterThanEqualNegative)
+  {
+    ls_std::Float x {3.1414f};
+    ls_std::Float y {3.1415f};
+
+    ASSERT_FALSE(x >= y);
+    ASSERT_FALSE(x >= 3.1415f);
+  }
+
+  TEST_F(FloatTest, operatorLessThan)
+  {
+    ls_std::Float x {3.1413f};
+    ls_std::Float y {3.1414f};
+
+    ASSERT_TRUE(x < y);
+    ASSERT_TRUE(x < 3.1414f);
+  }
+
+  TEST_F(FloatTest, operatorLessThanNegative)
+  {
+    ls_std::Float x {3.1414f};
+    ls_std::Float y {3.1414f};
+
+    ASSERT_FALSE(x < y);
+    ASSERT_FALSE(x < 3.1414f);
+  }
+
+  TEST_F(FloatTest, operatorLessThanEqual)
+  {
+    ls_std::Float x {3.1414f};
+    ls_std::Float y {3.1414f};
+    ls_std::Float z {3.1415f};
+
+    ASSERT_TRUE(x <= y);
+    ASSERT_TRUE(x <= z);
+    ASSERT_TRUE(x <= 3.1414f);
+    ASSERT_TRUE(x <= 3.1415f);
+  }
+
+  TEST_F(FloatTest, operatorLessThanEqualNegative)
+  {
+    ls_std::Float x {3.1415f};
+    ls_std::Float y {3.1414f};
+
+    ASSERT_FALSE(x <= y);
+    ASSERT_FALSE(x <= 3.1414f);
+  }
+
+  // increment / decrement operator
+
+  TEST_F(FloatTest, operatorIncrement)
+  {
+    ls_std::Float x {3.1415f};
+    ASSERT_FLOAT_EQ(3.1415f, x);
+
+    ++x;
+    ASSERT_FLOAT_EQ(4.1415f, x);
+
+    ++x;
+    ASSERT_FLOAT_EQ(5.1415f, x);
+  }
+
+  TEST_F(FloatTest, operatorDecrement)
+  {
+    ls_std::Float x {3.1415f};
+    ASSERT_FLOAT_EQ(3.1415f, x);
+
+    --x;
+    ASSERT_FLOAT_EQ(2.1415f, x);
+
+    --x;
+    ASSERT_FLOAT_EQ(1.1415f, x);
+  }
+
+  // implementation
+
+  TEST_F(FloatTest, parse)
+  {
+    ls_std::Float x {};
+
+    x.parse("3.1415f");
+    ASSERT_FLOAT_EQ(3.1415f, x);
+
+    x.parse("-2.1415f");
+    ASSERT_FLOAT_EQ(-2.1415f, x);
+  }
+
+  TEST_F(FloatTest, toString)
+  {
+    ls_std::Float x {13.1543f};
+    ASSERT_TRUE(x.toString().find("13.1543") != std::string::npos);
+  }
+
+  // additional functionality
+
+  TEST_F(FloatTest, getEpsilon)
+  {
+    ls_std::Float x {};
+    ASSERT_FLOAT_EQ(0.00001f, x.getEpsilon());
+  }
+
+  TEST_F(FloatTest, getValue)
+  {
+    ls_std::Float x {3.1415f};
+    ASSERT_FLOAT_EQ(3.1415f, x.getValue());
+  }
+
+  TEST_F(FloatTest, setEpsilon)
+  {
+    ls_std::Float x {};
+    x.setEpsilon(0.01f);
+    ASSERT_FLOAT_EQ(0.01f, x.getEpsilon());
+  }
+}