A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
names.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2009 University of Washington
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 */
6
7#include "names.h"
8
9#include "abort.h"
10#include "assert.h"
11#include "log.h"
12#include "object.h"
13#include "singleton.h"
14
15#include <map>
16
17/**
18 * \file
19 * \ingroup config
20 * ns3::Names, ns3::NamesNode and ns3::NamePriv implementations.
21 */
22
23namespace ns3
24{
25
27
28/**
29 * \ingroup config
30 * Node in the naming tree.
31 */
33{
34 public:
35 /** Default constructor. */
36 NameNode();
37 /**
38 * Copy constructor.
39 *
40 * \param [in] nameNode The NameNode to copy from.
41 */
42 NameNode(const NameNode& nameNode);
43 /**
44 * Constructor.
45 *
46 * \param [in] parent The parent NameNode.
47 * \param [in] name The name of this NameNode
48 * \param [in] object The object corresponding to this NameNode.
49 */
50 NameNode(NameNode* parent, std::string name, Ptr<Object> object);
51 /**
52 * Assignment operator.
53 *
54 * \param [in] rhs The NameNode to copy from.
55 * \returns The lhs NameNode.
56 */
57 NameNode& operator=(const NameNode& rhs);
58
59 /** Destructor. */
60 ~NameNode();
61
62 /** The parent NameNode. */
64 /** The name of this NameNode. */
65 std::string m_name;
66 /** The object corresponding to this NameNode. */
68
69 /** Children of this NameNode. */
70 std::map<std::string, NameNode*> m_nameMap;
71};
72
74 : m_parent(nullptr),
75 m_name(""),
76 m_object(nullptr)
77{
78}
79
81{
82 m_parent = nameNode.m_parent;
83 m_name = nameNode.m_name;
84 m_object = nameNode.m_object;
85 m_nameMap = nameNode.m_nameMap;
86}
87
90{
91 m_parent = rhs.m_parent;
92 m_name = rhs.m_name;
93 m_object = rhs.m_object;
94 m_nameMap = rhs.m_nameMap;
95 return *this;
96}
97
98NameNode::NameNode(NameNode* parent, std::string name, Ptr<Object> object)
99 : m_parent(parent),
100 m_name(name),
101 m_object(object)
102{
103 NS_LOG_FUNCTION(this << parent << name << object);
104}
105
110
111/**
112 * \ingroup config
113 * The singleton root Names object.
114 */
115class NamesPriv : public Singleton<NamesPriv>
116{
117 public:
118 /** Constructor. */
119 NamesPriv();
120 /** Destructor. */
121 ~NamesPriv() override;
122
123 // Doxygen \copydoc bug: won't copy these docs, so we repeat them.
124
125 /**
126 * Internal implementation for Names::Add(std::string,Ptr<Object>)
127 *
128 * \param [in] name The name of the object you want to associate;
129 * which may be prepended with a path to that object.
130 * \param [in] object A smart pointer to the object itself.
131 * \return \c true if the object was named successfully.
132 */
133 bool Add(std::string name, Ptr<Object> object);
134 /**
135 * Internal implementation for Names::Add(std::string,std::string,Ptr<Object>)
136 *
137 * \param [in] path A path name describing a previously named object
138 * under which you want this new name to be defined.
139 * \param [in] name The name of the object you want to associate.
140 * \param [in] object A smart pointer to the object itself.
141 * \return \c true if the object was named successfully.
142 */
143 bool Add(std::string path, std::string name, Ptr<Object> object);
144 /**
145 * Internal implementation for Names::Add(Ptr<Object>,std::string,Ptr<Object>)
146 *
147 * \param [in] context A smart pointer to an object that is used
148 * in place of the path under which you want this new
149 * name to be defined.
150 * \param [in] name The name of the object you want to associate.
151 * \param [in] object A smart pointer to the object itself.
152 * \return \c true if the object was named successfully.
153 */
154 bool Add(Ptr<Object> context, std::string name, Ptr<Object> object);
155
156 /**
157 * Internal implementation for Names::Rename(std::string,std::string)
158 *
159 * \param [in] oldpath The current path name to the object you want
160 * to change.
161 * \param [in] newname The new name of the object you want to change.
162 * \return \c true if the object was renamed successfully.
163 */
164 bool Rename(std::string oldpath, std::string newname);
165 /**
166 * Internal implementation for
167 * Names::Rename(std::string,std::string,std::string)
168 *
169 * \param [in] path A path name describing a previously named object
170 * under which you want this name change to occur
171 * (cf. directory).
172 * \param [in] oldname The currently defined name of the object.
173 * \param [in] newname The new name you want the object to have.
174 * \return \c true if the object was renamed successfully.
175 */
176 bool Rename(std::string path, std::string oldname, std::string newname);
177 /**
178 * Internal implementation for
179 * Names::Rename(Ptr<Object>,std::string,std::string)
180 *
181 * \param [in] context A smart pointer to an object that is used
182 * in place of the path under which you want this
183 * new name to be defined.
184 * \param [in] oldname The current shortname of the object you want
185 * to change.
186 * \param [in] newname The new shortname of the object you want
187 * to change.
188 * \return \c true if the object was renamed successfully.
189 */
190 bool Rename(Ptr<Object> context, std::string oldname, std::string newname);
191
192 /**
193 * Internal implementation for Names::FindName()
194 *
195 * \param [in] object A smart pointer to an object for which you want
196 * to find its name.
197 * \returns A string containing the name of the object if found,
198 * otherwise the empty string.
199 */
200 std::string FindName(Ptr<Object> object);
201 /**
202 * Internal implementation of Names::FindPath()
203 *
204 * \param [in] object A smart pointer to an object for which you
205 * want to find its fullname.
206 * \returns A string containing the name path of the object,
207 * otherwise the empty string.
208 */
209 std::string FindPath(Ptr<Object> object);
210
211 /**
212 * Internal implementation for Names::Clear()
213 */
214 void Clear();
215
216 /**
217 * Internal implementation for ns3::Names::Find(std::string)
218 *
219 * \param [in] path A string containing a name space path used
220 * to locate the object.
221 * \returns A smart pointer to the named object converted to
222 * the requested type.
223 */
224 Ptr<Object> Find(std::string path);
225 /**
226 * Internal implementation for ns3::Names::Find(std::string,std::string)
227 *
228 * \param [in] path A path name describing a previously named object
229 * under which you want to look for the specified name.
230 * \param [in] name A string containing a name to search for.
231 * \returns A smart pointer to the named object converted to
232 * the requested type.
233 */
234 Ptr<Object> Find(std::string path, std::string name);
235 /**
236 * Internal implementation for ns3::Names::Find(Ptr<Object>,std::string)
237 *
238 * \param [in] context A smart pointer to an object that is used
239 * in place of the path under which you want this
240 * new name to be defined.
241 * \param [in] name A string containing a name to search for.
242 * \returns A smart pointer to the named object converted to
243 * the requested type.
244 */
245 Ptr<Object> Find(Ptr<Object> context, std::string name);
246
247 private:
248 /**
249 * Check if an object has a name.
250 *
251 * \param [in] object The object to check.
252 * \returns The corresponding NameNode, if it exists.
253 */
255 /**
256 * Check if a name already exists as a child of a NameNode.
257 *
258 * \param [in] node The node to search.
259 * \param [in] name The name to search for.
260 * \returns \c true if \c name already exists as a child of \c node.
261 */
262 bool IsDuplicateName(NameNode* node, std::string name);
263
264 /** The root NameNode. */
266
267 /** Map from object pointers to their NameNodes. */
268 std::map<Ptr<Object>, NameNode*> m_objectMap;
269};
270
272{
273 NS_LOG_FUNCTION(this);
274
275 m_root.m_parent = nullptr;
276 m_root.m_name = "Names";
277 m_root.m_object = nullptr;
278}
279
281{
282 NS_LOG_FUNCTION(this);
283 Clear();
284 m_root.m_name = "";
285}
286
287void
289{
290 NS_LOG_FUNCTION(this);
291 //
292 // Every name is associated with an object in the object map, so freeing the
293 // NameNodes in this map will free all of the memory allocated for the NameNodes
294 //
295 for (auto i = m_objectMap.begin(); i != m_objectMap.end(); ++i)
296 {
297 delete i->second;
298 i->second = nullptr;
299 }
300
301 m_objectMap.clear();
302
303 m_root.m_parent = nullptr;
304 m_root.m_name = "Names";
305 m_root.m_object = nullptr;
306 m_root.m_nameMap.clear();
307}
308
309bool
310NamesPriv::Add(std::string name, Ptr<Object> object)
311{
312 NS_LOG_FUNCTION(this << name << object);
313 //
314 // This is the simple, easy to use version of Add, so we want it to be flexible.
315 // We don't want to force a user to always type the fully qualified namespace
316 // name, so we allow the namespace name to be omitted. For example, calling
317 // Add ("Client/ath0", obj) should result in exactly the same behavior as
318 // Add ("/Names/Client/ath0", obj). Calling Add ("Client", obj) should have
319 // the same effect as Add ("Names/Client", obj)
320 //
321 // The first thing to do, then, is to "canonicalize" the input string to always
322 // be a fully qualified name.
323 //
324 // If we are given a name that begins with "/Names/" we assume that this is a
325 // fully qualified path name to the object we want to create. We split the name
326 // into a path string and a final segment (name) and then call the "Real" Add.
327 //
328 std::string namespaceName = "/Names";
329 std::string::size_type offset = name.find(namespaceName);
330 if (offset != 0)
331 {
332 //
333 // This must be a name that has the "/Names" namespace prefix omitted.
334 // Do some reasonableness checking on the rest of the name.
335 //
336 offset = name.find('/');
337 if (offset == 0)
338 {
339 NS_ASSERT_MSG(false, "NamesPriv::Add(): Name begins with '/' but not \"/Names\"");
340 return false;
341 }
342
343 name = "/Names/" + name;
344 }
345
346 //
347 // There must now be a fully qualified path in the string. All fully
348 // qualified names begin with "/Names". We have to split off the final
349 // segment which will become the name of the object. A '/' that
350 // separates the path from the final segment had better be there since
351 // we just made sure that at least the namespace name was there.
352 //
353 std::string::size_type i = name.rfind('/');
354 NS_ASSERT_MSG(i != std::string::npos,
355 "NamesPriv::Add(): Internal error. Can't find '/' in name");
356
357 //
358 // The slash we found cannot be the slash at the start of the namespaceName.
359 // This would indicate there is no name in the path at all. It can be
360 // any other index.
361 //
362 NS_ASSERT_MSG(i != 0, "NamesPriv::Add(): Can't find a name in the path string");
363
364 //
365 // We now know where the path string starts and ends, and where the
366 // name starts and ends. All we have to do is to call our available
367 // function for adding a name under a path string.
368 //
369 return Add(name.substr(0, i), name.substr(i + 1), object);
370}
371
372bool
373NamesPriv::Add(std::string path, std::string name, Ptr<Object> object)
374{
375 NS_LOG_FUNCTION(this << path << name << object);
376 if (path == "/Names")
377 {
378 return Add(Ptr<Object>(nullptr, false), name, object);
379 }
380 return Add(Find(path), name, object);
381}
382
383bool
384NamesPriv::Add(Ptr<Object> context, std::string name, Ptr<Object> object)
385{
386 NS_LOG_FUNCTION(this << context << name << object);
387
388 if (IsNamed(object))
389 {
390 NS_LOG_LOGIC("Object is already named");
391 return false;
392 }
393
394 NameNode* node = nullptr;
395 if (context)
396 {
397 node = IsNamed(context);
398 NS_ASSERT_MSG(node, "NamesPriv::Name(): context must point to a previously named node");
399 }
400 else
401 {
402 node = &m_root;
403 }
404
405 if (IsDuplicateName(node, name))
406 {
407 NS_LOG_LOGIC("Name is already taken");
408 return false;
409 }
410
411 auto newNode = new NameNode(node, name, object);
412 node->m_nameMap[name] = newNode;
413 m_objectMap[object] = newNode;
414
415 return true;
416}
417
418bool
419NamesPriv::Rename(std::string oldpath, std::string newname)
420{
421 NS_LOG_FUNCTION(this << oldpath << newname);
422 //
423 // This is the simple, easy to use version of Rename, so we want it to be
424 // flexible. We don't want to force a user to always type the fully
425 // qualified namespace name, so we allow the namespace name to be omitted.
426 // For example, calling Rename ("Client/ath0", "eth0") should result in
427 // exactly the same behavior as Rename ("/Names/Client/ath0", "eth0").
428 // Calling Rename ("Client", "Router") should have the same effect as
429 // Rename ("Names/Client", "Router")
430 //
431 // The first thing to do, then, is to "canonicalize" the input string to always
432 // be a fully qualified path.
433 //
434 // If we are given a name that begins with "/Names/" we assume that this is a
435 // fully qualified path to the object we want to change. We split the path into
436 // path string (cf directory) and a final segment (cf filename) and then call
437 // the "Real" Rename.
438 //
439 std::string namespaceName = "/Names";
440 std::string::size_type offset = oldpath.find(namespaceName);
441 if (offset != 0)
442 {
443 //
444 // This must be a name that has the "/Names" namespace prefix omitted.
445 // Do some reasonableness checking on the rest of the name.
446 //
447 offset = oldpath.find('/');
448 if (offset == 0)
449 {
450 NS_ASSERT_MSG(false, "NamesPriv::Add(): Name begins with '/' but not \"/Names\"");
451 return false;
452 }
453
454 oldpath = "/Names/" + oldpath;
455 }
456
457 //
458 // There must now be a fully qualified path in the oldpath string. All
459 // fully qualified names begin with "/Names". We have to split off the final
460 // segment which will become the name we want to rename. A '/' that
461 // separates the path from the final segment (name) had better be there since
462 // we just made sure that at least the namespace name was there.
463 //
464 std::string::size_type i = oldpath.rfind('/');
465 NS_ASSERT_MSG(i != std::string::npos,
466 "NamesPriv::Add(): Internal error. Can't find '/' in name");
467
468 //
469 // The slash we found cannot be the slash at the start of the namespaceName.
470 // This would indicate there is no name in the path at all. It can be
471 // any other index.
472 //
473 NS_ASSERT_MSG(i != 0, "NamesPriv::Add(): Can't find a name in the path string");
474
475 //
476 // We now know where the path part of the string starts and ends, and where the
477 // name part starts and ends. All we have to do is to call our available
478 // function for creating adding a name under a path string.
479 //
480 return Rename(oldpath.substr(0, i), oldpath.substr(i + 1), newname);
481}
482
483bool
484NamesPriv::Rename(std::string path, std::string oldname, std::string newname)
485{
486 NS_LOG_FUNCTION(this << path << oldname << newname);
487 if (path == "/Names")
488 {
489 return Rename(Ptr<Object>(nullptr, false), oldname, newname);
490 }
491 return Rename(Find(path), oldname, newname);
492}
493
494bool
495NamesPriv::Rename(Ptr<Object> context, std::string oldname, std::string newname)
496{
497 NS_LOG_FUNCTION(this << context << oldname << newname);
498
499 NameNode* node = nullptr;
500 if (context)
501 {
502 node = IsNamed(context);
503 NS_ASSERT_MSG(node, "NamesPriv::Name(): context must point to a previously named node");
504 }
505 else
506 {
507 node = &m_root;
508 }
509
510 if (IsDuplicateName(node, newname))
511 {
512 NS_LOG_LOGIC("New name is already taken");
513 return false;
514 }
515
516 auto i = node->m_nameMap.find(oldname);
517 if (i == node->m_nameMap.end())
518 {
519 NS_LOG_LOGIC("Old name does not exist in name map");
520 return false;
521 }
522 else
523 {
524 NS_LOG_LOGIC("Old name exists in name map");
525
526 //
527 // The rename process consists of:
528 // 1. Getting the pointer to the name node from the map and remembering it;
529 // 2. Removing the map entry corresponding to oldname from the map;
530 // 3. Changing the name string in the name node;
531 // 4. Adding the name node back in the map under the newname.
532 //
533 NameNode* changeNode = i->second;
534 node->m_nameMap.erase(i);
535 changeNode->m_name = newname;
536 node->m_nameMap[newname] = changeNode;
537 return true;
538 }
539}
540
541std::string
543{
544 NS_LOG_FUNCTION(this << object);
545
546 auto i = m_objectMap.find(object);
547 if (i == m_objectMap.end())
548 {
549 NS_LOG_LOGIC("Object does not exist in object map");
550 return "";
551 }
552 else
553 {
554 NS_LOG_LOGIC("Object exists in object map");
555 return i->second->m_name;
556 }
557}
558
559std::string
561{
562 NS_LOG_FUNCTION(this << object);
563
564 auto i = m_objectMap.find(object);
565 if (i == m_objectMap.end())
566 {
567 NS_LOG_LOGIC("Object does not exist in object map");
568 return "";
569 }
570
571 NameNode* p = i->second;
573 "NamesPriv::FindFullName(): Internal error: Invalid NameNode pointer from map");
574
575 std::string path;
576
577 do
578 {
579 path = "/" + p->m_name + path;
580 NS_LOG_LOGIC("path is " << path);
581 } while ((p = p->m_parent) != nullptr);
582
583 return path;
584}
585
587NamesPriv::Find(std::string path)
588{
589 //
590 // This is hooked in from simple, easy to use version of Find, so we want it
591 // to be flexible.
592 //
593 // If we are provided a path that doesn't begin with "/Names", we assume
594 // that the caller has simply given us a path starting with a name that
595 // is in the root namespace. This allows people to omit the "/Names" prefix.
596 // and simply do a Find ("Client/eth0") instead of having to always do a
597 // Find ("/Names/Client/eth0");
598 //
599 // So, if we are given a name that begins with "/Names/" the upshot is that we
600 // just remove that prefix and treat the rest of the string as starting with a
601 // name in the root namespace.
602 //
603
604 NS_LOG_FUNCTION(this << path);
605 std::string namespaceName = "/Names/";
606 std::string remaining;
607
608 std::string::size_type offset = path.find(namespaceName);
609 if (offset == 0)
610 {
611 NS_LOG_LOGIC(path << " is a fully qualified name");
612 remaining = path.substr(namespaceName.size());
613 }
614 else
615 {
616 NS_LOG_LOGIC(path << " begins with a relative name");
617 remaining = path;
618 }
619
620 NameNode* node = &m_root;
621
622 //
623 // The string <remaining> is now composed entirely of path segments in
624 // the /Names name space and we have eaten the leading slash. e.g.,
625 // remaining = "ClientNode/eth0"
626 //
627 // The start of the search is always at the root of the name space.
628 //
629 for (;;)
630 {
631 NS_LOG_LOGIC("Looking for the object of name " << remaining);
632 offset = remaining.find('/');
633 if (offset == std::string::npos)
634 {
635 //
636 // There are no remaining slashes so this is the last segment of the
637 // specified name. We're done when we find it
638 //
639 auto i = node->m_nameMap.find(remaining);
640 if (i == node->m_nameMap.end())
641 {
642 NS_LOG_LOGIC("Name does not exist in name map");
643 return nullptr;
644 }
645 else
646 {
647 NS_LOG_LOGIC("Name parsed, found object");
648 return i->second->m_object;
649 }
650 }
651 else
652 {
653 //
654 // There are more slashes so this is an intermediate segment of the
655 // specified name. We need to "recurse" when we find this segment.
656 //
657 offset = remaining.find('/');
658 std::string segment = remaining.substr(0, offset);
659
660 auto i = node->m_nameMap.find(segment);
661 if (i == node->m_nameMap.end())
662 {
663 NS_LOG_LOGIC("Name does not exist in name map");
664 return nullptr;
665 }
666 else
667 {
668 node = i->second;
669 remaining = remaining.substr(offset + 1);
670 NS_LOG_LOGIC("Intermediate segment parsed");
671 continue;
672 }
673 }
674 }
675
676 NS_ASSERT_MSG(node, "NamesPriv::Find(): Internal error: this can't happen");
677 return nullptr;
678}
679
681NamesPriv::Find(std::string path, std::string name)
682{
683 NS_LOG_FUNCTION(this << path << name);
684
685 if (path == "/Names")
686 {
687 return Find(Ptr<Object>(nullptr, false), name);
688 }
689 return Find(Find(path), name);
690}
691
693NamesPriv::Find(Ptr<Object> context, std::string name)
694{
695 NS_LOG_FUNCTION(this << context << name);
696
697 NameNode* node = nullptr;
698
699 if (!context)
700 {
701 NS_LOG_LOGIC("Zero context implies root NameNode");
702 node = &m_root;
703 }
704 else
705 {
706 node = IsNamed(context);
707 if (node == nullptr)
708 {
709 NS_LOG_LOGIC("Context does not point to a previously named node");
710 return nullptr;
711 }
712 }
713
714 auto i = node->m_nameMap.find(name);
715 if (i == node->m_nameMap.end())
716 {
717 NS_LOG_LOGIC("Name does not exist in name map");
718 return nullptr;
719 }
720 else
721 {
722 NS_LOG_LOGIC("Name exists in name map");
723 return i->second->m_object;
724 }
725}
726
729{
730 NS_LOG_FUNCTION(this << object);
731
732 auto i = m_objectMap.find(object);
733 if (i == m_objectMap.end())
734 {
735 NS_LOG_LOGIC("Object does not exist in object map, returning NameNode 0");
736 return nullptr;
737 }
738 else
739 {
740 NS_LOG_LOGIC("Object exists in object map, returning NameNode " << &i->second);
741 return i->second;
742 }
743}
744
745bool
746NamesPriv::IsDuplicateName(NameNode* node, std::string name)
747{
748 NS_LOG_FUNCTION(this << node << name);
749
750 auto i = node->m_nameMap.find(name);
751 if (i == node->m_nameMap.end())
752 {
753 NS_LOG_LOGIC("Name does not exist in name map");
754 return false;
755 }
756 else
757 {
758 NS_LOG_LOGIC("Name exists in name map");
759 return true;
760 }
761}
762
763void
764Names::Add(std::string name, Ptr<Object> object)
765{
766 NS_LOG_FUNCTION(name << object);
767 bool result = NamesPriv::Get()->Add(name, object);
768 NS_ABORT_MSG_UNLESS(result, "Names::Add(): Error adding name " << name);
769}
770
771void
772Names::Rename(std::string oldpath, std::string newname)
773{
774 NS_LOG_FUNCTION(oldpath << newname);
775 bool result = NamesPriv::Get()->Rename(oldpath, newname);
776 NS_ABORT_MSG_UNLESS(result, "Names::Rename(): Error renaming " << oldpath << " to " << newname);
777}
778
779void
780Names::Add(std::string path, std::string name, Ptr<Object> object)
781{
782 NS_LOG_FUNCTION(path << name << object);
783 bool result = NamesPriv::Get()->Add(path, name, object);
784 NS_ABORT_MSG_UNLESS(result, "Names::Add(): Error adding " << path << " " << name);
785}
786
787void
788Names::Rename(std::string path, std::string oldname, std::string newname)
789{
790 NS_LOG_FUNCTION(path << oldname << newname);
791 bool result = NamesPriv::Get()->Rename(path, oldname, newname);
792 NS_ABORT_MSG_UNLESS(result,
793 "Names::Rename (): Error renaming " << path << " " << oldname << " to "
794 << newname);
795}
796
797void
798Names::Add(Ptr<Object> context, std::string name, Ptr<Object> object)
799{
800 NS_LOG_FUNCTION(context << name << object);
801 bool result = NamesPriv::Get()->Add(context, name, object);
802 NS_ABORT_MSG_UNLESS(result,
803 "Names::Add(): Error adding name " << name << " under context "
804 << &context);
805}
806
807void
808Names::Rename(Ptr<Object> context, std::string oldname, std::string newname)
809{
810 NS_LOG_FUNCTION(context << oldname << newname);
811 bool result = NamesPriv::Get()->Rename(context, oldname, newname);
812 NS_ABORT_MSG_UNLESS(result,
813 "Names::Rename (): Error renaming " << oldname << " to " << newname
814 << " under context " << &context);
815}
816
817std::string
819{
820 NS_LOG_FUNCTION(object);
821 return NamesPriv::Get()->FindName(object);
822}
823
824std::string
826{
827 NS_LOG_FUNCTION(object);
828 return NamesPriv::Get()->FindPath(object);
829}
830
831void
833{
835 return NamesPriv::Get()->Clear();
836}
837
839Names::FindInternal(std::string name)
840{
841 NS_LOG_FUNCTION(name);
842 return NamesPriv::Get()->Find(name);
843}
844
846Names::FindInternal(std::string path, std::string name)
847{
848 NS_LOG_FUNCTION(path << name);
849 return NamesPriv::Get()->Find(path, name);
850}
851
853Names::FindInternal(Ptr<Object> context, std::string name)
854{
855 NS_LOG_FUNCTION(context << name);
856 return NamesPriv::Get()->Find(context, name);
857}
858
859} // namespace ns3
NS_ABORT_x macro definitions.
NS_ASSERT() and NS_ASSERT_MSG() macro definitions.
Node in the naming tree.
Definition names.cc:33
NameNode * m_parent
The parent NameNode.
Definition names.cc:63
~NameNode()
Destructor.
Definition names.cc:106
NameNode()
Default constructor.
Definition names.cc:73
Ptr< Object > m_object
The object corresponding to this NameNode.
Definition names.cc:67
std::map< std::string, NameNode * > m_nameMap
Children of this NameNode.
Definition names.cc:70
NameNode & operator=(const NameNode &rhs)
Assignment operator.
Definition names.cc:89
std::string m_name
The name of this NameNode.
Definition names.cc:65
static void Rename(std::string oldpath, std::string newname)
Rename a previously associated name.
Definition names.cc:772
static Ptr< Object > FindInternal(std::string path)
Non-templated internal version of Names::Find.
Definition names.cc:839
static void Add(std::string name, Ptr< Object > object)
Add the association between the string "name" and the Ptr<Object> obj.
Definition names.cc:764
static void Clear()
Clear the list of objects associated with names.
Definition names.cc:832
static std::string FindName(Ptr< Object > object)
Given a pointer to an object, look to see if that object has a name associated with it and,...
Definition names.cc:818
static std::string FindPath(Ptr< Object > object)
Given a pointer to an object, look to see if that object has a name associated with it and return the...
Definition names.cc:825
The singleton root Names object.
Definition names.cc:116
bool Add(std::string name, Ptr< Object > object)
Internal implementation for Names::Add(std::string,Ptr<Object>)
Definition names.cc:310
NameNode m_root
The root NameNode.
Definition names.cc:265
bool IsDuplicateName(NameNode *node, std::string name)
Check if a name already exists as a child of a NameNode.
Definition names.cc:746
std::string FindPath(Ptr< Object > object)
Internal implementation of Names::FindPath()
Definition names.cc:560
bool Rename(std::string oldpath, std::string newname)
Internal implementation for Names::Rename(std::string,std::string)
Definition names.cc:419
std::string FindName(Ptr< Object > object)
Internal implementation for Names::FindName()
Definition names.cc:542
~NamesPriv() override
Destructor.
Definition names.cc:280
NameNode * IsNamed(Ptr< Object > object)
Check if an object has a name.
Definition names.cc:728
std::map< Ptr< Object >, NameNode * > m_objectMap
Map from object pointers to their NameNodes.
Definition names.cc:268
NamesPriv()
Constructor.
Definition names.cc:271
Ptr< Object > Find(std::string path)
Internal implementation for ns3::Names::Find(std::string)
Definition names.cc:587
void Clear()
Internal implementation for Names::Clear()
Definition names.cc:288
Smart pointer class similar to boost::intrusive_ptr.
A template singleton.
Definition singleton.h:57
static NamesPriv * Get()
Definition singleton.h:96
#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:75
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
Definition abort.h:133
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:271
#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 ",...
Debug message logging.
Declaration of class ns3::Names.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ns3::Object class declaration, which is the root of the Object hierarchy and Aggregation.
ns3::Singleton declaration and template implementation.