This is an automated email from the ASF dual-hosted git repository.

jbarrett pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode-native.git


The following commit(s) were added to refs/heads/develop by this push:
     new 1bbac3f  GEODE-5025: Uses templates to define Cacheable types (#366)
1bbac3f is described below

commit 1bbac3f5e22a3ecdf8ca4eebfce64fdd8d2732fc
Author: Jacob Barrett <[email protected]>
AuthorDate: Fri Oct 5 10:46:00 2018 -0700

    GEODE-5025: Uses templates to define Cacheable types (#366)
    
    * Converts CacheableKeyType into CacheableKeyPrimitive template.
    
    * Converts CacheableContainerType into CacheableContainerPrimitive template.
    
    * Move templates internal.
    
    *  Cleanup equals operator
    
    * Workaround for MSVC limits
---
 CMakeLists.txt                                     |   3 +-
 clicache/src/CacheableBuiltins.hpp                 |  16 +-
 cppcache/include/geode/CacheableBuiltins.hpp       | 486 +++++++++------------
 .../geode/internal/CacheableBuiltinTemplates.hpp   | 218 +++++++++
 .../testThinClientSecurityAuthorizationMU.cpp      |   1 -
 cppcache/src/PdxInstanceFactory.cpp                |   3 +-
 cppcache/src/PdxInstanceImpl.cpp                   |   5 +-
 cppcache/src/SerializationRegistry.hpp             |   2 +
 8 files changed, 428 insertions(+), 306 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index e1e1d71..a8a556f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -261,11 +261,10 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
 
   target_compile_options(_WarningsAsError INTERFACE
     /WX
+       /wd4996
        /wd4068 # TODO fix
        )
 
-  # TODO error on warnings
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4996")
   set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ignore:4099")
   set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /ignore:4099")
 
diff --git a/clicache/src/CacheableBuiltins.hpp 
b/clicache/src/CacheableBuiltins.hpp
index 5c884b4..94bcf0e 100644
--- a/clicache/src/CacheableBuiltins.hpp
+++ b/clicache/src/CacheableBuiltins.hpp
@@ -570,49 +570,49 @@ namespace Apache
       /// An immutable wrapper for byte arrays that can serve
       /// as a distributable object for caching.
       /// </summary>
-      using CacheableBytes = CacheableArray<native::CacheableArray<int8_t, 
native::internal::DSCode::CacheableBytes>, Byte, 
static_cast<int8_t>(DSCode::CacheableBytes)>;
+      using CacheableBytes = 
CacheableArray<native::internal::CacheableArrayPrimitive<int8_t, 
native::internal::DSCode::CacheableBytes>, Byte, 
static_cast<int8_t>(DSCode::CacheableBytes)>;
 
       /// <summary>
       /// An immutable wrapper for array of doubles that can serve
       /// as a distributable object for caching.
       /// </summary>
-      using CacheableDoubleArray = 
CacheableArray<native::CacheableArray<double, 
native::internal::DSCode::CacheableDoubleArray>, Double, 
static_cast<int8_t>(DSCode::CacheableDoubleArray)>;
+      using CacheableDoubleArray = 
CacheableArray<native::internal::CacheableArrayPrimitive<double, 
native::internal::DSCode::CacheableDoubleArray>, Double, 
static_cast<int8_t>(DSCode::CacheableDoubleArray)>;
 
       /// <summary>
       /// An immutable wrapper for array of floats that can serve
       /// as a distributable object for caching.
       /// </summary>
-      using CacheableFloatArray = CacheableArray<native::CacheableArray<float, 
native::internal::DSCode::CacheableFloatArray>, Single, 
static_cast<int8_t>(DSCode::CacheableFloatArray)>;
+      using CacheableFloatArray = 
CacheableArray<native::internal::CacheableArrayPrimitive<float, 
native::internal::DSCode::CacheableFloatArray>, Single, 
static_cast<int8_t>(DSCode::CacheableFloatArray)>;
 
       /// <summary>
       /// An immutable wrapper for array of 16-bit integers that can serve
       /// as a distributable object for caching.
       /// </summary>
-      using CacheableInt16Array = 
CacheableArray<native::CacheableArray<int16_t, 
native::internal::DSCode::CacheableInt16Array>, System::Int16, 
static_cast<int8_t>(DSCode::CacheableInt16Array)>;
+      using CacheableInt16Array = 
CacheableArray<native::internal::CacheableArrayPrimitive<int16_t, 
native::internal::DSCode::CacheableInt16Array>, System::Int16, 
static_cast<int8_t>(DSCode::CacheableInt16Array)>;
 
       /// <summary>
       /// An immutable wrapper for array of 32-bit integers that can serve
       /// as a distributable object for caching.
       /// </summary>
-      using CacheableInt32Array = 
CacheableArray<native::CacheableArray<int32_t, 
native::internal::DSCode::CacheableInt32Array>, System::Int32, 
static_cast<int8_t>(DSCode::CacheableInt32Array)>;
+      using CacheableInt32Array = 
CacheableArray<native::internal::CacheableArrayPrimitive<int32_t, 
native::internal::DSCode::CacheableInt32Array>, System::Int32, 
static_cast<int8_t>(DSCode::CacheableInt32Array)>;
 
       /// <summary>
       /// An immutable wrapper for array of 64-bit integers that can serve
       /// as a distributable object for caching.
       /// </summary>
-      using CacheableInt64Array = 
CacheableArray<native::CacheableArray<int64_t, 
native::internal::DSCode::CacheableInt64Array>, System::Int64, 
static_cast<int8_t>(DSCode::CacheableInt64Array)>;
+      using CacheableInt64Array = 
CacheableArray<native::internal::CacheableArrayPrimitive<int64_t, 
native::internal::DSCode::CacheableInt64Array>, System::Int64, 
static_cast<int8_t>(DSCode::CacheableInt64Array)>;
 
       /// <summary>
       /// An immutable wrapper for array of booleans that can serve
       /// as a distributable object for caching.
       /// </summary>
-      using BooleanArray = CacheableArray<native::CacheableArray<bool, 
native::internal::DSCode::BooleanArray>, bool, 
static_cast<int8_t>(DSCode::BooleanArray)>;
+      using BooleanArray = 
CacheableArray<native::internal::CacheableArrayPrimitive<bool, 
native::internal::DSCode::BooleanArray>, bool, 
static_cast<int8_t>(DSCode::BooleanArray)>;
 
       /// <summary>
       /// An immutable wrapper for array of 16-bit characters that can serve
       /// as a distributable object for caching.
       /// </summary>
-      using CharArray = CacheableArray<native::CacheableArray<char16_t, 
native::internal::DSCode::CharArray>, Char, 
static_cast<int8_t>(DSCode::CharArray)>;
+      using CharArray = 
CacheableArray<native::internal::CacheableArrayPrimitive<char16_t, 
native::internal::DSCode::CharArray>, Char, 
static_cast<int8_t>(DSCode::CharArray)>;
     }  // namespace Client
   }  // namespace Geode
 }  // namespace Apache
diff --git a/cppcache/include/geode/CacheableBuiltins.hpp 
b/cppcache/include/geode/CacheableBuiltins.hpp
index 48f0ab0..af59d5e 100644
--- a/cppcache/include/geode/CacheableBuiltins.hpp
+++ b/cppcache/include/geode/CacheableBuiltins.hpp
@@ -31,83 +31,16 @@
 #include "CacheableKey.hpp"
 #include "Serializer.hpp"
 #include "internal/CacheableKeys.hpp"
+#include "internal/CacheableBuiltinTemplates.hpp"
 #include "CacheableString.hpp"
 
 namespace apache {
 namespace geode {
 namespace client {
 
-using internal::DataSerializablePrimitive;
-
-/** Template CacheableKey class for primitive types. */
-template <typename TObj, DSCode TYPEID, const char* TYPENAME>
-class APACHE_GEODE_EXPORT CacheableKeyType : public DataSerializablePrimitive,
-                                             public CacheableKey {
- protected:
-  TObj m_value;
-
-  inline CacheableKeyType()
-      : m_value(apache::geode::client::serializer::zeroObject<TObj>()) {}
-
-  inline explicit CacheableKeyType(const TObj value) : m_value(value) {}
-
- public:
-  /** Gets the contained value. */
-  inline TObj value() const { return m_value; }
-
-  // Cacheable methods
-
-  virtual void toData(DataOutput& output) const override {
-    apache::geode::client::serializer::writeObject(output, m_value);
-  }
-
-  virtual void fromData(DataInput& input) override {
-    apache::geode::client::serializer::readObject(input, m_value);
-  }
-
-  virtual DSCode getDsCode() const override { return TYPEID; }
-
-  /** Return a string representation of the object. */
-  virtual std::string toString() const override {
-    return std::to_string(m_value);
-  }
-
-  // CacheableKey methods
-
-  /** Return the hashcode for this key. */
-  virtual int32_t hashcode() const override {
-    return internal::hashcode(m_value);
-  }
-
-  /** Return true if this key matches other. */
-  virtual bool operator==(const CacheableKey& other) const override {
-    if (const auto otherPrimitive =
-            dynamic_cast<const DataSerializablePrimitive*>(&other)) {
-      if (otherPrimitive->getDsCode() != TYPEID) {
-        return false;
-      }
-    }
-    auto& otherValue = static_cast<const CacheableKeyType&>(other);
-    return internal::equals(m_value, otherValue.m_value);
-  }
-
-  /** Return true if this key matches other key value. */
-  inline bool operator==(const TObj other) const {
-    return internal::equals(m_value, other);
-  }
-
-  /**
-   * Return the size in bytes of the instance being serialized.
-   *
-   * This is used to determine whether the cache is using up more
-   * physical memory than it has been configured to use. The method can
-   * return zero if the user does not require the ability to control
-   * cache memory utilization.
-   */
-  virtual size_t objectSize() const override {
-    return sizeof(CacheableKeyType);
-  }
-};
+using internal::CacheableArrayPrimitive;
+using internal::CacheableContainerPrimitive;
+using internal::CacheableKeyPrimitive;
 
 /** Function to copy an array from source to destination. */
 template <typename TObj>
@@ -127,343 +60,298 @@ inline void copyArray(std::shared_ptr<TObj>* dest,
   }
 }
 
-/** Template class for container Cacheable types. */
-template <typename TBase, DSCode TYPEID>
-class APACHE_GEODE_EXPORT CacheableContainerType
-    : public DataSerializablePrimitive,
-      public TBase {
- protected:
-  inline CacheableContainerType() : TBase() {}
-  inline explicit CacheableContainerType(const int32_t n) : TBase(n) {}
-
- public:
-  // Cacheable methods
-
-  void toData(DataOutput& output) const override {
-    apache::geode::client::serializer::writeObject(output, *this);
-  }
-
-  void fromData(DataInput& input) override {
-    apache::geode::client::serializer::readObject(input, *this);
-  }
-
-  DSCode getDsCode() const override { return TYPEID; }
-
-  size_t objectSize() const override {
-    return sizeof(CacheableContainerType) + serializer::objectSize(*this);
-  }
-};
-
-// Disable extern template warning on MSVC compiler
-#ifdef _MSC_VER
-#pragma warning(disable : 4231)
-#endif
-
-#define _GEODE_CACHEABLE_KEY_TYPE_DEF_(p, k)                \
-  extern const char tName_##k[];                            \
-  template class CacheableKeyType<p, DSCode::k, tName_##k>; \
-  typedef CacheableKeyType<p, DSCode::k, tName_##k> _##k;
-
-// use a class instead of typedef for bug #283
-#define _GEODE_CACHEABLE_KEY_TYPE_(p, k)                                \
-  class APACHE_GEODE_EXPORT k : public _##k {                           \
-   public:                                                              \
-    inline k() : _##k() {}                                              \
-    inline explicit k(const p value) : _##k(value) {}                   \
-                                                                        \
-    /** Factory function registered with serialization registry. */     \
-    static std::shared_ptr<Serializable> createDeserializable() {       \
-      return std::make_shared<k>();                                     \
-    }                                                                   \
-    /** Factory function to create a new default instance. */           \
-    inline static std::shared_ptr<k> create() {                         \
-      return std::make_shared<k>();                                     \
-    }                                                                   \
-    /** Factory function to create an instance with the given value. */ \
-    inline static std::shared_ptr<k> create(const p value) {            \
-      return std::make_shared<k>(value);                                \
-    }                                                                   \
-  };                                                                    \
-  template <>                                                           \
-  inline std::shared_ptr<CacheableKey> CacheableKey::create(p value) {  \
-    return k::create(value);                                            \
-  }                                                                     \
-  template <>                                                           \
-  inline std::shared_ptr<Cacheable> Serializable::create(p value) {     \
-    return k::create(value);                                            \
-  }
-
-#define _GEODE_CACHEABLE_CONTAINER_TYPE_DEF_(p, c)     \
-  template class CacheableContainerType<p, DSCode::c>; \
-  typedef CacheableContainerType<p, DSCode::c> _##c;
-
-// use a class instead of typedef for bug #283
-#define _GEODE_CACHEABLE_CONTAINER_TYPE_(p, c)                         \
-  class APACHE_GEODE_EXPORT c : public _##c {                          \
-   public:                                                             \
-    inline c() : _##c() {}                                             \
-    inline explicit c(const int32_t n) : _##c(n) {}                    \
-                                                                       \
-    /** Factory function registered with serialization registry. */    \
-    static std::shared_ptr<Serializable> createDeserializable() {      \
-      return std::make_shared<c>();                                    \
-    }                                                                  \
-    /** Factory function to create a default instance. */              \
-    inline static std::shared_ptr<c> create() {                        \
-      return std::make_shared<c>();                                    \
-    }                                                                  \
-    /** Factory function to create an instance with the given size. */ \
-    inline static std::shared_ptr<c> create(const int32_t n) {         \
-      return std::make_shared<c>(n);                                   \
-    }                                                                  \
-  };
-
-// Instantiations for the built-in CacheableKeys
-
-_GEODE_CACHEABLE_KEY_TYPE_DEF_(bool, CacheableBoolean)
 /**
- * An immutable wrapper for booleans that can serve as
+ * An immutable wrapper for bool that can serve as
  * a distributable key object for caching.
  */
-_GEODE_CACHEABLE_KEY_TYPE_(bool, CacheableBoolean)
+using CacheableBoolean =
+    CacheableKeyPrimitive<bool, internal::DSCode::CacheableBoolean>;
+template <>
+inline std::shared_ptr<CacheableKey> CacheableKey::create(bool value) {
+  return CacheableBoolean::create(value);
+}
+template <>
+inline std::shared_ptr<Cacheable> Serializable::create(bool value) {
+  return CacheableBoolean::create(value);
+}
 
-_GEODE_CACHEABLE_KEY_TYPE_DEF_(int8_t, CacheableByte)
 /**
- * An immutable wrapper for bytes that can serve as
+ * An immutable wrapper for byte that can serve as
  * a distributable key object for caching.
  */
-_GEODE_CACHEABLE_KEY_TYPE_(int8_t, CacheableByte)
+using CacheableByte =
+    CacheableKeyPrimitive<int8_t, internal::DSCode::CacheableByte>;
+template <>
+inline std::shared_ptr<CacheableKey> CacheableKey::create(int8_t value) {
+  return CacheableByte::create(value);
+}
+template <>
+inline std::shared_ptr<Cacheable> Serializable::create(int8_t value) {
+  return CacheableByte::create(value);
+}
 
-_GEODE_CACHEABLE_KEY_TYPE_DEF_(double, CacheableDouble)
 /**
  * An immutable wrapper for doubles that can serve as
  * a distributable key object for caching.
  */
-_GEODE_CACHEABLE_KEY_TYPE_(double, CacheableDouble)
+using CacheableDouble =
+    CacheableKeyPrimitive<double, internal::DSCode::CacheableDouble>;
+template <>
+inline std::shared_ptr<CacheableKey> CacheableKey::create(double value) {
+  return CacheableDouble::create(value);
+}
+template <>
+inline std::shared_ptr<Cacheable> Serializable::create(double value) {
+  return CacheableDouble::create(value);
+}
 
-_GEODE_CACHEABLE_KEY_TYPE_DEF_(float, CacheableFloat)
 /**
  * An immutable wrapper for floats that can serve as
+
  * a distributable key object for caching.
  */
-_GEODE_CACHEABLE_KEY_TYPE_(float, CacheableFloat)
+using CacheableFloat =
+    CacheableKeyPrimitive<float, internal::DSCode::CacheableFloat>;
+template <>
+inline std::shared_ptr<CacheableKey> CacheableKey::create(float value) {
+  return CacheableFloat::create(value);
+}
+template <>
+inline std::shared_ptr<Cacheable> Serializable::create(float value) {
+  return CacheableFloat::create(value);
+}
 
-_GEODE_CACHEABLE_KEY_TYPE_DEF_(int16_t, CacheableInt16)
 /**
  * An immutable wrapper for 16-bit integers that can serve as
  * a distributable key object for caching.
  */
-_GEODE_CACHEABLE_KEY_TYPE_(int16_t, CacheableInt16)
+using CacheableInt16 =
+    CacheableKeyPrimitive<int16_t, internal::DSCode::CacheableInt16>;
+template <>
+inline std::shared_ptr<CacheableKey> CacheableKey::create(int16_t value) {
+  return CacheableInt16::create(value);
+}
+template <>
+inline std::shared_ptr<Cacheable> Serializable::create(int16_t value) {
+  return CacheableInt16::create(value);
+}
 
-_GEODE_CACHEABLE_KEY_TYPE_DEF_(int32_t, CacheableInt32)
 /**
  * An immutable wrapper for 32-bit integers that can serve as
  * a distributable key object for caching.
  */
-_GEODE_CACHEABLE_KEY_TYPE_(int32_t, CacheableInt32)
+using CacheableInt32 =
+    CacheableKeyPrimitive<int32_t, internal::DSCode::CacheableInt32>;
+template <>
+inline std::shared_ptr<CacheableKey> CacheableKey::create(int32_t value) {
+  return CacheableInt32::create(value);
+}
+template <>
+inline std::shared_ptr<Cacheable> Serializable::create(int32_t value) {
+  return CacheableInt32::create(value);
+}
 
-_GEODE_CACHEABLE_KEY_TYPE_DEF_(int64_t, CacheableInt64)
 /**
  * An immutable wrapper for 64-bit integers that can serve as
  * a distributable key object for caching.
  */
-_GEODE_CACHEABLE_KEY_TYPE_(int64_t, CacheableInt64)
+using CacheableInt64 =
+    CacheableKeyPrimitive<int64_t, internal::DSCode::CacheableInt64>;
+template <>
+inline std::shared_ptr<CacheableKey> CacheableKey::create(int64_t value) {
+  return CacheableInt64::create(value);
+}
+template <>
+inline std::shared_ptr<Cacheable> Serializable::create(int64_t value) {
+  return CacheableInt64::create(value);
+}
 
-_GEODE_CACHEABLE_KEY_TYPE_DEF_(char16_t, CacheableCharacter)
 /**
- * An immutable wrapper for characters that can serve as
+ * An immutable wrapper for 16-bit characters that can serve as
  * a distributable key object for caching.
  */
-_GEODE_CACHEABLE_KEY_TYPE_(char16_t, CacheableCharacter)
-
-// Instantiations for array built-in Cacheables
-
-template <typename T, DSCode GeodeTypeId>
-class APACHE_GEODE_EXPORT CacheableArray : public DataSerializablePrimitive {
- protected:
-  DSCode getDsCode() const override { return GeodeTypeId; }
-
-  size_t objectSize() const override {
-    return static_cast<uint32_t>(
-        apache::geode::client::serializer::objectArraySize(m_value));
-  }
-
- private:
-  std::vector<T> m_value;
-
- public:
-  inline CacheableArray() = default;
-
-  template <typename TT>
-  inline explicit CacheableArray(TT&& value)
-      : m_value(std::forward<TT>(value)) {}
-
-  ~CacheableArray() noexcept override = default;
-
-  CacheableArray(const CacheableArray& other) = delete;
-
-  CacheableArray& operator=(const CacheableArray& other) = delete;
-
-  inline const std::vector<T>& value() const { return m_value; }
-
-  inline int32_t length() const { return static_cast<int32_t>(m_value.size()); 
}
-
-  static std::shared_ptr<Serializable> createDeserializable() {
-    return std::make_shared<CacheableArray<T, GeodeTypeId>>();
-  }
-
-  inline static std::shared_ptr<CacheableArray<T, GeodeTypeId>> create() {
-    return std::make_shared<CacheableArray<T, GeodeTypeId>>();
-  }
-
-  inline static std::shared_ptr<CacheableArray<T, GeodeTypeId>> create(
-      const std::vector<T>& value) {
-    return std::make_shared<CacheableArray<T, GeodeTypeId>>(value);
-  }
-
-  inline static std::shared_ptr<CacheableArray<T, GeodeTypeId>> create(
-      std::vector<T>&& value) {
-    return std::make_shared<CacheableArray<T, GeodeTypeId>>(std::move(value));
-  }
-
-  inline T operator[](int32_t index) const {
-    if (index >= static_cast<int32_t>(m_value.size())) {
-      throw OutOfRangeException(
-          "CacheableArray::operator[]: Index out of range.");
-    }
-    return m_value[index];
-  }
-
-  virtual void toData(DataOutput& output) const override {
-    apache::geode::client::serializer::writeArrayObject(output, m_value);
-  }
-
-  virtual void fromData(DataInput& input) override {
-    m_value = apache::geode::client::serializer::readArrayObject<T>(input);
-  }
-};
+using CacheableCharacter =
+    CacheableKeyPrimitive<char16_t, internal::DSCode::CacheableCharacter>;
+template <>
+inline std::shared_ptr<CacheableKey> CacheableKey::create(char16_t value) {
+  return CacheableCharacter::create(value);
+}
+template <>
+inline std::shared_ptr<Cacheable> Serializable::create(char16_t value) {
+  return CacheableCharacter::create(value);
+}
 
 /**
  * An immutable wrapper for byte arrays that can serve as
  * a distributable object for caching.
  */
-using CacheableBytes = CacheableArray<int8_t, DSCode::CacheableBytes>;
+using CacheableBytes = CacheableArrayPrimitive<int8_t, DSCode::CacheableBytes>;
 
 /**
  * An immutable wrapper for array of booleans that can serve as
  * a distributable object for caching.
  */
-using BooleanArray = CacheableArray<bool, DSCode::BooleanArray>;
+using BooleanArray = CacheableArrayPrimitive<bool, DSCode::BooleanArray>;
 
 /**
  * An immutable wrapper for array of wide-characters that can serve as
  * a distributable object for caching.
  */
-using CharArray = CacheableArray<char16_t, DSCode::CharArray>;
+using CharArray = CacheableArrayPrimitive<char16_t, DSCode::CharArray>;
 
 /**
  * An immutable wrapper for array of doubles that can serve as
  * a distributable object for caching.
  */
 using CacheableDoubleArray =
-    CacheableArray<double, DSCode::CacheableDoubleArray>;
+    CacheableArrayPrimitive<double, DSCode::CacheableDoubleArray>;
 
 /**
  * An immutable wrapper for array of floats that can serve as
  * a distributable object for caching.
  */
-using CacheableFloatArray = CacheableArray<float, DSCode::CacheableFloatArray>;
+using CacheableFloatArray =
+    CacheableArrayPrimitive<float, DSCode::CacheableFloatArray>;
 
 /**
  * An immutable wrapper for array of 16-bit integers that can serve as
  * a distributable object for caching.
  */
 using CacheableInt16Array =
-    CacheableArray<int16_t, DSCode::CacheableInt16Array>;
+    CacheableArrayPrimitive<int16_t, DSCode::CacheableInt16Array>;
 
 /**
  * An immutable wrapper for array of 32-bit integers that can serve as
  * a distributable object for caching.
  */
 using CacheableInt32Array =
-    CacheableArray<int32_t, DSCode::CacheableInt32Array>;
+    CacheableArrayPrimitive<int32_t, DSCode::CacheableInt32Array>;
 
 /**
  * An immutable wrapper for array of 64-bit integers that can serve as
  * a distributable object for caching.
  */
 using CacheableInt64Array =
-    CacheableArray<int64_t, DSCode::CacheableInt64Array>;
+    CacheableArrayPrimitive<int64_t, DSCode::CacheableInt64Array>;
 
 /**
  * An immutable wrapper for array of strings that can serve as
  * a distributable object for caching.
  */
-using CacheableStringArray = CacheableArray<std::shared_ptr<CacheableString>,
-                                            DSCode::CacheableStringArray>;
+using CacheableStringArray =
+    CacheableArrayPrimitive<std::shared_ptr<CacheableString>,
+                            DSCode::CacheableStringArray>;
 
-// Instantiations for container types (Vector/HashMap/HashSet) Cacheables
+// The following are defined as classes to avoid the issues with MSVC++
+// warning/erroring on C4503
 
-_GEODE_CACHEABLE_CONTAINER_TYPE_DEF_(std::vector<std::shared_ptr<Cacheable>>,
-                                     CacheableVector)
 /**
  * A mutable <code>Cacheable</code> vector wrapper that can serve as
  * a distributable object for caching.
  */
-_GEODE_CACHEABLE_CONTAINER_TYPE_(std::vector<std::shared_ptr<Cacheable>>,
-                                 CacheableVector)
+class APACHE_GEODE_EXPORT CacheableVector
+    : public CacheableContainerPrimitive<
+          std::vector<std::shared_ptr<Cacheable>>, DSCode::CacheableVector,
+          CacheableVector> {
+ public:
+  using CacheableContainerPrimitive::CacheableContainerPrimitive;
+};
+
+template class internal::CacheableContainerPrimitive<
+    std::vector<std::shared_ptr<Cacheable>>, DSCode::CacheableVector,
+    CacheableVector>;
 
-_GEODE_CACHEABLE_CONTAINER_TYPE_DEF_(HashMapOfCacheable, CacheableHashMap)
 /**
  * A mutable <code>CacheableKey</code> to <code>Serializable</code>
  * hash map that can serve as a distributable object for caching.
  */
-_GEODE_CACHEABLE_CONTAINER_TYPE_(HashMapOfCacheable, CacheableHashMap)
+class APACHE_GEODE_EXPORT CacheableHashMap
+    : public CacheableContainerPrimitive<
+          HashMapOfCacheable, DSCode::CacheableHashMap, CacheableHashMap> {
+ public:
+  using CacheableContainerPrimitive::CacheableContainerPrimitive;
+};
+
+template class internal::CacheableContainerPrimitive<
+    HashMapOfCacheable, DSCode::CacheableHashMap, CacheableHashMap>;
 
-_GEODE_CACHEABLE_CONTAINER_TYPE_DEF_(HashSetOfCacheableKey, CacheableHashSet)
 /**
  * A mutable <code>CacheableKey</code> hash set wrapper that can serve as
  * a distributable object for caching.
  */
-_GEODE_CACHEABLE_CONTAINER_TYPE_(HashSetOfCacheableKey, CacheableHashSet)
+// using CacheableHashSet = CacheableContainerPrimitive<HashSetOfCacheableKey,
+//                                                     
DSCode::CacheableHashSet>;
+class APACHE_GEODE_EXPORT CacheableHashSet
+    : public CacheableContainerPrimitive<
+          HashSetOfCacheableKey, DSCode::CacheableHashSet, CacheableHashSet> {
+ public:
+  using CacheableContainerPrimitive::CacheableContainerPrimitive;
+};
+
+template class internal::CacheableContainerPrimitive<
+    HashSetOfCacheableKey, DSCode::CacheableHashSet, CacheableHashSet>;
 
-_GEODE_CACHEABLE_CONTAINER_TYPE_DEF_(std::vector<std::shared_ptr<Cacheable>>,
-                                     CacheableArrayList)
 /**
  * A mutable <code>Cacheable</code> array list wrapper that can serve as
  * a distributable object for caching.
  */
-_GEODE_CACHEABLE_CONTAINER_TYPE_(std::vector<std::shared_ptr<Cacheable>>,
-                                 CacheableArrayList)
+class APACHE_GEODE_EXPORT CacheableArrayList
+    : public CacheableContainerPrimitive<
+          std::vector<std::shared_ptr<Cacheable>>, DSCode::CacheableArrayList,
+          CacheableArrayList> {
+ public:
+  using CacheableContainerPrimitive::CacheableContainerPrimitive;
+};
+
+template class internal::CacheableContainerPrimitive<
+    std::vector<std::shared_ptr<Cacheable>>, DSCode::CacheableArrayList,
+    CacheableArrayList>;
 
-// linketlist for JSON formattor issue
-_GEODE_CACHEABLE_CONTAINER_TYPE_DEF_(std::vector<std::shared_ptr<Cacheable>>,
-                                     CacheableLinkedList)
 /**
  * A mutable <code>Cacheable</code> array list wrapper that can serve as
  * a distributable object for caching.
  */
-_GEODE_CACHEABLE_CONTAINER_TYPE_(std::vector<std::shared_ptr<Cacheable>>,
-                                 CacheableLinkedList)
+class APACHE_GEODE_EXPORT CacheableLinkedList
+    : public CacheableContainerPrimitive<
+          std::vector<std::shared_ptr<Cacheable>>, DSCode::CacheableLinkedList,
+          CacheableLinkedList> {
+ public:
+  using CacheableContainerPrimitive::CacheableContainerPrimitive;
+};
+
+template class internal::CacheableContainerPrimitive<
+    std::vector<std::shared_ptr<Cacheable>>, DSCode::CacheableLinkedList,
+    CacheableLinkedList>;
 
-_GEODE_CACHEABLE_CONTAINER_TYPE_DEF_(std::vector<std::shared_ptr<Cacheable>>,
-                                     CacheableStack)
 /**
  * A mutable <code>Cacheable</code> stack wrapper that can serve as
  * a distributable object for caching.
  */
-_GEODE_CACHEABLE_CONTAINER_TYPE_(std::vector<std::shared_ptr<Cacheable>>,
-                                 CacheableStack)
+class APACHE_GEODE_EXPORT CacheableStack
+    : public CacheableContainerPrimitive<
+          std::vector<std::shared_ptr<Cacheable>>, DSCode::CacheableStack,
+          CacheableStack> {
+ public:
+  using CacheableContainerPrimitive::CacheableContainerPrimitive;
+};
+
+template class internal::CacheableContainerPrimitive<
+    HashMapOfCacheable, DSCode::CacheableStack, CacheableStack>;
 
-_GEODE_CACHEABLE_CONTAINER_TYPE_DEF_(HashMapOfCacheable, CacheableHashTable)
 /**
  * A mutable <code>CacheableKey</code> to <code>Serializable</code>
  * hash map that can serve as a distributable object for caching.
  */
-_GEODE_CACHEABLE_CONTAINER_TYPE_(HashMapOfCacheable, CacheableHashTable)
+class APACHE_GEODE_EXPORT CacheableHashTable
+    : public CacheableContainerPrimitive<
+          HashMapOfCacheable, DSCode::CacheableHashTable, CacheableHashTable> {
+ public:
+  using CacheableContainerPrimitive::CacheableContainerPrimitive;
+};
+
+template class internal::CacheableContainerPrimitive<
+    HashMapOfCacheable, DSCode::CacheableHashTable, CacheableHashTable>;
 
-_GEODE_CACHEABLE_CONTAINER_TYPE_DEF_(HashMapOfCacheable,
-                                     CacheableIdentityHashMap)
 /**
  * A mutable <code>CacheableKey</code> to <code>Serializable</code>
  * hash map that can serve as a distributable object for caching. This is
@@ -471,10 +359,18 @@ _GEODE_CACHEABLE_CONTAINER_TYPE_DEF_(HashMapOfCacheable,
  * to <code>CacheableHashMap</code> i.e. does not provide the semantics of
  * java <code>IdentityHashMap</code>.
  */
-_GEODE_CACHEABLE_CONTAINER_TYPE_(HashMapOfCacheable, CacheableIdentityHashMap)
+class APACHE_GEODE_EXPORT CacheableIdentityHashMap
+    : public CacheableContainerPrimitive<HashMapOfCacheable,
+                                         DSCode::CacheableIdentityHashMap,
+                                         CacheableIdentityHashMap> {
+ public:
+  using CacheableContainerPrimitive::CacheableContainerPrimitive;
+};
+
+template class internal::CacheableContainerPrimitive<
+    HashMapOfCacheable, DSCode::CacheableIdentityHashMap,
+    CacheableIdentityHashMap>;
 
-_GEODE_CACHEABLE_CONTAINER_TYPE_DEF_(HashSetOfCacheableKey,
-                                     CacheableLinkedHashSet)
 /**
  * A mutable <code>CacheableKey</code> hash set wrapper that can serve as
  * a distributable object for caching. This is provided for compability
@@ -482,7 +378,17 @@ _GEODE_CACHEABLE_CONTAINER_TYPE_DEF_(HashSetOfCacheableKey,
  * <code>CacheableHashSet</code> i.e. does not provide the predictable
  * iteration semantics of java <code>LinkedHashSet</code>.
  */
-_GEODE_CACHEABLE_CONTAINER_TYPE_(HashSetOfCacheableKey, CacheableLinkedHashSet)
+class APACHE_GEODE_EXPORT CacheableLinkedHashSet
+    : public CacheableContainerPrimitive<HashSetOfCacheableKey,
+                                         DSCode::CacheableLinkedHashSet,
+                                         CacheableLinkedHashSet> {
+ public:
+  using CacheableContainerPrimitive::CacheableContainerPrimitive;
+};
+
+template class internal::CacheableContainerPrimitive<
+    HashSetOfCacheableKey, DSCode::CacheableLinkedHashSet,
+    CacheableLinkedHashSet>;
 
 }  // namespace client
 }  // namespace geode
diff --git a/cppcache/include/geode/internal/CacheableBuiltinTemplates.hpp 
b/cppcache/include/geode/internal/CacheableBuiltinTemplates.hpp
new file mode 100644
index 0000000..792687d
--- /dev/null
+++ b/cppcache/include/geode/internal/CacheableBuiltinTemplates.hpp
@@ -0,0 +1,218 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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.
+ */
+
+#pragma once
+
+#ifndef GEODE_CACHEABLEBUILTINTEMPLATES_H_
+#define GEODE_CACHEABLEBUILTINTEMPLATES_H_
+
+#include <cstring>
+
+#include "../Serializable.hpp"
+#include "../CacheableKey.hpp"
+#include "../Serializer.hpp"
+#include "CacheableKeys.hpp"
+#include "../CacheableString.hpp"
+
+namespace apache {
+namespace geode {
+namespace client {
+namespace internal {
+
+/**
+ * Template class for primitive key types.
+ */
+template <typename TObj, DSCode TYPEID>
+class APACHE_GEODE_EXPORT CacheableKeyPrimitive
+    : public DataSerializablePrimitive,
+      public CacheableKey {
+ private:
+  TObj value_;
+
+ public:
+  inline CacheableKeyPrimitive() = default;
+
+  inline explicit CacheableKeyPrimitive(const TObj value) : value_(value) {}
+
+  ~CacheableKeyPrimitive() noexcept override = default;
+
+  /** Gets the contained value. */
+  inline TObj value() const { return value_; }
+
+  void toData(DataOutput& output) const override {
+    apache::geode::client::serializer::writeObject(output, value_);
+  }
+
+  void fromData(DataInput& input) override {
+    apache::geode::client::serializer::readObject(input, value_);
+  }
+
+  DSCode getDsCode() const override { return TYPEID; }
+
+  std::string toString() const override { return std::to_string(value_); }
+
+  int32_t hashcode() const override { return internal::hashcode(value_); }
+
+  bool operator==(const CacheableKey& other) const override {
+    if (auto&& otherPrimitive =
+            dynamic_cast<const CacheableKeyPrimitive*>(&other)) {
+      return internal::equals(value_, otherPrimitive->value_);
+    }
+
+    return false;
+  }
+
+  /** Return true if this key matches other key value. */
+  inline bool operator==(const TObj other) const {
+    return internal::equals(value_, other);
+  }
+
+  virtual size_t objectSize() const override {
+    return sizeof(CacheableKeyPrimitive);
+  }
+
+  /** Factory function registered with serialization registry. */
+  static std::shared_ptr<Serializable> createDeserializable() {
+    return std::make_shared<CacheableKeyPrimitive>();
+  }
+
+  /** Factory function to create a new default instance. */
+  inline static std::shared_ptr<CacheableKeyPrimitive> create() {
+    return std::make_shared<CacheableKeyPrimitive>();
+  }
+
+  /** Factory function to create an instance with the given value. */
+  inline static std::shared_ptr<CacheableKeyPrimitive> create(
+      const TObj value) {
+    return std::make_shared<CacheableKeyPrimitive>(value);
+  }
+};
+
+template <typename T, DSCode GeodeTypeId>
+class APACHE_GEODE_EXPORT CacheableArrayPrimitive
+    : public DataSerializablePrimitive {
+ protected:
+  DSCode getDsCode() const override { return GeodeTypeId; }
+
+  size_t objectSize() const override {
+    return static_cast<uint32_t>(
+        apache::geode::client::serializer::objectArraySize(m_value));
+  }
+
+ private:
+  std::vector<T> m_value;
+
+ public:
+  inline CacheableArrayPrimitive() = default;
+
+  template <typename TT>
+  CacheableArrayPrimitive(TT&& value) : m_value(std::forward<TT>(value)) {}
+
+  ~CacheableArrayPrimitive() noexcept override = default;
+
+  CacheableArrayPrimitive(const CacheableArrayPrimitive& other) = delete;
+
+  CacheableArrayPrimitive& operator=(const CacheableArrayPrimitive& other) =
+      delete;
+
+  inline const std::vector<T>& value() const { return m_value; }
+
+  inline int32_t length() const { return static_cast<int32_t>(m_value.size()); 
}
+
+  static std::shared_ptr<Serializable> createDeserializable() {
+    return std::make_shared<CacheableArrayPrimitive<T, GeodeTypeId>>();
+  }
+
+  inline static std::shared_ptr<CacheableArrayPrimitive<T, GeodeTypeId>>
+  create() {
+    return std::make_shared<CacheableArrayPrimitive<T, GeodeTypeId>>();
+  }
+
+  inline static std::shared_ptr<CacheableArrayPrimitive<T, GeodeTypeId>> 
create(
+      const std::vector<T>& value) {
+    return std::make_shared<CacheableArrayPrimitive<T, GeodeTypeId>>(value);
+  }
+
+  inline static std::shared_ptr<CacheableArrayPrimitive<T, GeodeTypeId>> 
create(
+      std::vector<T>&& value) {
+    return std::make_shared<CacheableArrayPrimitive<T, GeodeTypeId>>(
+        std::move(value));
+  }
+
+  inline T operator[](int32_t index) const {
+    if (index >= static_cast<int32_t>(m_value.size())) {
+      throw OutOfRangeException(
+          "CacheableArrayPrimitive::operator[]: Index out of range.");
+    }
+    return m_value[index];
+  }
+
+  virtual void toData(DataOutput& output) const override {
+    apache::geode::client::serializer::writeArrayObject(output, m_value);
+  }
+
+  virtual void fromData(DataInput& input) override {
+    m_value = apache::geode::client::serializer::readArrayObject<T>(input);
+  }
+};
+
+/** Template class for container Cacheable types. */
+template <typename TBase, DSCode TYPEID, class _Derived>
+class APACHE_GEODE_EXPORT CacheableContainerPrimitive
+    : public DataSerializablePrimitive,
+      public TBase {
+ public:
+  inline CacheableContainerPrimitive() : TBase() {}
+
+  inline explicit CacheableContainerPrimitive(const int32_t n) : TBase(n) {}
+
+  void toData(DataOutput& output) const override {
+    apache::geode::client::serializer::writeObject(output, *this);
+  }
+
+  void fromData(DataInput& input) override {
+    apache::geode::client::serializer::readObject(input, *this);
+  }
+
+  DSCode getDsCode() const override { return TYPEID; }
+
+  size_t objectSize() const override {
+    return sizeof(_Derived) + serializer::objectSize(*this);
+  }
+
+  /** Factory function registered with serialization registry. */
+  inline static std::shared_ptr<Serializable> createDeserializable() {
+    return std::make_shared<_Derived>();
+  }
+
+  /** Factory function to create a default instance. */
+  inline static std::shared_ptr<_Derived> create() {
+    return std::make_shared<_Derived>();
+  }
+
+  /** Factory function to create an instance with the given size. */
+  inline static std::shared_ptr<_Derived> create(const int32_t n) {
+    return std::make_shared<_Derived>(n);
+  }
+};
+
+}  // namespace internal
+}  // namespace client
+}  // namespace geode
+}  // namespace apache
+
+#endif  // GEODE_CACHEABLEBUILTINTEMPLATES_H_
diff --git 
a/cppcache/integration-test/testThinClientSecurityAuthorizationMU.cpp 
b/cppcache/integration-test/testThinClientSecurityAuthorizationMU.cpp
index 4e61e5f..066e6ec 100644
--- a/cppcache/integration-test/testThinClientSecurityAuthorizationMU.cpp
+++ b/cppcache/integration-test/testThinClientSecurityAuthorizationMU.cpp
@@ -30,7 +30,6 @@
 
 #include "ThinClientSecurity.hpp"
 
-using apache::geode::client::CacheableArray;
 using apache::geode::client::CacheableArrayList;
 using apache::geode::client::CacheableBoolean;
 using apache::geode::client::CacheableVector;
diff --git a/cppcache/src/PdxInstanceFactory.cpp 
b/cppcache/src/PdxInstanceFactory.cpp
index 4d90e81..2584839 100644
--- a/cppcache/src/PdxInstanceFactory.cpp
+++ b/cppcache/src/PdxInstanceFactory.cpp
@@ -197,8 +197,7 @@ PdxInstanceFactory& PdxInstanceFactory::writeByteArray(
   isFieldAdded(fieldName);
   m_pdxType->addVariableLengthTypeField(fieldName, "byte[]",
                                         PdxFieldTypes::BYTE_ARRAY);
-  auto cacheableObject =
-      CacheableArray<int8_t, DSCode::CacheableBytes>::create(value);
+  auto cacheableObject = CacheableBytes::create(value);
   m_FieldVsValues.emplace(fieldName, cacheableObject);
   return *this;
 }
diff --git a/cppcache/src/PdxInstanceImpl.cpp b/cppcache/src/PdxInstanceImpl.cpp
index 59d1b14..91f01b9 100644
--- a/cppcache/src/PdxInstanceImpl.cpp
+++ b/cppcache/src/PdxInstanceImpl.cpp
@@ -157,7 +157,7 @@ void PdxInstanceImpl::writeField(PdxWriter& writer,
     }
     case PdxFieldTypes::BYTE_ARRAY: {
       if (auto&& val = std::dynamic_pointer_cast<
-              CacheableArray<int8_t, DSCode::CacheableBytes>>(value)) {
+              CacheableArrayPrimitive<int8_t, DSCode::CacheableBytes>>(value)) 
{
         writer.writeByteArray(fieldName, val->value());
       }
       break;
@@ -1818,8 +1818,7 @@ void PdxInstanceImpl::setField(const std::string& 
fieldName,
                                 " or type of field not matched " +
                                 (pft != nullptr ? pft->toString() : ""));
   }
-  auto cacheableObject =
-      CacheableArray<int8_t, DSCode::CacheableBytes>::create(value);
+  auto cacheableObject = CacheableBytes::create(value);
   m_updatedFields[fieldName] = cacheableObject;
 }
 
diff --git a/cppcache/src/SerializationRegistry.hpp 
b/cppcache/src/SerializationRegistry.hpp
index 8dbb8d2..7da00a3 100644
--- a/cppcache/src/SerializationRegistry.hpp
+++ b/cppcache/src/SerializationRegistry.hpp
@@ -34,6 +34,7 @@
 
 #include <geode/internal/geode_globals.hpp>
 #include <geode/internal/DataSerializableInternal.hpp>
+#include <geode/internal/DataSerializablePrimitive.hpp>
 #include <geode/Serializable.hpp>
 #include <geode/PdxSerializer.hpp>
 #include <geode/DataOutput.hpp>
@@ -77,6 +78,7 @@ namespace geode {
 namespace client {
 
 using internal::DataSerializableInternal;
+using internal::DataSerializablePrimitive;
 
 typedef ACE_Hash_Map_Manager<DSCode, TypeFactoryMethod, ACE_Null_Mutex>
     DSCodeToFactoryMap;

Reply via email to