A Discrete-Event Network Simulator
API
type-id.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008 INRIA
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18  */
19 #include "type-id.h"
20 
21 #include "hash.h"
22 #include "log.h" // NS_ASSERT and NS_LOG
23 #include "singleton.h"
24 #include "trace-source-accessor.h"
25 
26 #include <iomanip>
27 #include <map>
28 #include <sstream>
29 #include <vector>
30 
37 /*********************************************************************
38  * Helper code
39  *********************************************************************/
40 
41 namespace ns3
42 {
43 
44 NS_LOG_COMPONENT_DEFINE("TypeId");
45 
46 // IidManager needs to be in ns3 namespace for NS_ASSERT and NS_LOG
47 // to find g_log
48 
78 class IidManager : public Singleton<IidManager>
79 {
80  public:
86  uint16_t AllocateUid(std::string name);
92  void SetParent(uint16_t uid, uint16_t parent);
98  void SetGroupName(uint16_t uid, std::string groupName);
104  void SetSize(uint16_t uid, std::size_t size);
110  void AddConstructor(uint16_t uid, Callback<ObjectBase*> callback);
115  void HideFromDocumentation(uint16_t uid);
121  uint16_t GetUid(std::string name) const;
127  uint16_t GetUid(TypeId::hash_t hash) const;
133  std::string GetName(uint16_t uid) const;
139  TypeId::hash_t GetHash(uint16_t uid) const;
145  uint16_t GetParent(uint16_t uid) const;
151  std::string GetGroupName(uint16_t uid) const;
157  std::size_t GetSize(uint16_t uid) const;
163  Callback<ObjectBase*> GetConstructor(uint16_t uid) const;
169  bool HasConstructor(uint16_t uid) const;
174  uint16_t GetRegisteredN() const;
184  uint16_t GetRegistered(uint16_t i) const;
201  void AddAttribute(uint16_t uid,
202  std::string name,
203  std::string help,
204  uint32_t flags,
205  Ptr<const AttributeValue> initialValue,
209  const std::string& supportMsg = "");
216  void SetAttributeInitialValue(uint16_t uid,
217  std::size_t i,
218  Ptr<const AttributeValue> initialValue);
224  std::size_t GetAttributeN(uint16_t uid) const;
231  TypeId::AttributeInformation GetAttribute(uint16_t uid, std::size_t i) const;
246  void AddTraceSource(uint16_t uid,
247  std::string name,
248  std::string help,
250  std::string callback,
252  const std::string& supportMsg = "");
258  std::size_t GetTraceSourceN(uint16_t uid) const;
265  TypeId::TraceSourceInformation GetTraceSource(uint16_t uid, std::size_t i) const;
271  bool MustHideFromDocumentation(uint16_t uid) const;
272 
273  private:
280  bool HasTraceSource(uint16_t uid, std::string name);
287  bool HasAttribute(uint16_t uid, std::string name);
293  static TypeId::hash_t Hasher(const std::string name);
294 
297  {
299  std::string name;
303  uint16_t parent;
305  std::string groupName;
307  std::size_t size;
315  std::vector<TypeId::AttributeInformation> attributes;
317  std::vector<TypeId::TraceSourceInformation> traceSources;
321  std::string supportMsg;
322  };
323 
325  typedef std::vector<IidInformation>::const_iterator Iterator;
326 
332  IidManager::IidInformation* LookupInformation(uint16_t uid) const;
333 
335  std::vector<IidInformation> m_information;
336 
338  typedef std::map<std::string, uint16_t> namemap_t;
341 
343  typedef std::map<TypeId::hash_t, uint16_t> hashmap_t;
346 
348  enum
349  {
356  HashChainFlag = 0x80000000
357  };
358 };
359 
360 // static
362 IidManager::Hasher(const std::string name)
363 {
364  static ns3::Hasher hasher(Create<Hash::Function::Murmur3>());
365  return hasher.clear().GetHash32(name);
366 }
367 
373 #define IID "IidManager"
379 #define IIDL IID << ": "
380 
381 uint16_t
382 IidManager::AllocateUid(std::string name)
383 {
384  NS_LOG_FUNCTION(IID << name);
385  // Type names are definitive: equal names are equal types
386  NS_ABORT_MSG_UNLESS(m_namemap.count(name) == 0,
387  "Trying to allocate twice the same uid: " << name);
388 
390  if (m_hashmap.count(hash) == 1)
391  {
392  NS_LOG_ERROR("Hash chaining TypeId for '"
393  << name << "'. "
394  << "This is not a bug, but is extremely unlikely. "
395  << "Please contact the ns3 developers.");
396  // ns3 developer contacted about this message:
397  // You have four options (in order of difficulty):
398  // 1. Let it ride, and play the odds that a third collision
399  // never appears.
400  // 2. Change the name of the new (or old) tag, even trivially, to
401  // remove the collision.
402  // 3. Switch to 64-bit hashes.
403  // 4. Implement 2-bit (or higher) chaining.
404  //
405  // Oh, by the way, I owe you a beer, since I bet Mathieu that
406  // this would never happen.. -- Peter Barnes, LLNL
407 
409  "Triplicate hash detected while chaining TypeId for '"
410  << name << "'. Please contact the ns3 developers for assistance.");
411  // ns3 developer contacted about this message:
412  // You have three options: #2-4 above.
413  //
414  // Oh, by the way, I have no idea how this crazy hashing idea got
415  // into ns3. -- Peter Barnes, LLNL
416 
417  // Alphabetize the two types, so it's deterministic
419  if (name > hinfo->name)
420  { // new type gets chained
421  NS_LOG_LOGIC(IIDL << "New TypeId '" << name << "' getting chained.");
422  hash = hash | HashChainFlag;
423  }
424  else
425  { // chain old type
426  NS_LOG_LOGIC(IIDL << "Old TypeId '" << hinfo->name << "' getting chained.");
427  uint16_t oldUid = GetUid(hinfo->hash);
428  m_hashmap.erase(m_hashmap.find(hinfo->hash));
429  hinfo->hash = hash | HashChainFlag;
430  m_hashmap.insert(std::make_pair(hinfo->hash, oldUid));
431  // leave new hash unchained
432  }
433  }
434 
435  IidInformation information;
436  information.name = name;
437  information.hash = hash;
438  information.parent = 0;
439  information.groupName = "";
440  information.size = (std::size_t)(-1);
441  information.hasConstructor = false;
442  information.mustHideFromDocumentation = false;
443  information.supportLevel = TypeId::SUPPORTED;
444  m_information.push_back(information);
445  std::size_t tuid = m_information.size();
446  NS_ASSERT(tuid <= 0xffff);
447  auto uid = static_cast<uint16_t>(tuid);
448 
449  // Add to both maps:
450  m_namemap.insert(std::make_pair(name, uid));
451  m_hashmap.insert(std::make_pair(hash, uid));
452  NS_LOG_LOGIC(IIDL << uid);
453  return uid;
454 }
455 
457 IidManager::LookupInformation(uint16_t uid) const
458 {
459  NS_LOG_FUNCTION(IID << uid);
460  NS_ASSERT(uid <= m_information.size() && uid != 0);
461  NS_LOG_LOGIC(IIDL << m_information[uid - 1].name);
462  return const_cast<IidInformation*>(&m_information[uid - 1]);
463 }
464 
465 void
466 IidManager::SetParent(uint16_t uid, uint16_t parent)
467 {
468  NS_LOG_FUNCTION(IID << uid << parent);
469  NS_ASSERT(parent <= m_information.size());
470  IidInformation* information = LookupInformation(uid);
471  information->parent = parent;
472 }
473 
474 void
475 IidManager::SetGroupName(uint16_t uid, std::string groupName)
476 {
477  NS_LOG_FUNCTION(IID << uid << groupName);
478  IidInformation* information = LookupInformation(uid);
479  information->groupName = groupName;
480 }
481 
482 void
483 IidManager::SetSize(uint16_t uid, std::size_t size)
484 {
485  NS_LOG_FUNCTION(IID << uid << size);
486  IidInformation* information = LookupInformation(uid);
487  information->size = size;
488 }
489 
490 void
492 {
493  NS_LOG_FUNCTION(IID << uid);
494  IidInformation* information = LookupInformation(uid);
495  information->mustHideFromDocumentation = true;
496 }
497 
498 void
500 {
501  NS_LOG_FUNCTION(IID << uid << &callback);
502  IidInformation* information = LookupInformation(uid);
503  if (information->hasConstructor)
504  {
505  NS_FATAL_ERROR(information->name << " already has a constructor.");
506  }
507  information->hasConstructor = true;
508  information->constructor = callback;
509 }
510 
511 uint16_t
512 IidManager::GetUid(std::string name) const
513 {
514  NS_LOG_FUNCTION(IID << name);
515  uint16_t uid = 0;
516  auto it = m_namemap.find(name);
517  if (it != m_namemap.end())
518  {
519  uid = it->second;
520  }
521  NS_LOG_LOGIC(IIDL << uid);
522  return uid;
523 }
524 
525 uint16_t
527 {
529  auto it = m_hashmap.find(hash);
530  uint16_t uid = 0;
531  if (it != m_hashmap.end())
532  {
533  uid = it->second;
534  }
535  NS_LOG_LOGIC(IIDL << uid);
536  return uid;
537 }
538 
539 std::string
540 IidManager::GetName(uint16_t uid) const
541 {
542  NS_LOG_FUNCTION(IID << uid);
543  IidInformation* information = LookupInformation(uid);
544  NS_LOG_LOGIC(IIDL << information->name);
545  return information->name;
546 }
547 
549 IidManager::GetHash(uint16_t uid) const
550 {
551  NS_LOG_FUNCTION(IID << uid);
552  IidInformation* information = LookupInformation(uid);
553  TypeId::hash_t hash = information->hash;
554  NS_LOG_LOGIC(IIDL << hash);
555  return hash;
556 }
557 
558 uint16_t
559 IidManager::GetParent(uint16_t uid) const
560 {
561  NS_LOG_FUNCTION(IID << uid);
562  IidInformation* information = LookupInformation(uid);
563  uint16_t pid = information->parent;
564  NS_LOG_LOGIC(IIDL << pid);
565  return pid;
566 }
567 
568 std::string
569 IidManager::GetGroupName(uint16_t uid) const
570 {
571  NS_LOG_FUNCTION(IID << uid);
572  IidInformation* information = LookupInformation(uid);
573  NS_LOG_LOGIC(IIDL << information->groupName);
574  return information->groupName;
575 }
576 
577 std::size_t
578 IidManager::GetSize(uint16_t uid) const
579 {
580  NS_LOG_FUNCTION(IID << uid);
581  IidInformation* information = LookupInformation(uid);
582  std::size_t size = information->size;
583  NS_LOG_LOGIC(IIDL << size);
584  return size;
585 }
586 
588 IidManager::GetConstructor(uint16_t uid) const
589 {
590  NS_LOG_FUNCTION(IID << uid);
591  IidInformation* information = LookupInformation(uid);
592  if (!information->hasConstructor)
593  {
594  NS_FATAL_ERROR("Requested constructor for " << information->name
595  << " but it does not have one.");
596  }
597  return information->constructor;
598 }
599 
600 bool
601 IidManager::HasConstructor(uint16_t uid) const
602 {
603  NS_LOG_FUNCTION(IID << uid);
604  IidInformation* information = LookupInformation(uid);
605  bool hasC = information->hasConstructor;
606  NS_LOG_LOGIC(IIDL << hasC);
607  return hasC;
608 }
609 
610 uint16_t
612 {
613  NS_LOG_FUNCTION(IID << m_information.size());
614  return static_cast<uint16_t>(m_information.size());
615 }
616 
617 uint16_t
618 IidManager::GetRegistered(uint16_t i) const
619 {
620  NS_LOG_FUNCTION(IID << i);
621  return i + 1;
622 }
623 
624 bool
625 IidManager::HasAttribute(uint16_t uid, std::string name)
626 {
627  NS_LOG_FUNCTION(IID << uid << name);
628  IidInformation* information = LookupInformation(uid);
629  while (true)
630  {
631  for (auto i = information->attributes.begin(); i != information->attributes.end(); ++i)
632  {
633  if (i->name == name)
634  {
635  NS_LOG_LOGIC(IIDL << true);
636  return true;
637  }
638  }
639  IidInformation* parent = LookupInformation(information->parent);
640  if (parent == information)
641  {
642  // top of inheritance tree
643  NS_LOG_LOGIC(IIDL << false);
644  return false;
645  }
646  // check parent
647  information = parent;
648  }
649  NS_LOG_LOGIC(IIDL << false);
650  return false;
651 }
652 
653 void
655  std::string name,
656  std::string help,
657  uint32_t flags,
658  Ptr<const AttributeValue> initialValue,
661  TypeId::SupportLevel supportLevel,
662  const std::string& supportMsg)
663 {
664  NS_LOG_FUNCTION(IID << uid << name << help << flags << initialValue << accessor << checker
665  << supportLevel << supportMsg);
666  IidInformation* information = LookupInformation(uid);
667  if (name.find(' ') != std::string::npos)
668  {
669  NS_FATAL_ERROR("Attribute name \"" << name << "\" may not contain spaces ' ', "
670  << "encountered when registering TypeId \""
671  << information->name << "\"");
672  }
673  if (HasAttribute(uid, name))
674  {
675  NS_FATAL_ERROR("Attribute \"" << name << "\" already registered on tid=\""
676  << information->name << "\"");
677  }
679  info.name = name;
680  info.help = help;
681  info.flags = flags;
682  info.initialValue = initialValue;
683  info.originalInitialValue = initialValue;
684  info.accessor = accessor;
685  info.checker = checker;
686  info.supportLevel = supportLevel;
687  info.supportMsg = supportMsg;
688  information->attributes.push_back(info);
689  NS_LOG_LOGIC(IIDL << information->attributes.size() - 1);
690 }
691 
692 void
694  std::size_t i,
695  Ptr<const AttributeValue> initialValue)
696 {
697  NS_LOG_FUNCTION(IID << uid << i << initialValue);
698  IidInformation* information = LookupInformation(uid);
699  NS_ASSERT(i < information->attributes.size());
700  information->attributes[i].initialValue = initialValue;
701 }
702 
703 std::size_t
704 IidManager::GetAttributeN(uint16_t uid) const
705 {
706  NS_LOG_FUNCTION(IID << uid);
707  IidInformation* information = LookupInformation(uid);
708  std::size_t size = information->attributes.size();
709  NS_LOG_LOGIC(IIDL << size);
710  return size;
711 }
712 
714 IidManager::GetAttribute(uint16_t uid, std::size_t i) const
715 {
716  NS_LOG_FUNCTION(IID << uid << i);
717  IidInformation* information = LookupInformation(uid);
718  NS_ASSERT(i < information->attributes.size());
719  NS_LOG_LOGIC(IIDL << information->name);
720  return information->attributes[i];
721 }
722 
723 bool
724 IidManager::HasTraceSource(uint16_t uid, std::string name)
725 {
726  NS_LOG_FUNCTION(IID << uid << name);
727  IidInformation* information = LookupInformation(uid);
728  while (true)
729  {
730  for (auto i = information->traceSources.begin(); i != information->traceSources.end(); ++i)
731  {
732  if (i->name == name)
733  {
734  NS_LOG_LOGIC(IIDL << true);
735  return true;
736  }
737  }
738  IidInformation* parent = LookupInformation(information->parent);
739  if (parent == information)
740  {
741  // top of inheritance tree
742  NS_LOG_LOGIC(IIDL << false);
743  return false;
744  }
745  // check parent
746  information = parent;
747  }
748  NS_LOG_LOGIC(IIDL << false);
749  return false;
750 }
751 
752 void
754  std::string name,
755  std::string help,
757  std::string callback,
758  TypeId::SupportLevel supportLevel,
759  const std::string& supportMsg)
760 {
761  NS_LOG_FUNCTION(IID << uid << name << help << accessor << callback << supportLevel
762  << supportMsg);
763  IidInformation* information = LookupInformation(uid);
764  if (HasTraceSource(uid, name))
765  {
766  NS_FATAL_ERROR("Trace source \"" << name << "\" already registered on tid=\""
767  << information->name << "\"");
768  }
770  source.name = name;
771  source.help = help;
772  source.accessor = accessor;
773  source.callback = callback;
774  source.supportLevel = supportLevel;
775  source.supportMsg = supportMsg;
776  information->traceSources.push_back(source);
777  NS_LOG_LOGIC(IIDL << information->traceSources.size() - 1);
778 }
779 
780 std::size_t
781 IidManager::GetTraceSourceN(uint16_t uid) const
782 {
783  NS_LOG_FUNCTION(IID << uid);
784  IidInformation* information = LookupInformation(uid);
785  std::size_t size = information->traceSources.size();
786  NS_LOG_LOGIC(IIDL << size);
787  return size;
788 }
789 
791 IidManager::GetTraceSource(uint16_t uid, std::size_t i) const
792 {
793  NS_LOG_FUNCTION(IID << uid << i);
794  IidInformation* information = LookupInformation(uid);
795  NS_ASSERT(i < information->traceSources.size());
796  NS_LOG_LOGIC(IIDL << information->name);
797  return information->traceSources[i];
798 }
799 
800 bool
802 {
803  NS_LOG_FUNCTION(IID << uid);
804  IidInformation* information = LookupInformation(uid);
805  bool hide = information->mustHideFromDocumentation;
806  NS_LOG_LOGIC(IIDL << hide);
807  return hide;
808 }
809 
810 } // namespace ns3
811 
812 namespace ns3
813 {
814 
815 /*********************************************************************
816  * The TypeId class
817  *********************************************************************/
818 
819 TypeId::TypeId(const std::string& name)
820 {
821  NS_LOG_FUNCTION(this << name);
822  uint16_t uid = IidManager::Get()->AllocateUid(name);
823  NS_LOG_LOGIC(uid);
824  NS_ASSERT(uid != 0);
825  m_tid = uid;
826 }
827 
828 TypeId::TypeId(uint16_t tid)
829  : m_tid(tid)
830 {
831  NS_LOG_FUNCTION(this << tid);
832 }
833 
834 TypeId
835 TypeId::LookupByName(std::string name)
836 {
837  NS_LOG_FUNCTION(name);
838  uint16_t uid = IidManager::Get()->GetUid(name);
839  NS_ASSERT_MSG(uid != 0, "Assert in TypeId::LookupByName: " << name << " not found");
840  return TypeId(uid);
841 }
842 
843 bool
844 TypeId::LookupByNameFailSafe(std::string name, TypeId* tid)
845 {
846  NS_LOG_FUNCTION(name << tid->GetUid());
847  uint16_t uid = IidManager::Get()->GetUid(name);
848  if (uid == 0)
849  {
850  return false;
851  }
852  *tid = TypeId(uid);
853  return true;
854 }
855 
856 TypeId
858 {
859  uint16_t uid = IidManager::Get()->GetUid(hash);
860  NS_ASSERT_MSG(uid != 0,
861  "Assert in TypeId::LookupByHash: 0x" << std::hex << hash << std::dec
862  << " not found");
863  return TypeId(uid);
864 }
865 
866 bool
868 {
869  uint16_t uid = IidManager::Get()->GetUid(hash);
870  if (uid == 0)
871  {
872  return false;
873  }
874  *tid = TypeId(uid);
875  return true;
876 }
877 
878 uint16_t
880 {
882  return IidManager::Get()->GetRegisteredN();
883 }
884 
885 TypeId
887 {
888  NS_LOG_FUNCTION(i);
889  return TypeId(IidManager::Get()->GetRegistered(i));
890 }
891 
892 bool
894 {
895  NS_LOG_FUNCTION(this << name << info);
896  TypeId tid;
897  TypeId nextTid = *this;
898  do
899  {
900  tid = nextTid;
901  for (std::size_t i = 0; i < tid.GetAttributeN(); i++)
902  {
904  if (tmp.name == name)
905  {
906  if (tmp.supportLevel == TypeId::SUPPORTED)
907  {
908  *info = tmp;
909  return true;
910  }
911  else if (tmp.supportLevel == TypeId::DEPRECATED)
912  {
913  std::cerr << "Attribute '" << name << "' is deprecated: " << tmp.supportMsg
914  << std::endl;
915  *info = tmp;
916  return true;
917  }
918  else if (tmp.supportLevel == TypeId::OBSOLETE)
919  {
920  NS_FATAL_ERROR("Attribute '" << name << "' is obsolete, with no fallback: "
921  << tmp.supportMsg);
922  }
923  }
924  }
925  nextTid = tid.GetParent();
926  } while (nextTid != tid);
927  return false;
928 }
929 
930 TypeId
932 {
933  NS_LOG_FUNCTION(this << tid.GetUid());
935  return *this;
936 }
937 
938 TypeId
939 TypeId::SetGroupName(std::string groupName)
940 {
941  NS_LOG_FUNCTION(this << groupName);
942  IidManager::Get()->SetGroupName(m_tid, groupName);
943  return *this;
944 }
945 
946 TypeId
947 TypeId::SetSize(std::size_t size)
948 {
949  NS_LOG_FUNCTION(this << size);
950  IidManager::Get()->SetSize(m_tid, size);
951  return *this;
952 }
953 
954 TypeId
956 {
957  NS_LOG_FUNCTION(this);
958  uint16_t parent = IidManager::Get()->GetParent(m_tid);
959  return TypeId(parent);
960 }
961 
962 bool
964 {
965  NS_LOG_FUNCTION(this);
966  uint16_t parent = IidManager::Get()->GetParent(m_tid);
967  return parent != m_tid;
968 }
969 
970 bool
972 {
973  NS_LOG_FUNCTION(this << other.GetUid());
974  TypeId tmp = *this;
975  while (tmp != other && tmp != tmp.GetParent())
976  {
977  tmp = tmp.GetParent();
978  }
979  return tmp == other && *this != other;
980 }
981 
982 std::string
984 {
985  NS_LOG_FUNCTION(this);
986  std::string groupName = IidManager::Get()->GetGroupName(m_tid);
987  return groupName;
988 }
989 
990 std::string
992 {
993  NS_LOG_FUNCTION(this);
994  std::string name = IidManager::Get()->GetName(m_tid);
995  return name;
996 }
997 
1000 {
1002  return hash;
1003 }
1004 
1005 std::size_t
1007 {
1008  NS_LOG_FUNCTION(this);
1009  std::size_t size = IidManager::Get()->GetSize(m_tid);
1010  return size;
1011 }
1012 
1013 bool
1015 {
1016  NS_LOG_FUNCTION(this);
1017  bool hasConstructor = IidManager::Get()->HasConstructor(m_tid);
1018  return hasConstructor;
1019 }
1020 
1021 void
1023 {
1024  NS_LOG_FUNCTION(this << &cb);
1026 }
1027 
1028 TypeId
1029 TypeId::AddAttribute(std::string name,
1030  std::string help,
1031  const AttributeValue& initialValue,
1034  SupportLevel supportLevel,
1035  const std::string& supportMsg)
1036 {
1037  NS_LOG_FUNCTION(this << name << help << &initialValue << accessor << checker << supportLevel
1038  << supportMsg);
1040  name,
1041  help,
1042  ATTR_SGC,
1043  initialValue.Copy(),
1044  accessor,
1045  checker,
1046  supportLevel,
1047  supportMsg);
1048  return *this;
1049 }
1050 
1051 TypeId
1052 TypeId::AddAttribute(std::string name,
1053  std::string help,
1054  uint32_t flags,
1055  const AttributeValue& initialValue,
1058  SupportLevel supportLevel,
1059  const std::string& supportMsg)
1060 {
1061  NS_LOG_FUNCTION(this << name << help << flags << &initialValue << accessor << checker
1062  << supportLevel << supportMsg);
1064  name,
1065  help,
1066  flags,
1067  initialValue.Copy(),
1068  accessor,
1069  checker,
1070  supportLevel,
1071  supportMsg);
1072  return *this;
1073 }
1074 
1075 bool
1077 {
1078  NS_LOG_FUNCTION(this << i << initialValue);
1079  IidManager::Get()->SetAttributeInitialValue(m_tid, i, initialValue);
1080  return true;
1081 }
1082 
1085 {
1086  NS_LOG_FUNCTION(this);
1088  return cb;
1089 }
1090 
1091 bool
1093 {
1094  NS_LOG_FUNCTION(this);
1095  bool mustHide = IidManager::Get()->MustHideFromDocumentation(m_tid);
1096  return mustHide;
1097 }
1098 
1099 std::size_t
1101 {
1102  NS_LOG_FUNCTION(this);
1103  std::size_t n = IidManager::Get()->GetAttributeN(m_tid);
1104  return n;
1105 }
1106 
1108 TypeId::GetAttribute(std::size_t i) const
1109 {
1110  NS_LOG_FUNCTION(this << i);
1111  return IidManager::Get()->GetAttribute(m_tid, i);
1112 }
1113 
1114 std::string
1115 TypeId::GetAttributeFullName(std::size_t i) const
1116 {
1117  NS_LOG_FUNCTION(this << i);
1119  return GetName() + "::" + info.name;
1120 }
1121 
1122 std::size_t
1124 {
1125  NS_LOG_FUNCTION(this);
1127 }
1128 
1130 TypeId::GetTraceSource(std::size_t i) const
1131 {
1132  NS_LOG_FUNCTION(this << i);
1133  return IidManager::Get()->GetTraceSource(m_tid, i);
1134 }
1135 
1136 TypeId
1137 TypeId::AddTraceSource(std::string name,
1138  std::string help,
1140  std::string callback,
1141  SupportLevel supportLevel,
1142  const std::string& supportMsg)
1143 {
1144  NS_LOG_FUNCTION(this << name << help << accessor << callback << supportLevel << supportMsg);
1145  IidManager::Get()
1146  ->AddTraceSource(m_tid, name, help, accessor, callback, supportLevel, supportMsg);
1147  return *this;
1148 }
1149 
1150 TypeId
1152 {
1153  NS_LOG_FUNCTION(this);
1155  return *this;
1156 }
1157 
1160 {
1161  NS_LOG_FUNCTION(this << name);
1162  TypeId tid;
1163  TypeId nextTid = *this;
1165  do
1166  {
1167  tid = nextTid;
1168  for (std::size_t i = 0; i < tid.GetTraceSourceN(); i++)
1169  {
1170  tmp = tid.GetTraceSource(i);
1171  if (tmp.name == name)
1172  {
1173  if (tmp.supportLevel == TypeId::SUPPORTED)
1174  {
1175  *info = tmp;
1176  return tmp.accessor;
1177  }
1178  else if (tmp.supportLevel == TypeId::DEPRECATED)
1179  {
1180  std::cerr << "TraceSource '" << name << "' is deprecated: " << tmp.supportMsg
1181  << std::endl;
1182  *info = tmp;
1183  return tmp.accessor;
1184  }
1185  else if (tmp.supportLevel == TypeId::OBSOLETE)
1186  {
1187  NS_FATAL_ERROR("TraceSource '" << name << "' is obsolete, with no fallback: "
1188  << tmp.supportMsg);
1189  }
1190  }
1191  }
1192  nextTid = tid.GetParent();
1193  } while (nextTid != tid);
1194  return nullptr;
1195 }
1196 
1198 TypeId::LookupTraceSourceByName(std::string name) const
1199 {
1201  return LookupTraceSourceByName(name, &info);
1202 }
1203 
1204 uint16_t
1206 {
1207  NS_LOG_FUNCTION(this);
1208  return m_tid;
1209 }
1210 
1211 void
1212 TypeId::SetUid(uint16_t uid)
1213 {
1214  NS_LOG_FUNCTION(this << uid);
1215  m_tid = uid;
1216 }
1217 
1224 std::ostream&
1225 operator<<(std::ostream& os, TypeId tid)
1226 {
1227  os << tid.GetName();
1228  return os;
1229 }
1230 
1237 std::istream&
1238 operator>>(std::istream& is, TypeId& tid)
1239 {
1240  std::string tidString;
1241  is >> tidString;
1242  bool ok = TypeId::LookupByNameFailSafe(tidString, &tid);
1243  if (!ok)
1244  {
1245  is.setstate(std::ios_base::badbit);
1246  }
1247  return is;
1248 }
1249 
1251 
1252 bool
1253 operator<(TypeId a, TypeId b)
1254 {
1255  return a.m_tid < b.m_tid;
1256 }
1257 
1258 } // namespace ns3
Hold a value for an Attribute.
Definition: attribute.h:70
virtual Ptr< AttributeValue > Copy() const =0
Callback template class.
Definition: callback.h:438
Generic Hash function interface.
Definition: hash.h:87
uint32_t GetHash32(const char *buffer, const std::size_t size)
Compute 32-bit hash of a byte buffer.
Definition: hash.h:236
Hasher & clear()
Restore initial state.
Definition: hash.cc:56
TypeId information manager.
Definition: type-id.cc:79
TypeId::hash_t GetHash(uint16_t uid) const
Get the hash of a type id.
Definition: type-id.cc:549
std::map< TypeId::hash_t, uint16_t > hashmap_t
Type of the by-hash index.
Definition: type-id.cc:343
std::vector< IidInformation >::const_iterator Iterator
Iterator type.
Definition: type-id.cc:325
uint16_t GetRegisteredN() const
Get the total number of type ids.
Definition: type-id.cc:611
uint16_t GetParent(uint16_t uid) const
Get the parent of a type id.
Definition: type-id.cc:559
std::map< std::string, uint16_t > namemap_t
Type of the by-name index.
Definition: type-id.cc:338
void SetAttributeInitialValue(uint16_t uid, std::size_t i, Ptr< const AttributeValue > initialValue)
Set the initial value of an Attribute.
Definition: type-id.cc:693
void SetGroupName(uint16_t uid, std::string groupName)
Set the group name of a type id.
Definition: type-id.cc:475
void SetParent(uint16_t uid, uint16_t parent)
Set the parent of a type id.
Definition: type-id.cc:466
std::vector< IidInformation > m_information
The container of all type id records.
Definition: type-id.cc:335
void SetSize(uint16_t uid, std::size_t size)
Set the size of the object class referred to by this id.
Definition: type-id.cc:483
std::string GetGroupName(uint16_t uid) const
Get the group name of a type id.
Definition: type-id.cc:569
bool HasTraceSource(uint16_t uid, std::string name)
Check if a type id has a given TraceSource.
Definition: type-id.cc:724
uint16_t GetRegistered(uint16_t i) const
Get a type id by index.
Definition: type-id.cc:618
Callback< ObjectBase * > GetConstructor(uint16_t uid) const
Get the constructor Callback of a type id.
Definition: type-id.cc:588
std::size_t GetAttributeN(uint16_t uid) const
Get the number of attributes.
Definition: type-id.cc:704
uint16_t GetUid(std::string name) const
Get a type id by name.
Definition: type-id.cc:512
void AddConstructor(uint16_t uid, Callback< ObjectBase * > callback)
Add a constructor Callback to this type id.
Definition: type-id.cc:499
void HideFromDocumentation(uint16_t uid)
Mark this type id to be excluded from documentation.
Definition: type-id.cc:491
std::string GetName(uint16_t uid) const
Get the name of a type id.
Definition: type-id.cc:540
std::size_t GetTraceSourceN(uint16_t uid) const
Get the number of Trace sources.
Definition: type-id.cc:781
std::size_t GetSize(uint16_t uid) const
Get the size of a type id.
Definition: type-id.cc:578
TypeId::TraceSourceInformation GetTraceSource(uint16_t uid, std::size_t i) const
Get the trace source by index.
Definition: type-id.cc:791
@ HashChainFlag
Hash chaining flag.
Definition: type-id.cc:356
bool MustHideFromDocumentation(uint16_t uid) const
Check if this TypeId should not be listed in documentation.
Definition: type-id.cc:801
IidManager::IidInformation * LookupInformation(uint16_t uid) const
Retrieve the information record for a type.
Definition: type-id.cc:457
bool HasConstructor(uint16_t uid) const
Check if a type id has a constructor Callback.
Definition: type-id.cc:601
bool HasAttribute(uint16_t uid, std::string name)
Check if a type id has a given Attribute.
Definition: type-id.cc:625
static TypeId::hash_t Hasher(const std::string name)
Hashing function.
Definition: type-id.cc:362
hashmap_t m_hashmap
The by-hash index.
Definition: type-id.cc:345
uint16_t AllocateUid(std::string name)
Create a new unique type id.
Definition: type-id.cc:382
void AddAttribute(uint16_t uid, std::string name, std::string help, uint32_t flags, Ptr< const AttributeValue > initialValue, Ptr< const AttributeAccessor > accessor, Ptr< const AttributeChecker > checker, TypeId::SupportLevel supportLevel=TypeId::SUPPORTED, const std::string &supportMsg="")
Record a new attribute in a type id.
Definition: type-id.cc:654
void AddTraceSource(uint16_t uid, std::string name, std::string help, Ptr< const TraceSourceAccessor > accessor, std::string callback, TypeId::SupportLevel supportLevel=TypeId::SUPPORTED, const std::string &supportMsg="")
Record a new TraceSource.
Definition: type-id.cc:753
TypeId::AttributeInformation GetAttribute(uint16_t uid, std::size_t i) const
Get Attribute information by index.
Definition: type-id.cc:714
namemap_t m_namemap
The by-name index.
Definition: type-id.cc:340
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
A template singleton.
Definition: singleton.h:61
static IidManager * Get()
Get a pointer to the singleton instance.
Definition: singleton.h:100
a unique identifier for an interface.
Definition: type-id.h:59
bool IsChildOf(TypeId other) const
Check if this TypeId is a child of another.
Definition: type-id.cc:971
std::size_t GetTraceSourceN() const
Get the number of Trace sources.
Definition: type-id.cc:1123
bool SetAttributeInitialValue(std::size_t i, Ptr< const AttributeValue > initialValue)
Set the initial value of an Attribute.
Definition: type-id.cc:1076
static TypeId LookupByName(std::string name)
Get a TypeId by name.
Definition: type-id.cc:835
bool HasParent() const
Check if this TypeId has a parent.
Definition: type-id.cc:963
TypeId SetSize(std::size_t size)
Set the size of this type.
Definition: type-id.cc:947
hash_t GetHash() const
Get the hash.
Definition: type-id.cc:999
TypeId AddTraceSource(std::string name, std::string help, Ptr< const TraceSourceAccessor > accessor, std::string callback, SupportLevel supportLevel=SUPPORTED, const std::string &supportMsg="")
Record a new TraceSource.
Definition: type-id.cc:1137
bool MustHideFromDocumentation() const
Check if this TypeId should not be listed in documentation.
Definition: type-id.cc:1092
@ ATTR_SGC
The attribute can be read, and written at any time.
Definition: type-id.h:67
static bool LookupByHashFailSafe(hash_t hash, TypeId *tid)
Get a TypeId by hash.
Definition: type-id.cc:867
TypeId::TraceSourceInformation GetTraceSource(std::size_t i) const
Get the trace source by index.
Definition: type-id.cc:1130
std::string GetGroupName() const
Get the group name.
Definition: type-id.cc:983
TypeId HideFromDocumentation()
Hide this TypeId from documentation.
Definition: type-id.cc:1151
Callback< ObjectBase * > GetConstructor() const
Get the constructor callback.
Definition: type-id.cc:1084
static uint16_t GetRegisteredN()
Get the number of registered TypeIds.
Definition: type-id.cc:879
std::string GetAttributeFullName(std::size_t i) const
Get the Attribute name by index.
Definition: type-id.cc:1115
bool HasConstructor() const
Check if this TypeId has a constructor.
Definition: type-id.cc:1014
std::size_t GetAttributeN() const
Get the number of attributes.
Definition: type-id.cc:1100
TypeId GetParent() const
Get the parent of this TypeId.
Definition: type-id.cc:955
void SetUid(uint16_t uid)
Set the internal id of this TypeId.
Definition: type-id.cc:1212
uint16_t m_tid
The TypeId value.
Definition: type-id.h:565
TypeId SetGroupName(std::string groupName)
Set the group name.
Definition: type-id.cc:939
static TypeId LookupByHash(hash_t hash)
Get a TypeId by hash.
Definition: type-id.cc:857
static TypeId GetRegistered(uint16_t i)
Get a TypeId by index.
Definition: type-id.cc:886
std::size_t GetSize() const
Get the size of this object.
Definition: type-id.cc:1006
Ptr< const TraceSourceAccessor > LookupTraceSourceByName(std::string name) const
Find a TraceSource by name.
Definition: type-id.cc:1198
uint32_t hash_t
Type of hash values.
Definition: type-id.h:120
TypeId()
Default constructor.
Definition: type-id.h:605
TypeId::AttributeInformation GetAttribute(std::size_t i) const
Get Attribute information by index.
Definition: type-id.cc:1108
uint16_t GetUid() const
Get the internal id of this TypeId.
Definition: type-id.cc:1205
static bool LookupByNameFailSafe(std::string name, TypeId *tid)
Get a TypeId by name.
Definition: type-id.cc:844
SupportLevel
The level of support or deprecation for attributes or trace sources.
Definition: type-id.h:73
@ SUPPORTED
Attribute or trace source is currently used.
Definition: type-id.h:74
@ OBSOLETE
Attribute or trace source is not used anymore; simulation fails.
Definition: type-id.h:76
@ DEPRECATED
Attribute or trace source is deprecated; user is warned.
Definition: type-id.h:75
TypeId AddAttribute(std::string name, std::string help, const AttributeValue &initialValue, Ptr< const AttributeAccessor > accessor, Ptr< const AttributeChecker > checker, SupportLevel supportLevel=SUPPORTED, const std::string &supportMsg="")
Record in this TypeId the fact that a new attribute exists.
Definition: type-id.cc:1029
bool LookupAttributeByName(std::string name, AttributeInformation *info) const
Find an Attribute by name, retrieving the associated AttributeInformation.
Definition: type-id.cc:893
std::string GetName() const
Get the name.
Definition: type-id.cc:991
TypeId SetParent()
Set the parent TypeId.
Definition: type-id.h:644
void DoAddConstructor(Callback< ObjectBase * > callback)
Implementation for AddConstructor().
Definition: type-id.cc:1022
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
Definition: abort.h:144
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:254
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define IIDL
Definition: type-id.cc:379
#define IID
Definition: type-id.cc:373
ns3::Hasher, ns3::Hash32() and ns3::Hash64() function declarations.
Debug message logging.
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition: json.h:4680
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ATTRIBUTE_HELPER_CPP(ValueClassTest)
bool operator<(const EventId &a, const EventId &b)
Definition: event-id.h:170
std::istream & operator>>(std::istream &is, Angles &a)
Definition: angles.cc:183
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:159
ns3::Singleton declaration and template implementation.
The information record about a single type id.
Definition: type-id.cc:297
std::string groupName
The group name.
Definition: type-id.cc:305
uint16_t parent
The parent type id.
Definition: type-id.cc:303
std::vector< TypeId::TraceSourceInformation > traceSources
The container of TraceSources.
Definition: type-id.cc:317
std::size_t size
The size of the object represented by this type id.
Definition: type-id.cc:307
std::string supportMsg
Support message.
Definition: type-id.cc:321
std::string name
The type id name.
Definition: type-id.cc:299
std::vector< TypeId::AttributeInformation > attributes
The container of Attributes.
Definition: type-id.cc:315
Callback< ObjectBase * > constructor
The constructor Callback.
Definition: type-id.cc:311
bool hasConstructor
true if a constructor Callback has been registered.
Definition: type-id.cc:309
bool mustHideFromDocumentation
true if this type should be omitted from documentation.
Definition: type-id.cc:313
TypeId::hash_t hash
The type id hash value.
Definition: type-id.cc:301
TypeId::SupportLevel supportLevel
Support level/deprecation.
Definition: type-id.cc:319
Attribute implementation.
Definition: type-id.h:81
Ptr< const AttributeValue > originalInitialValue
Default initial value.
Definition: type-id.h:89
TypeId::SupportLevel supportLevel
Support level/deprecation.
Definition: type-id.h:97
std::string name
Attribute name.
Definition: type-id.h:83
Ptr< const AttributeAccessor > accessor
Accessor object.
Definition: type-id.h:93
uint32_t flags
AttributeFlags value.
Definition: type-id.h:87
Ptr< const AttributeChecker > checker
Checker object.
Definition: type-id.h:95
std::string supportMsg
Support message.
Definition: type-id.h:99
Ptr< const AttributeValue > initialValue
Configured initial value.
Definition: type-id.h:91
std::string help
Attribute help string.
Definition: type-id.h:85
TraceSource implementation.
Definition: type-id.h:104
std::string name
Trace name.
Definition: type-id.h:106
std::string supportMsg
Support message.
Definition: type-id.h:116
std::string help
Trace help string.
Definition: type-id.h:108
Ptr< const TraceSourceAccessor > accessor
Trace accessor.
Definition: type-id.h:112
std::string callback
Callback function signature type.
Definition: type-id.h:110
TypeId::SupportLevel supportLevel
Support level/deprecation.
Definition: type-id.h:114
ns3::TraceSourceAccessor and ns3::MakeTraceSourceAccessor declarations.
ns3::TypeId declaration; inline and template implementations.