tag_scalar.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /*
  2. libnbt++ - A library for the Minecraft Named Binary Tag format.
  3. Copyright (C) 2013 ljfa-ag
  4. This file is part of libnbt++.
  5. libnbt++ is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. libnbt++ is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with libnbt++. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #ifndef TAG_SCALAR_H_INCLUDED
  17. #define TAG_SCALAR_H_INCLUDED
  18. #include "endian_str.h"
  19. #include "tag_base.h"
  20. #include <type_traits>
  21. namespace nbt
  22. {
  23. namespace detail //Forward declaration.
  24. { template<class S> struct get_scalar_type; }
  25. /**
  26. * \brief Contains an integral or floating-point number.
  27. *
  28. * Common class for tag_byte, tag_short, tag_int, tag_long, tag_float and tag_double.
  29. */
  30. template<class S> class tag_scalar : public tag
  31. {
  32. public:
  33. ///The type of the value.
  34. typedef S value_type;
  35. ///The type of the tag.
  36. static constexpr tag_type type = detail::get_scalar_type<S>::value;
  37. ///Scalar constructor
  38. explicit tag_scalar(S val = 0): value(val) {}
  39. tag_type get_type() const noexcept { return type; }
  40. void print(std::ostream& os) const;
  41. value_type value;
  42. protected:
  43. void write_payload(std::ostream& os) const
  44. { endian::write_big(os, value); }
  45. };
  46. //Typedefs that should be used instead of the template tag_scalar.
  47. typedef tag_scalar<int8_t> tag_byte;
  48. typedef tag_scalar<int16_t> tag_short;
  49. typedef tag_scalar<int32_t> tag_int;
  50. typedef tag_scalar<int64_t> tag_long;
  51. typedef tag_scalar<float> tag_float;
  52. typedef tag_scalar<double> tag_double;
  53. namespace detail
  54. {
  55. template<> struct get_scalar_type<int8_t> : std::integral_constant<tag::tag_type, tag::tag_type::_byte> {};
  56. template<> struct get_scalar_type<int16_t> : std::integral_constant<tag::tag_type, tag::tag_type::_short> {};
  57. template<> struct get_scalar_type<int32_t> : std::integral_constant<tag::tag_type, tag::tag_type::_int> {};
  58. template<> struct get_scalar_type<int64_t> : std::integral_constant<tag::tag_type, tag::tag_type::_long> {};
  59. template<> struct get_scalar_type<float> : std::integral_constant<tag::tag_type, tag::tag_type::_float> {};
  60. template<> struct get_scalar_type<double> : std::integral_constant<tag::tag_type, tag::tag_type::_double> {};
  61. }
  62. template<class S> inline void tag_scalar<S>::print(std::ostream& os) const
  63. { os << type << '(' << value << ')'; }
  64. //Specialization for tag_byte, so a number is printed into the stream and not a character.
  65. template<> inline void tag_scalar<int8_t>::print(std::ostream& os) const
  66. { os << "byte(" << static_cast<int>(value) << ')'; }
  67. }
  68. #endif // TAG_SCALAR_H_INCLUDED