Added all numeric types including SaTimeT
Still not implemented are SaNameT and SaAnyT
---
 src/smf/smfd/imm_modify_config/attribute.cc    | 183 +++++++++++++++++++------
 src/smf/smfd/imm_modify_config/attribute.h     | 118 +++++++++++-----
 src/smf/smfd/imm_modify_demo/ccbdemo1.cc       |  71 ++++++++--
 src/smf/smfd/imm_modify_demo/democlass.xml     |   8 ++
 src/smf/smfd/imm_om_api/common/common.h        |  41 ++++++
 src/smf/smfd/imm_om_api/common/imm_attribute.h |  29 ++++
 6 files changed, 361 insertions(+), 89 deletions(-)

diff --git a/src/smf/smfd/imm_modify_config/attribute.cc 
b/src/smf/smfd/imm_modify_config/attribute.cc
index 8485cf2dc..93bd6f520 100644
--- a/src/smf/smfd/imm_modify_config/attribute.cc
+++ b/src/smf/smfd/imm_modify_config/attribute.cc
@@ -112,50 +112,43 @@ bool AttributeHandler::AddAttributes(const 
CreateDescriptor& create_descriptor)
   return rc;
 }
 
+// Add one attribute to a creator. Store the attribute and
+// its values until this object goes out of scope
+// Return false if fail
 bool AttributeHandler::AddAttribute(const AttributeDescriptor& attribute) {
   bool rc = true;
   SaImmValueTypeT value_type = attribute.value_type;
   switch (value_type) {
-    case SA_IMM_ATTR_SAINT32T: {
-      SaInt32T numeric_value = 0;
-      std::vector<SaInt32T> num_values;
-      for (auto& value_str : attribute.values_as_strings) {
-        if (StringToNumericValue<SaInt32T>
-            (value_str, numeric_value, value_type) == false) {
-          LOG_NO("LLDTEST %s: '%s' could not be converted to a SaInt32T",
-                 __FUNCTION__, value_str.c_str());
-          rc = false;
-          break;
-        }
-        num_values.push_back(numeric_value);
-      }
-      std::unique_ptr<SetAttribute> CreatorAttribute =
-          std::unique_ptr<SetAttribute>(new SetAttribute(creator_));
-      CreatorAttribute->SetAttributeValues(attribute.attribute_name,
-                                          num_values);
-      set_attributesp_.push_back(std::move(CreatorAttribute));
+    case SA_IMM_ATTR_SAINT32T:
+      rc = StoreNumericAttribute<SaInt32T>(attribute);
       break;
-    }
-    case SA_IMM_ATTR_SAUINT32T: {
-      SaUint32T num_value = 0;
-      std::vector<SaUint32T> numeric_values;
-      for (auto& value_str : attribute.values_as_strings) {
-        if (StringToNumericValue<SaUint32T>
-            (value_str, num_value, value_type) == false) {
-          LOG_NO("LLDTEST %s: '%s' could not be converted to a SaInt32T",
-                 __FUNCTION__, value_str.c_str());
-          rc = false;
-          break;
-        }
-        numeric_values.push_back(num_value);
-      }
-      std::unique_ptr<SetAttribute> CreatorAttribute =
-          std::unique_ptr<SetAttribute>(new SetAttribute(creator_));
-      CreatorAttribute->SetAttributeValues(attribute.attribute_name,
-                                          numeric_values);
-      set_attributesp_.push_back(std::move(CreatorAttribute));
+
+    case SA_IMM_ATTR_SAUINT32T:
+      rc = StoreNumericAttribute<SaUint32T>(attribute);
       break;
-    }
+
+    case SA_IMM_ATTR_SAINT64T:
+      rc = StoreNumericAttribute<SaInt64T>(attribute);
+      break;
+
+    case SA_IMM_ATTR_SAUINT64T:
+      rc = StoreNumericAttribute<SaUint64T>(attribute);
+      break;
+      
+    case SA_IMM_ATTR_SATIMET:
+      rc = StoreNumericAttribute<CppSaTimeT>(attribute);
+      // rc = StoreTimeTAttribute(attribute);
+      break;
+
+    case SA_IMM_ATTR_SAFLOATT:
+      rc = StoreNumericAttribute<SaFloatT>(attribute);
+      break;
+
+    case SA_IMM_ATTR_SADOUBLET:
+      rc = StoreNumericAttribute<SaDoubleT>(attribute);
+      break;
+
+
     case SA_IMM_ATTR_SASTRINGT: {
       std::unique_ptr<SetAttribute> CreatorAttribute =
           std::unique_ptr<SetAttribute>(new SetAttribute(creator_));
@@ -171,8 +164,40 @@ bool AttributeHandler::AddAttribute(const 
AttributeDescriptor& attribute) {
   return rc;
 }
 
+// Convert all values as a string for an attribute to numeric values.
+// Create a SetAttribute object and give that object the attribute name and its
+// numeric values. The SetAttribute object will store the attribute and give
+// the attribute name and values to the creator
+// Save the SetAttribute object in a vector so that the object will be in scope
+// until "this" object goes out of scope which shall happen when the creator
+// has given the create operation to IMM
+template<typename T>
+bool AttributeHandler::
+StoreNumericAttribute(const AttributeDescriptor& attribute) {
+  bool rc = true;
+  SaImmValueTypeT value_type = attribute.value_type;
+  T numeric_value{0};
+  std::vector<T> num_values;
+  for (auto& value_str : attribute.values_as_strings) {
+    if (StringToNumericValue<T>
+        (value_str, numeric_value, value_type) == false) {
+      LOG_NO("LLDTEST %s: StringToNumericValue() Fail", __FUNCTION__);
+      rc = false;
+      break;
+    }
+    num_values.push_back(numeric_value);
+  }
+  if (rc == true) {
+    std::unique_ptr<SetAttribute> CreatorAttribute =
+        std::unique_ptr<SetAttribute>(new SetAttribute(creator_));
+      CreatorAttribute->SetAttributeValues(attribute.attribute_name,
+                                           num_values);
+    set_attributesp_.push_back(std::move(CreatorAttribute));
+  }
+  return rc;
+}
 
-
+// SaUint32T
 void SetAttribute::SetAttributeValues(const std::string& name,
                                 const std::vector<SaUint32T>& num_values) {
   Uint32ValueStore_ =
@@ -188,6 +213,7 @@ void SetAttribute::SetAttributeValues(const std::string& 
name,
   creator_->SetAttributeValue(name, Uint32ValueStore_->Values_p);
 }
 
+// SaInt32T
 void SetAttribute::SetAttributeValues(const std::string& name,
                                 const std::vector<SaInt32T>& num_values) {
   Int32ValueStore_ =
@@ -202,6 +228,85 @@ void SetAttribute::SetAttributeValues(const std::string& 
name,
   creator_->SetAttributeValue(name, Int32ValueStore_->Values_p);
 }
 
+// SaUint64T
+void SetAttribute::SetAttributeValues(const std::string& name,
+                                const std::vector<SaUint64T>& num_values) {
+  Uint64ValueStore_ =
+      std::unique_ptr<Uint64ValueStore>(new Uint64ValueStore);
+  for (auto& num_value : num_values) {
+    Uint64ValueStore_->Values.push_back(num_value);
+  }
+  SaUint64T* v_ptr = Uint64ValueStore_->Values.data();
+  for (size_t i = 0; i < Uint64ValueStore_->Values.size(); i++) {
+    Uint64ValueStore_->Values_p.push_back(v_ptr++);
+  }
+  creator_->SetAttributeValue(name, Uint64ValueStore_->Values_p);
+}
+
+void SetAttribute::SetAttributeValues(const std::string& name,
+                                const std::vector<SaInt64T>& num_values) {
+  Int64ValueStore_ =
+      std::unique_ptr<Int64ValueStore>(new Int64ValueStore);
+  for (auto& num_value : num_values) {
+    Int64ValueStore_->Values.push_back(num_value);
+  }
+  SaInt64T* v_ptr = Int64ValueStore_->Values.data();
+  for (size_t i = 0; i < Int64ValueStore_->Values.size(); i++) {
+    Int64ValueStore_->Values_p.push_back(v_ptr++);
+  }
+  creator_->SetAttributeValue(name, Int64ValueStore_->Values_p);
+}
+
+// SaFloatT
+void SetAttribute::SetAttributeValues(const std::string& name,
+                                const std::vector<SaFloatT>& num_values) {
+  FloatValueStore_ =
+      std::unique_ptr<FloatValueStore>(new FloatValueStore);
+  for (auto& num_value : num_values) {
+    FloatValueStore_->Values.push_back(num_value);
+  }
+  SaFloatT* v_ptr = FloatValueStore_->Values.data();
+  for (size_t i = 0; i < FloatValueStore_->Values.size(); i++) {
+    FloatValueStore_->Values_p.push_back(v_ptr++);
+  }
+  creator_->SetAttributeValue(name, FloatValueStore_->Values_p);
+}
+
+// SaDoubleT
+void SetAttribute::SetAttributeValues(const std::string& name,
+                                const std::vector<SaDoubleT>& num_values) {
+  DoubleValueStore_ =
+      std::unique_ptr<DoubleValueStore>(new DoubleValueStore);
+  for (auto& num_value : num_values) {
+    DoubleValueStore_->Values.push_back(num_value);
+  }
+  SaDoubleT* v_ptr = DoubleValueStore_->Values.data();
+  for (size_t i = 0; i < DoubleValueStore_->Values.size(); i++) {
+    DoubleValueStore_->Values_p.push_back(v_ptr++);
+  }
+  creator_->SetAttributeValue(name, DoubleValueStore_->Values_p);
+}
+
+// SaTimeT
+// For C++ SaTimeT is the same type as SaInt64T but they are different IMM
+// model types and must because of that be handled as different types when
+// given to the creator API (see SetAttributeValue and TimeValueStore)
+void SetAttribute::SetAttributeValues(const std::string& name,
+                                const std::vector<CppSaTimeT>& time_values) {
+  TimeValueStore_ =
+      std::unique_ptr<TimeValueStore>(new TimeValueStore);
+  for (auto& num_value : time_values) {
+    TimeValueStore_->Values.push_back(num_value);
+  }
+  CppSaTimeT* v_ptr = TimeValueStore_->Values.data();
+  for (size_t i = 0; i < TimeValueStore_->Values.size(); i++) {
+    TimeValueStore_->Values_p.push_back(v_ptr++);
+  }
+  creator_->SetAttributeValue(name, TimeValueStore_->Values_p);
+}
+
+// DODO(Lennart) Also add SaNameT and SaAnyT
+
 void SetAttribute::SetAttributeValues(const std::string& name,
                                 const std::vector<std::string>& str_values) {
   StringValueStore_ =
diff --git a/src/smf/smfd/imm_modify_config/attribute.h 
b/src/smf/smfd/imm_modify_config/attribute.h
index a4add2fcb..f6411f787 100644
--- a/src/smf/smfd/imm_modify_config/attribute.h
+++ b/src/smf/smfd/imm_modify_config/attribute.h
@@ -32,23 +32,61 @@
 #ifndef ATTRVAL_HDL_H
 #define ATTRVAL_HDL_H
 
+#if 0 // All the IMM types
+SA_IMM_ATTR_SAINT32T = 1,      /* SaInt32T */
+SA_IMM_ATTR_SAUINT32T = 2,     /* SaUint32T */
+SA_IMM_ATTR_SAINT64T = 3,      /* SaInt64T */
+SA_IMM_ATTR_SAUINT64T = 4,     /* SaUint64T */
+SA_IMM_ATTR_SATIMET = 5,       /* SaTimeT is SaInt64T */
+SA_IMM_ATTR_SANAMET = 6,       /* SaNameT */
+SA_IMM_ATTR_SAFLOATT = 7,      /* SaFloatT */
+SA_IMM_ATTR_SADOUBLET = 8,     /* SaDoubleT */
+SA_IMM_ATTR_SASTRINGT = 9,     /* SaStringT */
+SA_IMM_ATTR_SAANYT = 10         /* SaAnyT */
+#endif
 namespace modelmodify {
 
 // Store values of different types
+struct Int32ValueStore {
+  std::vector<SaInt32T> Values;
+  std::vector<SaInt32T*> Values_p;
+};
 struct Uint32ValueStore {
   std::vector<SaUint32T> Values;
   std::vector<SaUint32T*> Values_p;
 };
-
-struct Int32ValueStore {
-  std::vector<SaInt32T> Values;
-  std::vector<SaInt32T*> Values_p;
+struct Int64ValueStore {
+  std::vector<SaInt64T> Values;
+  std::vector<SaInt64T*> Values_p;
+};
+struct Uint64ValueStore {
+  std::vector<SaUint64T> Values;
+  std::vector<SaUint64T*> Values_p;
+};
+struct TimeValueStore {
+  std::vector<CppSaTimeT> Values;
+  std::vector<CppSaTimeT*> Values_p;
+};
+struct FloatValueStore {
+  std::vector<SaFloatT> Values;
+  std::vector<SaFloatT*> Values_p;
+};
+struct DoubleValueStore {
+  std::vector<SaDoubleT> Values;
+  std::vector<SaDoubleT*> Values_p;
 };
-
 struct StringValueStore {
   std::vector<std::string> Values;
   std::vector<std::string*> Values_p;
 };
+struct NameValueStore {
+  std::vector<SaNameT> Values;
+  std::vector<SaNameT*> Values_p;
+};
+struct AnyValueStore {
+  std::vector<SaAnyT> Values;
+  std::vector<SaAnyT*> Values_p;
+};
 
 // Adds one attribute to a creator
 // Used by class Attribute. Class SAttribute must see to that all objects of
@@ -59,38 +97,16 @@ class SetAttribute {
   explicit SetAttribute(immom::ImmOmCcbObjectCreate* creator)
     : Uint32ValueStore_(nullptr),
       Int32ValueStore_(nullptr),
+      Int64ValueStore_(nullptr),
+      Uint64ValueStore_(nullptr),
+      TimeValueStore_(nullptr),
+      FloatValueStore_(nullptr),
+      DoubleValueStore_(nullptr),
       StringValueStore_(nullptr),
+      NameValueStore_(nullptr),
+      AnyValueStore_(nullptr),
       creator_(creator) {}
 
-#if 0// TODO(Lennart) Remove
-  void PrintValues() {
-    if (Uint32ValueStore_) {
-      cout << "Printing uint32 values via pointer to value" << endl;
-      TRACE("LLDTEST: Printing uint32 values via pointer to value");
-      for (auto& val_p : Uint32ValueStore_->Values_p) {
-        cout << " value = " << *val_p << endl;
-        TRACE("LLDTEST   value = %u", *val_p);
-      }
-    }
-    if (Int32ValueStore_) {
-      cout << "Printing int32 values via pointer to value" << endl;
-      TRACE("LLDTEST: Printing int32 values via pointer to value");
-      for (auto& val_p : Int32ValueStore_->Values_p) {
-        cout << " value = " << *val_p << endl;
-        TRACE("LLDTEST   value = %d", *val_p);
-      }
-    }
-    if (StringValueStore_) {
-      cout << "Printing std::string values via pointer to value" << endl;
-      TRACE("LLDTEST: Printing std::string values via pointer to value");
-      for (auto& val_p : StringValueStore_->StringValues) {
-        cout << " value = " << val_p << endl;
-        TRACE("LLDTEST   value = %s", *val_p);
-      }
-    }
-  }
-#endif
-
   // Store one attribute of a given type and add it to a creator
   // The values are stored in a vector and another vector with pointers to the
   // values is created. It is the pointer vector that is the in parameter for
@@ -99,13 +115,39 @@ class SetAttribute {
                           const std::vector<SaUint32T>& num_values);
   void SetAttributeValues(const std::string& name,
                           const std::vector<SaInt32T>& num_values);
+  void SetAttributeValues(const std::string& name,
+                          const std::vector<SaUint64T>& num_values);
+  void SetAttributeValues(const std::string& name,
+                          const std::vector<SaInt64T>& num_values);
+  void SetAttributeValues(const std::string& name,
+                          const std::vector<SaFloatT>& num_values);
+  void SetAttributeValues(const std::string& name,
+                          const std::vector<SaDoubleT>& num_values);
+
   void SetAttributeValues(const std::string& name,
                           const std::vector<std::string>& str_values);
+
+  void SetAttributeValues(const std::string& name,
+                          const std::vector<CppSaTimeT>& time_values);
+
  private:
+  // Numeric
   std::unique_ptr<Uint32ValueStore> Uint32ValueStore_;
   std::unique_ptr<Int32ValueStore> Int32ValueStore_;
+  std::unique_ptr<Int64ValueStore> Int64ValueStore_;
+  std::unique_ptr<Uint64ValueStore> Uint64ValueStore_;
+  std::unique_ptr<TimeValueStore> TimeValueStore_;
+  std::unique_ptr<FloatValueStore> FloatValueStore_;
+  std::unique_ptr<DoubleValueStore> DoubleValueStore_;
+
+  // Is used for SaStringT. See om_ccb_object_create
   std::unique_ptr<StringValueStore> StringValueStore_;
 
+  // Special SA types SaNameT and SaAnyT
+  std::unique_ptr<NameValueStore> NameValueStore_;
+  std::unique_ptr<AnyValueStore> AnyValueStore_;
+
+
   immom::ImmOmCcbObjectCreate* creator_;
 
   //DELETE_COPY_AND_MOVE_OPERATORS(Attribute);
@@ -134,11 +176,13 @@ class AttributeHandler {
   bool AddAttributes(const CreateDescriptor& create_descriptor);
 
  private:
-  // Add one attribute to a creator. Store the attribute and
-  // its values until this object goes out of scope
-  // Return false if fail
   bool AddAttribute(const AttributeDescriptor& attribute);
 
+  template<typename T>
+  bool StoreNumericAttribute(const AttributeDescriptor& attribute);
+
+  bool StoreTimeTAttribute(const AttributeDescriptor& attribute);
+
   std::vector<std::unique_ptr<SetAttribute>> set_attributesp_;
   immom::ImmOmCcbObjectCreate* creator_;
 
diff --git a/src/smf/smfd/imm_modify_demo/ccbdemo1.cc 
b/src/smf/smfd/imm_modify_demo/ccbdemo1.cc
index 4dd1149cf..7f40800c2 100644
--- a/src/smf/smfd/imm_modify_demo/ccbdemo1.cc
+++ b/src/smf/smfd/imm_modify_demo/ccbdemo1.cc
@@ -105,21 +105,40 @@ int main() {
   creator.SetAttributeValue("immTestValuesCfg", obj_name_ps);
 
   // Setting values and pointers to the values
-  std::vector<uint32_t> num_values;
-  std::vector<uint32_t*> num_values_pointers;
-  for (uint32_t i = 0; i < 5; i++) {
-    num_values.push_back(i);
+  std::vector<SaUint32T> uint32_values;
+  std::vector<SaUint32T*> uint32_values_pointers;
+  for (SaUint32T i = 0; i < 5; i++) {
+    uint32_values.push_back(i);
   }
-  uint32_t* val_ptr = num_values.data();
-  for (size_t i = 0; i < num_values.size(); i++) {
-    num_values_pointers.push_back(val_ptr++);
+  SaUint32T* val_ptr = uint32_values.data();
+  for (size_t i = 0; i < uint32_values.size(); i++) {
+    uint32_values_pointers.push_back(val_ptr++);
   }
-  cout << "The values:" << endl;
-  for (auto& valuep : num_values_pointers) {
-    cout << "  " << *valuep << endl;
+
+  std::vector<SaInt64T> int64_values;
+  std::vector<SaInt64T*> int64_values_pointers;
+  for (SaInt64T i = 10; i < 15; i++) {
+    int64_values.push_back(i);
+  }
+  SaInt64T* int64_p = int64_values.data();
+  for (size_t i = 0; i < int64_values.size(); i++) {
+    int64_values_pointers.push_back(int64_p++);
+  }
+
+  std::vector<SaTimeT> time_values;
+  std::vector<SaTimeT*> time_values_pointers;
+  for (SaTimeT i = 100; i < 105; i++) {
+    time_values.push_back(i);
+  }
+  SaTimeT* time_p = time_values.data();
+  for (size_t i = 0; i < time_values.size(); i++) {
+    time_values_pointers.push_back(time_p++);
   }
 
-  creator.SetAttributeValue("SaUint32TValues", num_values_pointers);
+  creator.SetAttributeValue("SaUint32TValues", uint32_values_pointers);
+  creator.SetAttributeValue("SaUint32TValues", int64_values_pointers);
+  creator.SetAttributeValue("SaTimeTValues", time_values_pointers);
+//  creator.SetAttributeValue("SaInt64TValues", time_values_pointers);
 
   cout << "AddObjectCreateToCcb()" << endl;
   if (creator.AddObjectCreateToCcb() == false) {
@@ -165,6 +184,9 @@ int main(void) {
   modelmodify::AttributeDescriptor object_name;
   modelmodify::AttributeDescriptor uint32_values;
   modelmodify::AttributeDescriptor int32_values;
+  modelmodify::AttributeDescriptor uint64_values;
+  modelmodify::AttributeDescriptor int64_values;
+  modelmodify::AttributeDescriptor time_values;
   modelmodify::AttributeDescriptor string_values;
 
   cout << "Construct attribute descriptors" << endl;
@@ -187,6 +209,24 @@ int main(void) {
   int32_values.AddValue(std::to_string(3));
   int32_values.AddValue(std::to_string(4));
 
+  // SA_IMM_ATTR_SAUINT64T
+  uint64_values.attribute_name = "SaUint64TValues";
+  uint64_values.value_type = SA_IMM_ATTR_SAUINT64T;
+  uint64_values.AddValue(std::to_string(5));
+  uint64_values.AddValue(std::to_string(6));
+
+  // SA_IMM_ATTR_SAINT64T
+  int64_values.attribute_name = "SaInt64TValues";
+  int64_values.value_type = SA_IMM_ATTR_SAINT64T;
+  int64_values.AddValue(std::to_string(7));
+  int64_values.AddValue(std::to_string(8));
+
+  // SA_IMM_ATTR_SATIMET
+  time_values.attribute_name = "SaTimeTValues";
+  time_values.value_type = SA_IMM_ATTR_SATIMET;
+  time_values.AddValue(std::to_string(100));
+  time_values.AddValue(std::to_string(200));
+
   // SA_IMM_ATTR_SASTRINGT Other string values
   string_values.attribute_name = "SaStringValues";
   string_values.value_type = SA_IMM_ATTR_SASTRINGT;
@@ -200,8 +240,11 @@ int main(void) {
   test_object_create.parent_name = "safApp=safSmfService";
   test_object_create.AddAttribute(object_name);
   test_object_create.AddAttribute(uint32_values);
-  test_object_create.AddAttribute(string_values);
   test_object_create.AddAttribute(int32_values);
+  test_object_create.AddAttribute(uint64_values);
+  test_object_create.AddAttribute(int64_values);
+  test_object_create.AddAttribute(time_values);
+  test_object_create.AddAttribute(string_values);
 
   cout << "Construct a CCB descriptor" << endl;
   // Construct a CCB descriptor:
@@ -213,7 +256,9 @@ int main(void) {
 
   modelmodify::ObjectModification obj_creator;
   obj_creator.SetCcbFlags(0);
-  obj_creator.DoModification(test_ccb);
+  if (obj_creator.DoModification(test_ccb) == false) {
+    cout << "DoModification() Fail" << endl;
+  }
 
   cout << endl << "ccbdemo1 Done" << endl;
   return 0;
diff --git a/src/smf/smfd/imm_modify_demo/democlass.xml 
b/src/smf/smfd/imm_modify_demo/democlass.xml
index 21d2babb0..1f012fd41 100644
--- a/src/smf/smfd/imm_modify_demo/democlass.xml
+++ b/src/smf/smfd/imm_modify_demo/democlass.xml
@@ -40,6 +40,14 @@
             <flag>SA_MULTI_VALUE</flag>
             <flag>SA_NO_DUPLICATES</flag>
         </attr>
+        <attr>
+            <name>SaTimeTValues</name>
+            <type>SA_TIME_T</type>
+            <category>SA_CONFIG</category>
+            <flag>SA_WRITABLE</flag>
+            <flag>SA_MULTI_VALUE</flag>
+            <flag>SA_NO_DUPLICATES</flag>
+        </attr>
         <attr>
             <name>SaFloatValues</name>
             <type>SA_FLOAT_T</type>
diff --git a/src/smf/smfd/imm_om_api/common/common.h 
b/src/smf/smfd/imm_om_api/common/common.h
index 5888ae869..f446c0097 100644
--- a/src/smf/smfd/imm_om_api/common/common.h
+++ b/src/smf/smfd/imm_om_api/common/common.h
@@ -38,6 +38,44 @@ const SaUint8T kDefaultImmReleaseCode  = 'A';
 const SaUint8T kDefaultImmMajorVersion = 2;
 const SaUint8T kDefaultImmMinorVersion = 11;
 
+// As SaTimeT and SaInt64T are aliases to same data type,
+// we can not distinguish if passing them to a template method.
+// We do workaround by introducing a new data type for SaNameT.
+//
+// Usage example:
+// CppSaTimeT time = 1234456;
+//
+// printf("%d", time());
+// SetAttributeValue("timeattribute", &time);
+//
+struct CppSaTimeT {
+  CppSaTimeT() { time = 0; }
+  explicit CppSaTimeT(SaTimeT t) : time{t} {};
+  // explicit CppSaTimeT(int t) : time{t} {};
+
+  CppSaTimeT& operator=(SaTimeT t) {
+    time = t;
+    return *this;
+  }
+
+#if 0
+  CppSaTimeT& operator=(int t) {
+    time = static_cast<SaTimeT>(t);
+    return *this;
+  }
+#endif
+
+  SaTimeT& operator()() {
+    return time;
+  }
+
+  bool operator==(SaTimeT t) {
+    return (time == t);
+  }
+
+  SaTimeT time;
+};
+
 //>
 // Base class of all IMM OI and OM abstractions
 //
@@ -115,6 +153,8 @@ SaImmValueTypeT ImmBase::GetAttributeValueType() {
     return SA_IMM_ATTR_SAUINT32T;
   } else if (std::is_same<T, SaInt64T>::value) {
     return SA_IMM_ATTR_SAINT64T;
+  } else if (std::is_same<T, CppSaTimeT>::value) {
+    return SA_IMM_ATTR_SATIMET;
   } else if (std::is_same<T, SaUint64T>::value) {
     return SA_IMM_ATTR_SAUINT64T;
   } else if (std::is_same<T, SaNameT>::value) {
@@ -139,6 +179,7 @@ SaImmValueTypeT ImmBase::GetAttributeValueType() {
   static_assert(                                \
       std::is_same<T, SaInt32T>::value       || \
       std::is_same<T, SaInt64T>::value       || \
+      std::is_same<T, CppSaTimeT>::value     || \
       std::is_same<T, SaUint32T>::value      || \
       std::is_same<T, SaUint32T>::value      || \
       std::is_same<T, SaUint64T>::value      || \
diff --git a/src/smf/smfd/imm_om_api/common/imm_attribute.h 
b/src/smf/smfd/imm_om_api/common/imm_attribute.h
index 945b108a4..a3412c876 100644
--- a/src/smf/smfd/imm_om_api/common/imm_attribute.h
+++ b/src/smf/smfd/imm_om_api/common/imm_attribute.h
@@ -204,6 +204,35 @@ AttributeProperty::set_value<std::string>(
   return *this;
 }
 
+template <> inline AttributeProperty&
+AttributeProperty::set_value<CppSaTimeT>(CppSaTimeT* ptr_to_value) {
+  attribute_type_ = ImmBase::GetAttributeValueType<CppSaTimeT>();
+  if (ptr_to_value != nullptr) {
+    attribute_values_pointers_ = reinterpret_cast<void**>(new SaTimeT*[1]());
+    assert(attribute_values_pointers_ != nullptr);
+    attribute_values_pointers_[0] = &(ptr_to_value->time);
+    num_of_values_ = 1;
+  }
+  return *this;
+}
+
+template <> inline AttributeProperty&
+AttributeProperty::set_value<CppSaTimeT>(
+    const std::vector<CppSaTimeT*>& list_of_ptr_to_values) {
+  attribute_type_ = ImmBase::GetAttributeValueType<CppSaTimeT>();
+  if (list_of_ptr_to_values.empty() == false) {
+    size_t size = list_of_ptr_to_values.size();
+    attribute_values_pointers_ = reinterpret_cast<void**>(new 
SaTimeT*[size]());
+    assert(attribute_values_pointers_ != nullptr);
+    unsigned i = 0;
+    for (auto& ptr_to_value : list_of_ptr_to_values) {
+      attribute_values_pointers_[i++] = &(ptr_to_value->time);
+    }
+    num_of_values_ = size;
+  }
+  return *this;
+}
+
 // For internal use only
 using ListOfAttributePropertyPtr     = std::vector<AttributeProperty*>;
 using ListOfAttributeModificationPtr = std::vector<AttributeModification*>;
-- 
2.15.1


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to