public bool Equals(OptionalStructList <T> other) => this.values.ListEquals(other.values) &&
 this.flags.ListEquals(other.flags);
        /// <summary>
        /// Initializes a new instance of the <see cref="ImmutableGpxWaypointTable"/> class.
        /// </summary>
        /// <param name="waypoints">
        /// The <see cref="GpxWaypoint"/> instances to store.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// Thrown when <paramref name="waypoints"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// Thrown when an element of <paramref name="waypoints"/> is <see langword="null" />
        /// </exception>
        public ImmutableGpxWaypointTable(IEnumerable <GpxWaypoint> waypoints)
        {
            switch (waypoints)
            {
            case null:
                throw new ArgumentNullException(nameof(waypoints));

            case ImmutableGpxWaypointTable otherTable:
                this.longitudes         = otherTable.longitudes;
                this.latitudes          = otherTable.latitudes;
                this.elevationsInMeters = otherTable.elevationsInMeters;
                this.timestampsUtc      = otherTable.timestampsUtc;
                this.names                          = otherTable.names;
                this.descriptions                   = otherTable.descriptions;
                this.symbolTexts                    = otherTable.symbolTexts;
                this.magneticVariations             = otherTable.magneticVariations;
                this.geoidHeights                   = otherTable.geoidHeights;
                this.comments                       = otherTable.comments;
                this.sources                        = otherTable.sources;
                this.webLinkLists                   = otherTable.webLinkLists;
                this.classifications                = otherTable.classifications;
                this.fixKinds                       = otherTable.fixKinds;
                this.numbersOfSatellites            = otherTable.numbersOfSatellites;
                this.horizontalDilutionsOfPrecision = otherTable.horizontalDilutionsOfPrecision;
                this.verticalDilutionsOfPrecision   = otherTable.verticalDilutionsOfPrecision;
                this.positionDilutionsOfPrecision   = otherTable.positionDilutionsOfPrecision;
                this.secondsSinceLastDgpsUpdates    = otherTable.secondsSinceLastDgpsUpdates;
                this.dgpsStationIds                 = otherTable.dgpsStationIds;
                this.allExtensions                  = otherTable.allExtensions;
                this.Count                          = otherTable.Count;
                return;
            }

            int                cnt                                  = 0;
            var                longitudes                           = new List <GpxLongitude>();
            var                latitudes                            = new List <GpxLatitude>();
            List <double?>     elevationsInMeters                   = null;
            List <DateTime?>   timestampsUtc                        = null;
            List <string>      names                                = null;
            List <string>      descriptions                         = null;
            List <string>      symbolTexts                          = null;
            List <GpxDegrees?> magneticVariations                   = null;
            List <double?>     geoidHeights                         = null;
            List <string>      comments                             = null;
            List <string>      sources                              = null;
            List <ImmutableArray <GpxWebLink> > webLinkLists        = null;
            List <string>            classifications                = null;
            List <int?>              fixKinds                       = null;
            List <uint?>             numbersOfSatellites            = null;
            List <double?>           horizontalDilutionsOfPrecision = null;
            List <double?>           verticalDilutionsOfPrecision   = null;
            List <double?>           positionDilutionsOfPrecision   = null;
            List <double?>           secondsSinceLastDgpsUpdates    = null;
            List <GpxDgpsStationId?> dgpsStationIds                 = null;
            List <object>            allExtensions                  = null;

            foreach (var waypoint in waypoints)
            {
                if (waypoint is null)
                {
                    throw new ArgumentException("No null waypoints are allowed", nameof(waypoints));
                }

                longitudes.Add(waypoint.Longitude);
                latitudes.Add(waypoint.Latitude);
                Add(ref elevationsInMeters, waypoint.ElevationInMeters, cnt);
                Add(ref timestampsUtc, waypoint.TimestampUtc, cnt);
                Add(ref names, waypoint.Name, cnt);
                Add(ref descriptions, waypoint.Description, cnt);
                Add(ref symbolTexts, waypoint.SymbolText, cnt);
                Add(ref magneticVariations, waypoint.MagneticVariation, cnt);
                Add(ref geoidHeights, waypoint.GeoidHeight, cnt);
                Add(ref comments, waypoint.Comment, cnt);
                Add(ref sources, waypoint.Source, cnt);
                Add(ref webLinkLists, waypoint.Links, cnt);
                Add(ref classifications, waypoint.Classification, cnt);
                Add(ref fixKinds, (int?)waypoint.FixKind, cnt);
                Add(ref numbersOfSatellites, waypoint.NumberOfSatellites, cnt);
                Add(ref horizontalDilutionsOfPrecision, waypoint.HorizontalDilutionOfPrecision, cnt);
                Add(ref verticalDilutionsOfPrecision, waypoint.VerticalDilutionOfPrecision, cnt);
                Add(ref positionDilutionsOfPrecision, waypoint.PositionDilutionOfPrecision, cnt);
                Add(ref secondsSinceLastDgpsUpdates, waypoint.SecondsSinceLastDgpsUpdate, cnt);
                Add(ref dgpsStationIds, waypoint.DgpsStationId, cnt);
                Add(ref allExtensions, waypoint.Extensions, cnt);

                ++cnt;
            }

            this.longitudes         = longitudes.ToImmutableArray();
            this.latitudes          = latitudes.ToImmutableArray();
            this.elevationsInMeters = Optional(elevationsInMeters);
            this.timestampsUtc      = Optional(timestampsUtc);
            this.names                          = Optional(names);
            this.descriptions                   = Optional(descriptions);
            this.symbolTexts                    = Optional(symbolTexts);
            this.magneticVariations             = Optional(magneticVariations);
            this.geoidHeights                   = Optional(geoidHeights);
            this.comments                       = Optional(comments);
            this.sources                        = Optional(sources);
            this.webLinkLists                   = Optional(webLinkLists);
            this.classifications                = Optional(classifications);
            this.fixKinds                       = Optional(fixKinds);
            this.numbersOfSatellites            = Optional(numbersOfSatellites);
            this.horizontalDilutionsOfPrecision = Optional(horizontalDilutionsOfPrecision);
            this.verticalDilutionsOfPrecision   = Optional(verticalDilutionsOfPrecision);
            this.positionDilutionsOfPrecision   = Optional(positionDilutionsOfPrecision);
            this.secondsSinceLastDgpsUpdates    = Optional(secondsSinceLastDgpsUpdates);
            this.dgpsStationIds                 = Optional(dgpsStationIds);
            this.allExtensions                  = Optional(allExtensions);

            this.Count = cnt;
        }
 public bool Equals(OptionalStructList <T> other) => _values.ListEquals(other._values) &&
 _flags.ListEquals(other._flags);