Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tweak "enums" in both NITRO and SIX #486

Merged
merged 3 commits into from
Sep 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 10 additions & 19 deletions externals/nitro/modules/c++/nitf/include/nitf/BandInfo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,20 @@
*
*/

#ifndef __NITF_BANDINFO_HPP__
#define __NITF_BANDINFO_HPP__
#ifndef NITF_BandInfo_hpp_INCLUDED_
#define NITF_BandInfo_hpp_INCLUDED_
#pragma once

#include <string>
#include <map>

#include "nitf/BandInfo.h"
#include "nitf/System.hpp"
#include "nitf/LookupTable.hpp"
#include "nitf/Field.hpp"
#include "nitf/Object.hpp"
#include "nitf/Property.hpp"
#include "nitf/Enum.hpp"

/*!
* \file BandInfo.hpp
Expand All @@ -40,22 +42,11 @@

namespace nitf
{
template<typename T>
T from_string(const std::string&) noexcept(false);
NITF_ENUM(5, Representation, R, G, B, M, LU);
NITF_ENUM(2, Subcategory, I, Q);

enum class Representation
{
R, G, B, M, LU
};
std::string to_string(Representation) noexcept(false);
template<> Representation from_string(const std::string&) noexcept(false);
NITF_ENUM(3, TestTestTest, A, B, C);

enum class Subcategory
{
I, Q
};
std::string to_string(Subcategory) noexcept(false);
template<> Subcategory from_string(const std::string&) noexcept(false);

/*!
* \class BandInfo
Expand All @@ -78,7 +69,7 @@ DECLARE_CLASS(BandInfo)
BandInfo() noexcept(false);
~BandInfo() = default;

explicit BandInfo(const Representation&);
explicit BandInfo(Representation);

//! Get the representation
nitf::Field getRepresentation() const;
Expand All @@ -87,7 +78,7 @@ DECLARE_CLASS(BandInfo)
[&](const Representation& v) -> void { getRepresentation().set(to_string(v)); }
};

explicit BandInfo(const Subcategory&);
explicit BandInfo(Subcategory);

//! Get the subcategory
nitf::Field getSubcategory() const;
Expand Down Expand Up @@ -157,4 +148,4 @@ DECLARE_CLASS(BandInfo)
};

}
#endif
#endif // NITF_BandInfo_hpp_INCLUDED_
104 changes: 104 additions & 0 deletions externals/nitro/modules/c++/nitf/include/nitf/Enum.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/* =========================================================================
* This file is part of NITRO
* =========================================================================
*
* (C) Copyright 2021, Maxar Technologies, Inc.
*
* NITRO is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, If not,
* see <http://www.gnu.org/licenses/>.
*
*/

#ifndef NITF_Enum_hpp_INCLUDED_
#define NITF_Enum_hpp_INCLUDED_
#pragma once

#include <string>
#include <map>
#include <stdexcept>

namespace nitf
{
namespace details
{
template<typename TKey, typename TValue>
inline std::map<TValue, TKey> swap_key_value(const std::map<TKey, TValue>& map)
{
std::map<TValue, TKey> retval;
for (const auto& p : map)
{
retval[p.second] = p.first;
}
return retval;
}

template<typename TKey, typename TValue>
inline TValue index(const std::map<TKey, TValue>& map, const TKey& k) noexcept(false)
{
const auto it = map.find(k);
if (it == map.end())
{
throw std::invalid_argument("key not found in map.");
}
return it->second;
}

// You need to specialize string_to_enum() for each "enum class"
template<typename T> const std::map<std::string, T>& string_to_enum();
template<typename T>
inline const std::map<T, std::string>& enum_to_string()
{
static const auto retval = swap_key_value(string_to_enum<T>());
return retval;
}

template<typename T>
inline std::string to_string(T v) noexcept(false)
{
return index(enum_to_string<T>(), v);
}
template<typename T>
inline T from_string(const std::string& v) noexcept(false)
{
return index(string_to_enum<T>(), v);
}
}

#define NITF_ENUM_define_enum_(name, ...) enum class name { __VA_ARGS__ }

#define NITF_ENUM_map_entry_(name, n) { #n, name::n }
#define NITF_ENUM_map_entry_2_(name, n1, n2) NITF_ENUM_map_entry_(name, n1), NITF_ENUM_map_entry_(name, n2)
#define NITF_ENUM_map_entry_3_(name, n1, n2, n3) NITF_ENUM_map_entry_(name, n1), NITF_ENUM_map_entry_2_(name, n2, n3)
#define NITF_ENUM_map_entry_4_(name, n1, n2, n3, n4) NITF_ENUM_map_entry_(name, n1), NITF_ENUM_map_entry_3_(name, n2, n3, n4)
#define NITF_ENUM_map_entry_5_(name, n1, n2, n3, n4, n5) NITF_ENUM_map_entry_(name, n1), NITF_ENUM_map_entry_4_(name, n2, n3, n4, n5),

#define NITF_ENUM_define_string_to_enum_(name, ...) namespace details { \
template<> inline const std::map<std::string, name>& string_to_enum() { \
static const std::map<std::string, name> retval { __VA_ARGS__ }; return retval; } }

#define NITF_ENUM(n, name, ...) NITF_ENUM_define_enum_(name, __VA_ARGS__); \
NITF_ENUM_define_string_to_enum_(name, NITF_ENUM_map_entry_##n##_(name, __VA_ARGS__))

template<typename T>
inline std::string to_string(T v) noexcept(false)
{
return details::to_string(v);
}
template<typename T>
inline T from_string(const std::string& v) noexcept(false)
{
return details::from_string<T>(v);
}
}
#endif // NITF_Enum_hpp_INCLUDED_
63 changes: 2 additions & 61 deletions externals/nitro/modules/c++/nitf/source/BandInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ BandInfo::BandInfo() noexcept(false) : BandInfo(nitf_BandInfo_construct(&error))
setManaged(false);
}

BandInfo::BandInfo(const Representation& representation) : BandInfo()
BandInfo::BandInfo(Representation representation) : BandInfo()
{
this->representation = representation;
}
Expand All @@ -59,7 +59,7 @@ nitf::Field BandInfo::getRepresentation() const
return nitf::Field(getNativeOrThrow()->representation);
}

BandInfo::BandInfo(const Subcategory& subcategory) : BandInfo()
BandInfo::BandInfo(Subcategory subcategory) : BandInfo()
{
getSubcategory().set(to_string(subcategory));
}
Expand Down Expand Up @@ -190,62 +190,3 @@ void BandInfo::init(const Representation& representation_, // C4458: declaration
init(to_string(representation_), subcategory_, imageFilterCondition, imageFilterCode);
}

// operator[] doesn't work with a "const" map as it can also insert
template<typename TKey, typename TValue>
static TValue index(const std::map<TKey, TValue>& map, TKey k)
{
const auto it = map.find(k);
if (it == map.end())
{
throw std::invalid_argument("key not found in map.");
}
return it->second;
}

template<typename TKey, typename TValue>
static std::map<TValue, TKey> swap_key_value(const std::map<TKey, TValue>& map)
{
std::map<TValue, TKey> retval;
for (const auto& p : map)
{
retval[p.second] = p.first;
}
return retval;
}

// Don't bother with checking lower-case; nobody should be passing
// an "r" directly to this routine, should always be the result of R.to_string()
#define NITF_string_to_Represenation_map_entry(name) { #name, Representation::name }
static const std::map<std::string, Representation> string_to_Represenation
{
NITF_string_to_Represenation_map_entry(R),
NITF_string_to_Represenation_map_entry(G),
NITF_string_to_Represenation_map_entry(B),
NITF_string_to_Represenation_map_entry(M),
NITF_string_to_Represenation_map_entry(LU),
};
std::string nitf::to_string(Representation v)
{
static const auto to_string_map = swap_key_value(string_to_Represenation);
return index(to_string_map, v);
}
template<> nitf::Representation nitf::from_string(const std::string& v)
{
return index(string_to_Represenation, v);
}

#define NITF_string_to_Subcategory_map_entry(name) { #name, Subcategory::name }
static const std::map<std::string, Subcategory> string_to_Subcategory
{
NITF_string_to_Subcategory_map_entry(I),
NITF_string_to_Subcategory_map_entry(Q),
};
std::string nitf::to_string(Subcategory v)
{
static const auto to_string_map = swap_key_value(string_to_Subcategory);
return index(to_string_map, v);
}
template<> nitf::Subcategory nitf::from_string(const std::string& v)
{
return index(string_to_Subcategory, v);
}
Loading