text:
#include "unittest.h"
#include "OpcUaStackCore/Base/Utility.h"
#include "OpcUaStackCore/Base/ConfigXml.h"
#include "OpcUaStackCore/BuildInTypes/OpcUaIdentifier.h"
#include "OpcUaStackCore/BuildInTypes/BuildInTypes.h"
#include "OpcUaStackCore/BuildInTypes/XmlNumber.h"
#include "OpcUaStackCore/StandardDataTypes/Argument.h"
#include <boost/iostreams/stream.hpp>

using namespace OpcUaStackCore;

BOOST_AUTO_TEST_SUITE(XmlEncoderDecoder_)

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_)
{
	std::cout << "XmlEncoderDecoder_t" << std::endl;
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_Boolean)
{
	ConfigXml xml;
	boost::property_tree::ptree pt;
	OpcUaBoolean value1, value2;

	value1 = false;
	XmlNumber::xmlEncode(pt, value1);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	XmlNumber::xmlDecode(pt, value2);
	BOOST_REQUIRE(value2 == false);
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_Byte)
{
	ConfigXml xml;
	boost::property_tree::ptree pt;
	OpcUaByte value1, value2;

	value1 = 12;
	XmlNumber::xmlEncode(pt, value1);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	XmlNumber::xmlDecode(pt, value2);
	BOOST_REQUIRE(value2 == 12);
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_SByte)
{
	ConfigXml xml;
	boost::property_tree::ptree pt;
	OpcUaSByte value1, value2;

	value1 = -12;
	XmlNumber::xmlEncode(pt, value1);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	XmlNumber::xmlDecode(pt, value2);
	BOOST_REQUIRE(value2 == -12);
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_UInt16)
{
	ConfigXml xml;
	boost::property_tree::ptree pt;
	OpcUaUInt16 value1, value2;

	value1 = 123;
	XmlNumber::xmlEncode(pt, value1);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	XmlNumber::xmlDecode(pt, value2);
	BOOST_REQUIRE(value2 == 123);
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_Int16)
{
	ConfigXml xml;
	boost::property_tree::ptree pt;
	OpcUaInt16 value1, value2;

	value1 = -123;
	XmlNumber::xmlEncode(pt, value1);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	XmlNumber::xmlDecode(pt, value2);
	BOOST_REQUIRE(value2 == -123);
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_UInt32)
{
	ConfigXml xml;
	boost::property_tree::ptree pt;
	OpcUaUInt32 value1, value2;

	value1 = 1234;
	XmlNumber::xmlEncode(pt, value1);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	XmlNumber::xmlDecode(pt, value2);
	BOOST_REQUIRE(value2 == 1234);
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_Int32)
{
	ConfigXml xml;
	boost::property_tree::ptree pt;
	OpcUaInt32 value1, value2;

	value1 = -1234;
	XmlNumber::xmlEncode(pt, value1);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	XmlNumber::xmlDecode(pt, value2);
	BOOST_REQUIRE(value2 == -1234);
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_UInt64)
{
	ConfigXml xml;
	boost::property_tree::ptree pt;
	OpcUaUInt64 value1, value2;

	value1 = 12345;
	XmlNumber::xmlEncode(pt, value1);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	XmlNumber::xmlDecode(pt, value2);
	BOOST_REQUIRE(value2 == 12345);
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_Int64)
{
	ConfigXml xml;
	boost::property_tree::ptree pt;
	OpcUaInt64 value1, value2;

	value1 = -12345;
	XmlNumber::xmlEncode(pt, value1);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	XmlNumber::xmlDecode(pt, value2);
	BOOST_REQUIRE(value2 == -12345);
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_Float)
{
	ConfigXml xml;
	boost::property_tree::ptree pt;
	OpcUaFloat value1, value2;

	value1 = 12.34;
	XmlNumber::xmlEncode(pt, value1);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	XmlNumber::xmlDecode(pt, value2);
	BOOST_REQUIRE(value2 > 12.33 && value2 < 12.35);
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_Double)
{
	ConfigXml xml;
	boost::property_tree::ptree pt;
	OpcUaDouble value1, value2;

	value1 = 12.34;
	XmlNumber::xmlEncode(pt, value1);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	XmlNumber::xmlDecode(pt, value2);
	BOOST_REQUIRE(value2 > 12.33 && value2 < 12.35);
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaString)
{
	Xmlns xmlns;
	ConfigXml xml;
	boost::property_tree::ptree pt;
	OpcUaString value1, value2;

	value1.value("Dies ist ein String");
	value1.xmlEncode(pt, xmlns);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	value2.xmlDecode(pt, xmlns);
	BOOST_REQUIRE(value2.value() == std::string("Dies ist ein String"));
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaDataTime)
{
	boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time();

	Xmlns xmlns;
	ConfigXml xml;
	boost::property_tree::ptree pt;
	OpcUaDateTime value1, value2;

	value1.dateTime(now);
	value1.xmlEncode(pt, xmlns);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	value2.xmlDecode(pt, xmlns);
	BOOST_REQUIRE(value2.dateTime() == now);
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaGuid)
{
	Xmlns xmlns;
	ConfigXml xml;
	boost::property_tree::ptree pt;
	OpcUaGuid value1, value2;

	value1 = "12345678-9ABC-DEF0-1234-56789ABCDEF0";
	value1.xmlEncode(pt, xmlns);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	value2.xmlDecode(pt, xmlns);
	std::string str = value2;
	BOOST_REQUIRE(str == "12345678-9ABC-DEF0-1234-56789ABCDEF0");
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaByteString)
{
	std::string str = "Dies ist ein ByteString";
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaByteString value2;

	OpcUaByteString value1;
	value1.value(str);
	value1.xmlEncode(pt, xmlns);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	value2.xmlDecode(pt, xmlns);
	BOOST_REQUIRE(value2.toString() == str);
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaNodeId)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaNodeId value1, value2;

	value1.set("NodeName", 123);
	value1.xmlEncode(pt, xmlns);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	value2.xmlDecode(pt, xmlns);
	BOOST_REQUIRE(value2 == OpcUaNodeId("NodeName", 123));
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaExpandedNodeId)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaExpandedNodeId value1, value2;

	value1.fromString("svr=4711;ns=1;s=NodeName");
	value1.xmlEncode(pt, xmlns);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	value2.xmlDecode(pt, xmlns);
	BOOST_REQUIRE(value2.toString() == "svr=4711;ns=1;s=NodeName");
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_QualifiedName)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaQualifiedName value1, value2;

	value1.namespaceIndex(123);
	value1.name("Name");
	value1.xmlEncode(pt, xmlns);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	value2.xmlDecode(pt, xmlns);
	BOOST_REQUIRE(value2.namespaceIndex() == 123);
	BOOST_REQUIRE(value2.name().toStdString() == "Name");
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_LocalizedText)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaLocalizedText value1, value2;

	value1.locale("de");
	value1.text("Text");
	value1.xmlEncode(pt, xmlns);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	value2.xmlDecode(pt, xmlns);
	BOOST_REQUIRE(value2.locale().toStdString() == "de");
	BOOST_REQUIRE(value2.text().toStdString() == "Text");
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_ExtensionObject)
{
	OpcUaExtensionObject eo;
	eo.registerFactoryElement<Argument>(OpcUaId_Argument_Encoding_DefaultBinary);
	eo.registerFactoryElement<Argument>(OpcUaId_Argument_Encoding_DefaultXml);

	Argument::SPtr argument1, argument2;
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaExtensionObject value1, value2;

	argument1 = value1.parameter<Argument>(OpcUaId_Argument_Encoding_DefaultBinary);
	argument1->name().value("ArgumentName");
	argument1->dataType().set("NodeName", 23);
	argument1->arrayDimensions()->resize(3);
	argument1->arrayDimensions()->set(0, 123);
	argument1->arrayDimensions()->set(1, 456);
	argument1->arrayDimensions()->set(2, 789);
	argument1->description().set("de", "Description");
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	BOOST_REQUIRE(value2.typeId().nodeId<OpcUaUInt32>() == OpcUaId_Argument_Encoding_DefaultBinary);
	argument2 = value2.parameter<Argument>();
	BOOST_REQUIRE(argument2->name().toStdString() == "ArgumentName");
	BOOST_REQUIRE(argument2->dataType() == OpcUaNodeId("NodeName", 23));
	BOOST_REQUIRE(argument2->description() == OpcUaLocalizedText("de", "Description"));
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_OpcUaBoolean)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	value1.set((OpcUaBoolean)true);
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	BOOST_REQUIRE(value2.get<OpcUaBoolean>() == true);
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_SByte)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	value1.set((OpcUaSByte)-12);
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	BOOST_REQUIRE(value2.get<OpcUaSByte>() == -12);
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_Byte)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	value1.set((OpcUaByte)12);
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	BOOST_REQUIRE(value2.get<OpcUaByte>() == 12);
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_Int16)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	value1.set((OpcUaInt16)-123);
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	BOOST_REQUIRE(value2.get<OpcUaInt16>() == -123);
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_UInt16)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	value1.set((OpcUaUInt16)1234);
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	BOOST_REQUIRE(value2.get<OpcUaUInt16>() == 1234);
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_Int32)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	value1.set((OpcUaInt32)-1234);
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	BOOST_REQUIRE(value2.get<OpcUaInt32>() == -1234);
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_UInt32)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	value1.set((OpcUaUInt32)12345);
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	BOOST_REQUIRE(value2.get<OpcUaUInt32>() == 12345);
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_Int64)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	value1.set((OpcUaInt64)-12345);
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	BOOST_REQUIRE(value2.get<OpcUaInt64>() == -12345);
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_UInt64)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	value1.set((OpcUaUInt64)123456);
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	BOOST_REQUIRE(value2.get<OpcUaUInt64>() == 123456);
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_Float)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	value1.set((OpcUaFloat)1.2);
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	OpcUaFloat v = value2.get<OpcUaFloat>();
	BOOST_REQUIRE(v > 1.1 && v < 1.3);
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_Double)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	value1.set((OpcUaDouble)1.2);
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	OpcUaDouble v = value2.get<OpcUaDouble>();
	BOOST_REQUIRE(v > 1.1 && v < 1.3);
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_DateTime)
{
	boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time();

	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	value1.set(OpcUaDateTime(now));
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	BOOST_REQUIRE(value2.get<OpcUaDateTime>().dateTime() == now);
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_ByteString)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	OpcUaByteString::SPtr byteString1 = constructSPtr<OpcUaByteString>();
	byteString1->value("Das ist ein ByteString xxxx");
	value1.variant(byteString1);
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	OpcUaByteString::SPtr byteString2 = value2.variantSPtr<OpcUaByteString>();
	BOOST_REQUIRE(byteString2->toString() == "Das ist ein ByteString xxxx");
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_Guid)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	OpcUaGuid::SPtr guid1 = constructSPtr<OpcUaGuid>();
	*guid1 = "12345678-9ABC-DEF0-1234-56789ABCDEF0";
	value1.variant(guid1);
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	OpcUaGuid::SPtr guid2 = value2.variantSPtr<OpcUaGuid>();
	std::string str = *guid2;
	BOOST_REQUIRE(str == "12345678-9ABC-DEF0-1234-56789ABCDEF0");
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_NodeId)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	OpcUaNodeId::SPtr nodeId1 = constructSPtr<OpcUaNodeId>();
	nodeId1->set(4711,4712);
	value1.variant(nodeId1);
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	OpcUaNodeId::SPtr nodeId2 = value2.variantSPtr<OpcUaNodeId>();
	BOOST_REQUIRE(*nodeId2 == OpcUaNodeId(4711,4712));
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_ExpandedNodeId)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	OpcUaExpandedNodeId::SPtr expandedNodeId1 = constructSPtr<OpcUaExpandedNodeId>();
	expandedNodeId1->set(4711, 4712);
	expandedNodeId1->serverIndex(4713);
	value1.variant(expandedNodeId1);
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	OpcUaExpandedNodeId::SPtr expandedNodeId2 = value2.variantSPtr<OpcUaExpandedNodeId>();
	BOOST_REQUIRE(expandedNodeId2->namespaceIndex() == 4712);
	BOOST_REQUIRE(expandedNodeId2->serverIndex() == 4713);
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_QualifiedName)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	OpcUaQualifiedName::SPtr qualifiedName1 = constructSPtr<OpcUaQualifiedName>();
	qualifiedName1->set("Name", 4712);
	value1.variant(qualifiedName1);
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	OpcUaQualifiedName::SPtr qualifiedName2 = value2.variantSPtr<OpcUaQualifiedName>();
	BOOST_REQUIRE(*qualifiedName2 == OpcUaQualifiedName("Name", 4712));
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_LocalizedText)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	OpcUaLocalizedText::SPtr localizedText1 = constructSPtr<OpcUaLocalizedText>();
	localizedText1->set("de", "Name");
	value1.variant(localizedText1);
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	OpcUaLocalizedText::SPtr localizedText2 = value2.variantSPtr<OpcUaLocalizedText>();
	BOOST_REQUIRE(*localizedText2 == OpcUaLocalizedText("de", "Name"));
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_ExtensionObject)
{
	OpcUaExtensionObject eo;
	eo.registerFactoryElement<Argument>(OpcUaId_Argument_Encoding_DefaultBinary);
	eo.registerFactoryElement<Argument>(OpcUaId_Argument_Encoding_DefaultXml);

	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;
	Argument::SPtr argument1, argument2;

	OpcUaExtensionObject::SPtr extentionObject1 = constructSPtr<OpcUaExtensionObject>();
	argument1 = extentionObject1->parameter<Argument>(OpcUaId_Argument_Encoding_DefaultBinary);
	argument1->name().value("ArgumentName");
	argument1->dataType().set("NodeName", 23);
	argument1->arrayDimensions()->resize(3);
	argument1->arrayDimensions()->set(0, 123);
	argument1->arrayDimensions()->set(1, 456);
	argument1->arrayDimensions()->set(2, 789);
	argument1->description().set("de", "Description");
	value1.variant(extentionObject1);
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	OpcUaExtensionObject::SPtr extentionObject2 = value2.variantSPtr<OpcUaExtensionObject>();
	BOOST_REQUIRE(extentionObject2->typeId().nodeId<OpcUaUInt32>() == OpcUaId_Argument_Encoding_DefaultBinary);
	argument2 = extentionObject2->parameter<Argument>();
	BOOST_REQUIRE(argument2->name().toStdString() == "ArgumentName");
	BOOST_REQUIRE(argument2->dataType() == OpcUaNodeId("NodeName", 23));
	BOOST_REQUIRE(argument2->description() == OpcUaLocalizedText("de", "Description"));
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_DataValue)
{
	boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time();

	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaDataValue value1, value2;

	value1.variant()->set((OpcUaInt32)12345);
	value1.statusCode(BadNoData);
	value1.sourceTimestamp(OpcUaDateTime(now));
	value1.serverTimestamp(OpcUaDateTime(now));
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;
	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	BOOST_REQUIRE(value2.variant()->get<OpcUaInt32>() == 12345);
	BOOST_REQUIRE(value2.serverTimestamp().dateTime() == now);
	BOOST_REQUIRE(value2.sourceTimestamp().dateTime() == now);
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_Array_OpcUaBoolean)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	for (uint32_t idx=0; idx<10; idx++) {
		value1.pushBack((OpcUaBoolean)true);
	}
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	for (uint32_t idx=0; idx<10; idx++) {
		BOOST_REQUIRE(value2.get<OpcUaBoolean>(idx) == true);
	}
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_Array_SByte)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	for (uint32_t idx=0; idx<10; idx++) {
		value1.pushBack((OpcUaSByte)-idx);
	}
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	for (uint32_t idx=0; idx<10; idx++) {
		BOOST_REQUIRE(value2.get<OpcUaSByte>(idx) == -idx);
	}
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_Array_Byte)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	for (uint32_t idx=0; idx<10; idx++) {
		value1.pushBack((OpcUaByte)idx);
	}
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	for (uint32_t idx=0; idx<10; idx++) {
		BOOST_REQUIRE(value2.get<OpcUaByte>(idx) == idx);
	}
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_Array_Int16)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	for (uint32_t idx=0; idx<10; idx++) {
		value1.pushBack((OpcUaInt16)-idx);
	}
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	for (uint32_t idx=0; idx<10; idx++) {
		BOOST_REQUIRE(value2.get<OpcUaInt16	>(idx) == -idx);
	}
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_Array_UInt16)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	for (uint32_t idx=0; idx<10; idx++) {
		value1.pushBack((OpcUaUInt16)idx);
	}
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	for (uint32_t idx=0; idx<10; idx++) {
		BOOST_REQUIRE(value2.get<OpcUaUInt16>(idx) == idx);
	}
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_Array_Int32)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	for (uint32_t idx=0; idx<10; idx++) {
		value1.pushBack((OpcUaInt32)-idx);
	}
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	for (uint32_t idx=0; idx<10; idx++) {
		BOOST_REQUIRE(value2.get<OpcUaInt32>(idx) == -idx);
	}
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_Array_UInt32)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	for (uint32_t idx=0; idx<10; idx++) {
		value1.pushBack((OpcUaUInt32)idx);
	}
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	for (uint32_t idx=0; idx<10; idx++) {
		BOOST_REQUIRE(value2.get<OpcUaUInt32>(idx) == idx);
	}
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_Array_Int64)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	for (uint32_t idx=0; idx<10; idx++) {
		value1.pushBack((OpcUaInt64)-idx);
	}
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	for (uint32_t idx=0; idx<10; idx++) {
		BOOST_REQUIRE(value2.get<OpcUaInt64>(idx) == -idx);
	}
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_Array_UInt64)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	for (uint32_t idx=0; idx<10; idx++) {
		value1.pushBack((OpcUaUInt64)idx);
	}
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	for (uint32_t idx=0; idx<10; idx++) {
		BOOST_REQUIRE(value2.get<OpcUaUInt64>(idx) == idx);
	}
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_Array_Float)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	for (uint32_t idx=0; idx<10; idx++) {
		value1.pushBack((OpcUaFloat)idx);
	}
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	for (uint32_t idx=0; idx<10; idx++) {
		BOOST_REQUIRE(value2.get<OpcUaFloat>(idx) == idx);
	}
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_Array_Double)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	for (uint32_t idx=0; idx<10; idx++) {
		value1.pushBack((OpcUaDouble)idx);
	}
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	for (uint32_t idx=0; idx<10; idx++) {
		BOOST_REQUIRE(value2.get<OpcUaDouble>(idx) == idx);
	}
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_Array_DateTime)
{
	boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time();

	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	for (uint32_t idx=0; idx<10; idx++) {
		value1.pushBack(OpcUaDateTime(now));
	}
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	for (uint32_t idx=0; idx<10; idx++) {
		BOOST_REQUIRE(value2.get<OpcUaDateTime>(idx) == now);
	}
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_Array_String)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	for (uint32_t idx=0; idx<10; idx++) {
		OpcUaString::SPtr string = constructSPtr<OpcUaString>();
		string->value("Das ist ein ByteString");
		value1.pushBack(string);
	}
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	for (uint32_t idx=0; idx<10; idx++) {
		BOOST_REQUIRE(value2.getSPtr<OpcUaString>(idx)->value() == "Das ist ein ByteString");
	}
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_Array_ByteString)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	for (uint32_t idx=0; idx<10; idx++) {
		OpcUaByteString::SPtr byteString = constructSPtr<OpcUaByteString>();
		byteString->value("Das ist ein ByteString");
		value1.pushBack(byteString);
	}
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	for (uint32_t idx=0; idx<10; idx++) {
		BOOST_REQUIRE(value2.getSPtr<OpcUaByteString>(idx)->toString() == "Das ist ein ByteString");
	}
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_Array_Guid)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	for (uint32_t idx=0; idx<10; idx++) {
		OpcUaGuid::SPtr guid = constructSPtr<OpcUaGuid>();
		*guid = "12345678-9ABC-DEF0-1234-56789ABCDEF0";
		value1.pushBack(guid);
	}
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	for (uint32_t idx=0; idx<10; idx++) {
		BOOST_REQUIRE(value2.getSPtr<OpcUaGuid>(idx)->value() == "12345678-9ABC-DEF0-1234-56789ABCDEF0");
	}
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_Array_NodeId)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	for (uint32_t idx=0; idx<10; idx++) {
		OpcUaNodeId::SPtr nodeId = constructSPtr<OpcUaNodeId>();
		nodeId->set(4711, 4712);
		value1.pushBack(nodeId);
	}
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	for (uint32_t idx=0; idx<10; idx++) {
		BOOST_REQUIRE(*value2.getSPtr<OpcUaNodeId>(idx) == OpcUaNodeId(4711, 4712));
	}
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_Array_ExpandedNodeId)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	for (uint32_t idx=0; idx<10; idx++) {
		OpcUaExpandedNodeId::SPtr expandedNodeId = constructSPtr<OpcUaExpandedNodeId>();
		expandedNodeId->set(4711, 4712);
		expandedNodeId->serverIndex(4713);
		value1.pushBack(expandedNodeId);
	}
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	for (uint32_t idx=0; idx<10; idx++) {
		OpcUaExpandedNodeId::SPtr expandedNodeId = constructSPtr<OpcUaExpandedNodeId>();
		expandedNodeId->set(4711, 4712);
		expandedNodeId->serverIndex(4713);

		BOOST_REQUIRE(*value2.getSPtr<OpcUaExpandedNodeId>(idx) == *expandedNodeId);
	}
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_Array_QualifiedName)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	for (uint32_t idx=0; idx<10; idx++) {
		OpcUaQualifiedName::SPtr qualifiedName = constructSPtr<OpcUaQualifiedName>();
		qualifiedName->set("String", 4711);
		value1.pushBack(qualifiedName);
	}
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	for (uint32_t idx=0; idx<10; idx++) {
		BOOST_REQUIRE(*value2.getSPtr<OpcUaQualifiedName>(idx) == OpcUaQualifiedName("String", 4711));
	}
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_Array_LocalizedText)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	for (uint32_t idx=0; idx<10; idx++) {
		OpcUaLocalizedText::SPtr localizedText = constructSPtr<OpcUaLocalizedText>();
		localizedText->set("de", "TextString");
		value1.pushBack(localizedText);
	}
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	for (uint32_t idx=0; idx<10; idx++) {
		BOOST_REQUIRE(*value2.getSPtr<OpcUaLocalizedText>(idx) == OpcUaLocalizedText("de", "TextString"));
	}
}

BOOST_AUTO_TEST_CASE(XmlEncoderDecoder_OpcUaVariant_Array_ExtensionObject)
{
	boost::property_tree::ptree pt;
	Xmlns xmlns;
	ConfigXml xml;
	OpcUaVariant value1, value2;

	for (uint32_t idx=0; idx<10; idx++) {
		Argument::SPtr argument;
		OpcUaExtensionObject::SPtr extentionObject = constructSPtr<OpcUaExtensionObject>();
		argument = extentionObject->parameter<Argument>(OpcUaId_Argument_Encoding_DefaultBinary);
		argument->name().value("ArgumentName");
		argument->dataType().set("NodeName", 23);
		argument->arrayDimensions()->resize(3);
		argument->arrayDimensions()->set(0, 123);
		argument->arrayDimensions()->set(1, 456);
		argument->arrayDimensions()->set(2, 789);
		argument->description().set("de", "Description");
		value1.pushBack(extentionObject);
	}
	BOOST_REQUIRE(value1.xmlEncode(pt, xmlns) == true);

	xml.ptree(pt);
	xml.write(std::cout);
	std::cout << std::endl;

	BOOST_REQUIRE(value2.xmlDecode(pt, xmlns) == true);
	for (uint32_t idx=0; idx<10; idx++) {
		Argument::SPtr argument;
		OpcUaExtensionObject::SPtr extentionObject2 = value2.getSPtr<OpcUaExtensionObject>(idx);
		BOOST_REQUIRE(extentionObject2->typeId().nodeId<OpcUaUInt32>() == OpcUaId_Argument_Encoding_DefaultBinary);
		argument = extentionObject2->parameter<Argument>();
		BOOST_REQUIRE(argument->name().toStdString() == "ArgumentName");
		BOOST_REQUIRE(argument->dataType() == OpcUaNodeId("NodeName", 23));
		BOOST_REQUIRE(argument->description() == OpcUaLocalizedText("de", "Description"));
	}
}

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: gianricardo/OpcUaStack

max_issues_repo_name: gianricardo/OpcUaStack

max_forks_repo_name: gianricardo/OpcUaStack


text:
// ==========================================================================
// Munin View.
//
// Copyright (C) 2013 Matthew Chaplain, All Rights Reserved.
//
// Permission to reproduce, distribute, perform, display, and to prepare
// derivitive works from this file under the following conditions:
//
// 1. Any copy, reproduction or derivitive work of any part of this file
//    contains this copyright notice and licence in its entirety.
//
// 2. The rights granted to you under this license automatically terminate
//    should you attempt to assert any patent claims against the licensor
//    or contributors, which in any way restrict the ability of any party
//    from using this software or portions thereof in any form under the
//    terms of this license.
//
// Disclaimer: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
//             KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//             WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
//             PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
//             OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
//             OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
//             OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
//             SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ==========================================================================
#pragma once

#include <munin/basic_container.hpp>
#include <munin/layout.hpp>
#include <boost/any.hpp>
#include <memory>
#include <tuple>
#include <type_traits>
#include <utility>

namespace munin { namespace detail {

// Overload where the next argument is convertible to a component.
template <class... Args>
void view_helper(
    std::shared_ptr<container> const &content,
    std::shared_ptr<component> const &prev,
    std::shared_ptr<component> const &comp,
    Args&&... args);

// Overload where the next argument is not convertible to a component.
// In this case, the argument is automatically wrapped in a Boost.Any
// object and passed as the layout hint.
template <
    class Hint,
    class = typename std::enable_if<
        !std::is_convertible<Hint, std::shared_ptr<component>>::value
    >::type,
    class... Args
>
void view_helper(
    std::shared_ptr<container> const &content,
    std::shared_ptr<component> const &prev,
    Hint&& hint,
    Args&&... args);

// Overload where there is no next argument.  This is the terminal case.
inline void view_helper(
    std::shared_ptr<container> const &content,
    std::shared_ptr<component> const &prev)
{
    if (prev)
    {
        content->add_component(prev);
    }
}

}

//* =========================================================================
/// \brief Constructs a container with a given layout and components.
/// \par Usage
/// Simply call, passing a layout and a series of components and/or
/// layout hints.
/// \par Example #1
/// \code
///     auto v = munin::view(
///         munin::make_compass_layout(),
///         // Note: passing both components and layout hints.
///         munin::make_image("Name: "), munin::COMPASS_LAYOUT_WEST,
///         munin::make_framed_component(
///             munin::make_solid_frame(),
///             munin::make_edit()));
/// \endcode
/// \par Example #2
/// \code
///     auto y = munin::view(
///         munin::make_vertical_squeeze_layout(),
///         // Note: passing components only; no hints.
///         munin::make_button("OK"),
///         munin::make_button("Cancel"));
/// \endcode
//* =========================================================================
template <class... Args>
std::shared_ptr<container> view(
    std::unique_ptr<layout> lyt,
    Args&&... args)
{
    auto comp = std::make_shared<basic_container>();
    comp->set_layout(std::move(lyt));
    detail::view_helper(
        comp, std::shared_ptr<component>{}, std::forward<Args>(args)...);

    return comp;
}

namespace detail {

template <class... Args>
void view_helper(
    std::shared_ptr<container> const &content,
    std::shared_ptr<component> const &prev,
    std::shared_ptr<component> const &comp,
    Args&&... args)
{
    if (prev)
    {
        content->add_component(prev);
    }

    view_helper(content, comp, std::forward<Args>(args)...);
}

template <
    class Hint,
    class,
    class... Args
>
void view_helper(
    std::shared_ptr<container> const &content,
    std::shared_ptr<component> const &prev,
    Hint&& hint,
    Args&&... args)
{
    if (prev)
    {
        content->add_component(prev, boost::any(std::forward<Hint>(hint)));
    }

    view_helper(content, {}, std::forward<Args>(args)...);
}

}

}

ext: hpp


text:
// Boost.Geometry (aka GGL, Generic Geometry Library)
// QuickBook Example

// Copyright (c) 2020 Digvijay Janartha, Hamirpur, India.

// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

//[covered_by
//` Checks if the first geometry is inside or on border the second geometry

#include <iostream>

#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>

namespace bg = boost::geometry; /*< Convenient namespace alias >*/

int main()
{
    // Checks if the first geometry is inside or on border the second geometry.
    bg::model::polygon<bg::model::d2::point_xy<double> > poly1;
    bg::read_wkt("POLYGON((0 2,0 3,2 4,1 2,0 2))", poly1);
    bg::model::polygon<bg::model::d2::point_xy<double> > poly2;
    bg::read_wkt("POLYGON((0 4,3 4,2 2,0 1,0 4))", poly2);
    bool check_covered = bg::covered_by(poly1, poly2);
    if (check_covered) {
         std::cout << "Covered: Yes" << std::endl;
    } else {
        std::cout << "Covered: No" << std::endl;
    }

    bg::model::polygon<bg::model::d2::point_xy<double> > poly3;
    bg::read_wkt("POLYGON((-1 -1,-3 -4,-7 -7,-4 -3,-1 -1))", poly3);
    check_covered = bg::covered_by(poly1, poly3);
    if (check_covered) {
         std::cout << "Covered: Yes" << std::endl;
    } else {
        std::cout << "Covered: No" << std::endl;
    }

    // This should return true since both polygons are same, so they are lying on each other.
    check_covered = bg::covered_by(poly1, poly1);
    if (check_covered) {
         std::cout << "Covered: Yes" << std::endl;
    } else {
        std::cout << "Covered: No" << std::endl;
    }

    return 0;
}

//]

//[covered_by_output
/*`
Output:
[pre
Covered: Yes

[$img/algorithms/covered_by.png]

Covered: No
Covered: Yes
]
*/
//]

ext: cpp

max_stars_repo_name: jkerkela/geometry

max_issues_repo_name: jkerkela/geometry

max_forks_repo_name: jkerkela/geometry