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