librnr  1.14.5
RoadNarrows Robotics Common Library 1
example_assoc.c
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: RoadNarrows Robotics Common Library 1
4 //
5 // File: example_assoc.c
6 //
7 /*! \file
8  *
9  * $LastChangedDate: 2010-03-24 10:19:36 -0600 (Wed, 24 Mar 2010) $
10  * $Rev: 307 $
11  *
12  * \brief Example of a librnr simple associative map operations.
13  *
14  * \author Robin Knight (robin.knight@roadnarrows.com)
15  *
16  * \pkgcopyright{2007-2018,RoadNarrows LLC.,http://www.roadnarrows.com}
17  */
18 // Permission is hereby granted, without written agreement and without
19 // license or royalty fees, to use, copy, modify, and distribute this
20 // software and its documentation for any purpose, provided that
21 // (1) The above copyright notice and the following two paragraphs
22 // appear in all copies of the source code and (2) redistributions
23 // including binaries reproduces these notices in the supporting
24 // documentation. Substantial modifications to this software may be
25 // copyrighted by their authors and need not follow the licensing terms
26 // described here, provided that the new terms are clearly indicated in
27 // all files where they apply.
28 //
29 // IN NO EVENT SHALL THE AUTHOR, ROADNARROWS LLC, OR ANY MEMBERS/EMPLOYEES
30 // OF ROADNARROW LLC OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY
31 // PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
32 // DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
33 // EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF
34 // THE POSSIBILITY OF SUCH DAMAGE.
35 //
36 // THE AUTHOR AND ROADNARROWS LLC SPECIFICALLY DISCLAIM ANY WARRANTIES,
37 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
38 // FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
39 // "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
40 // PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
41 //
42 ////////////////////////////////////////////////////////////////////////////////
43 
44 
45 #include <stdio.h>
46 #include <string.h>
47 
48 #include "rnr/rnrconfig.h"
49 #include "rnr/new.h"
50 
51 
52 /*!
53  * \brief Major and minor solar body ids (partial, of course).
54  */
55 typedef enum
56 {
57  unknown,
58 
59  Sun,
60  Mercury,
61  Venus,
62  Earth, Moon,
63  Mars, Phobos, Deimos,
64  Ceres,
65  Jupiter, Io, Europa, Ganymede, Callisto,
66  Saturn, Titan,
67  Uranus, Titania,
68  Neptune, Triton,
69  Pluto, Charon,
70  Eris,
71 
72  NumBodies
73 } BodyId_T;
74 
75 /*!
76  * \brief Some solar body facts.
77  */
78 typedef struct
79 {
80  const char *m_sName; ///< name of body
81  double m_fDiam; ///< diameter of body (km)
82  double m_fOrbitalAvgDist; ///< average orbital distance (km)
83  double m_fOribtalPeriod; ///< orbital revolution period (days)
84  BodyId_T m_eOrbits; ///< body this body orbits around
85 } Factoids_T;
86 
87 //
88 // Define planet id <--> planet facts associative map
89 //
90 #define AMAP_NAME Planet ///< associate map namespace
91 #define AMAP_XTYPE BodyId_T ///< x data type
92 #define AMAP_YTYPE Factoids_T* ///< y data type
93 #include "rnr/assoc.h" ///< make the magic
94 
95 /*!
96  * \brief Solar body name-id pairs (partial).
97  */
99 {
100  {"unknown", unknown}, // default
101  {"Sun", Sun},
102  {"Mercury", Mercury},
103  {"Venus", Venus},
104  {"Earth", Earth},
105  {"Moon", Moon},
106  {"Mars", Mars},
107  {"Phobos", Phobos},
108  {"Deimos", Deimos},
109  {"Jupiter", Jupiter},
110  {"Io", Io},
111  {"Europa", Europa},
112  {"Ganymede", Ganymede},
113  {"Callisto", Callisto},
114  {"Saturn", Saturn},
115  {"Uranus", Uranus},
116  {"Neptune", Neptune},
117  {"Ceres", Ceres},
118  {"Pluto", Pluto}
119 };
120 
121 /*!
122  * \brief the solar body factoids
123  */
124 AssocMapPlanetPoint_T SolarBodyFacts[NumBodies];
125 
126 size_t BodyCount = 0; ///< number of bodies in facts table above.
127 
128 /*!
129  * \brief Add a new body to our db, normalizing units
130  *
131  * \param eThisBodyId Solar body id.
132  * \param diam Body diameter.
133  * \param units_diam Diameter units.
134  * \param dist Average orbital distance from the Sun.
135  * \param units_dist Distance units.
136  * \param period Average orbital period about parent body.
137  * \param units_period Period units.
138  * \param eOrbitsId Parent body.
139  */
140 static void AddNewBody(BodyId_T eThisBodyId,
141  double diam, char *units_diam,
142  double dist, char *units_dist,
143  double period, char *units_period,
144  BodyId_T eOrbitsId)
145 {
146  Factoids_T *pOid = NEW(Factoids_T);
147  const char *sName;
148 
149  sName = NvpVal2Name(SolarBodyNames,
150  arraysize(SolarBodyNames),
151  (int)eThisBodyId);
152 
153  if( sName == NULL )
154  {
155  fprintf(stderr, "Error: %d: unknown body type", eThisBodyId);
156  return;
157  }
158 
159  // normalize diameter to km units
160  if( !strcmp(units_diam, "miles") )
161  {
162  diam *= 1.609344;
163  }
164 
165  // normalize distance to km units
166  if( !strcmp(units_dist, "miles") )
167  {
168  dist *= 1.609344;
169  }
170 
171  // normalize period to days
172  if( !strcmp(units_period, "years") )
173  {
174  period *= 365.25;
175  }
176 
177  // initialize factoid
178  pOid->m_sName = sName;
179  pOid->m_fDiam = diam;
180  pOid->m_fOrbitalAvgDist = dist;
181  pOid->m_fOribtalPeriod = period;
182  pOid->m_eOrbits = eOrbitsId;
183 
184  // insert into table
185  SolarBodyFacts[BodyCount].x = eThisBodyId;
186  SolarBodyFacts[BodyCount].y = pOid;
187 
188  BodyCount++;
189 }
190 
191 /*!
192  * \brief Print solar body facts.
193  *
194  * \param pOid Pointer to facts.
195  */
197 {
198  printf("name: %s\n", pOid->m_sName);
199  printf("diameter: %e km\n", pOid->m_fDiam);
200  printf("distance: %e km\n", pOid->m_fOrbitalAvgDist);
201  printf("period: %f days\n", pOid->m_fOribtalPeriod);
202  printf("orbits: %s\n", NvpVal2Name(SolarBodyNames,
203  arraysize(SolarBodyNames),
204  (int)pOid->m_eOrbits));
205 }
206 
207 /*!
208  * \brief X comparator callback.
209  *
210  * \param x1 Solar body id x1.
211  * \param x2 Solar body id x2.
212  *
213  * \returns \h_lt 0, 0, or \h_gt 0 if body x1 is less than, equal to, or greater
214  * than x2, respectively.
215  */
216 int CmpIds(const BodyId_T x1, const BodyId_T x2)
217 {
218  return (int)(x1 - x2);
219 }
220 
221 /*!
222  * \brief Y comparator callback.
223  *
224  * \param y1 Solar body factoids y1.
225  * \param y2 Solar body factoids y2.
226  *
227  * \returns \h_lt 0, 0, or \h_gt 0 if y1 is less than, equal to, or greater
228  * than y2, respectively.
229  */
230 int CmpOids(const Factoids_T *y1, const Factoids_T *y2)
231 {
232  return strcmp(y1->m_sName, y2->m_sName);
233 }
234 
235 /*!
236  * \brief Example main.
237  *
238  * \param argc Command-line argument count.
239  * \param argv Command-line argument list.
240  *
241  * \par Exit Status:
242  * Program exits with 0 success, \h_gt 0 on failure.
243  */
244 int main(int argc, char *argv[])
245 {
246  AssocMapPlanetMapper_T map; // associative x<-->y mapper
247  AssocMapPlanetPoint_T dft = {unknown, NULL}; // default "body"
248  Factoids_T *pOid; // working factoid
249  Factoids_T findoid; // search factoid
250 
251  // add some factioids
252  AddNewBody(Mercury, 4878.0, "km", 46.0E6, "km", 0.24, "years", Sun);
253  AddNewBody(Moon, 3476.0, "km", 384400.0, "km", 27.322, "days", Earth);
254  AddNewBody(Deimos, 8.0, "km", 23460.0, "km", 1.263, "days", Mars);
255  AddNewBody(Phobos, 28.0, "km", 9270.0, "km", 0.319, "days", Mars);
256  AddNewBody(Callisto, 4800.0, "km", 1883000.0, "km", 16.689, "days", Jupiter);
257  AddNewBody(Europa, 3126.0, "km", 670900.0, "km", 3.551, "days", Jupiter);
258  AddNewBody(Jupiter, 88736.0, "miles", 817.0E6, "km", 12.0, "years", Sun);
259  AddNewBody(Earth, 7926.0, "miles", 91.0E6, "miles", 1.0, "years", Sun);
260 
261  // initialize mapper
262  map.m_tblAssocMap = SolarBodyFacts;
263  map.m_tblSize = BodyCount;
264  map.m_opXCmp = CmpIds;
265  map.m_opYCmp = CmpOids;
266  map.m_pMapDft = &dft;
267 
268  //
269  // print some data
270  //
271 
272  if( (pOid = AssocMapPlanetXtoY(&map, Moon)) != NULL )
273  {
274  PrintBody(pOid);
275  printf("\n");
276  }
277  if( (pOid = AssocMapPlanetXtoY(&map, Mercury)) != NULL )
278  {
279  PrintBody(pOid);
280  printf("\n");
281  }
282  if( (pOid = AssocMapPlanetXtoY(&map, Earth)) != NULL )
283  {
284  PrintBody(pOid);
285  printf("\n");
286  }
287  if( (pOid = AssocMapPlanetXtoY(&map, Callisto)) != NULL )
288  {
289  PrintBody(pOid);
290  printf("\n");
291  }
292  if( (pOid = AssocMapPlanetXtoY(&map, Eris)) != NULL ) // negative
293  {
294  PrintBody(pOid);
295  printf("\n");
296  }
297 
298  // what was ceres' id? negative
299  findoid.m_sName = "Ceres"; // note: only searches on name in this example
300  printf("ceres id: %u\n", AssocMapPlanetYtoX(&map, &findoid));
301 
302  // an Jupiter's id?
303  findoid.m_sName = "Jupiter";
304  printf("jupiter id: %u\n", AssocMapPlanetYtoX(&map, &findoid));
305 
306  return 0;
307 }
const char * NvpVal2Name(Nvp_T tbl[], size_t nTblEntries, int iVal)
Get the name associated with the value.
Definition: assoc.c:94
Nvp_T SolarBodyNames[]
Solar body name-id pairs (partial).
Definition: example_assoc.c:98
double m_fDiam
diameter of body (km)
Definition: example_assoc.c:81
BodyId_T m_eOrbits
body this body orbits around
Definition: example_assoc.c:84
#define NULL
null pointer
Definition: rnrconfig.h:199
Memory allocation and deallocation declarations.
Definition: assoc.h:151
#define arraysize(array)
array size, i.e. number of array entries
Definition: rnrconfig.h:259
int CmpIds(const BodyId_T x1, const BodyId_T x2)
X comparator callback.
int main(int argc, char *argv[])
Example main.
#define NEW(T)
Allocate new type.
Definition: new.h:49
size_t BodyCount
number of bodies in facts table above.
void PrintBody(Factoids_T *pOid)
Print solar body facts.
RoadNarrows Robotics common configuration file.
int CmpOids(const Factoids_T *y1, const Factoids_T *y2)
Y comparator callback.
const char * m_sName
name of body
Definition: example_assoc.c:80
AssocMapPlanetPoint_T SolarBodyFacts[NumBodies]
the solar body factoids
double m_fOrbitalAvgDist
average orbital distance (km)
Definition: example_assoc.c:82
Some solar body facts.
Definition: example_assoc.c:78
static void AddNewBody(BodyId_T eThisBodyId, double diam, char *units_diam, double dist, char *units_dist, double period, char *units_period, BodyId_T eOrbitsId)
Add a new body to our db, normalizing units.
double m_fOribtalPeriod
orbital revolution period (days)
Definition: example_assoc.c:83
BodyId_T
Major and minor solar body ids (partial, of course).
Definition: example_assoc.c:55