From f0e0fb5f3f2af8b695680e84572137660ffd835b Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Tue, 16 Feb 2021 21:27:12 +0300 Subject: Update documentation --- xsd/doc/cxx/tree/manual/index.xhtml.in | 264 +++++++++++++++++---------------- 1 file changed, 134 insertions(+), 130 deletions(-) (limited to 'xsd/doc/cxx/tree/manual/index.xhtml.in') diff --git a/xsd/doc/cxx/tree/manual/index.xhtml.in b/xsd/doc/cxx/tree/manual/index.xhtml.in index 48f36b6..5a7240a 100644 --- a/xsd/doc/cxx/tree/manual/index.xhtml.in +++ b/xsd/doc/cxx/tree/manual/index.xhtml.in @@ -469,12 +469,14 @@
  • XSD Compiler Command Line Manual
  • -
  • The examples/cxx/tree/ directory in the XSD - distribution contains a collection of examples and a README - file with an overview of each example.
  • +
  • The cxx/tree/ directory in the + xsd-examples package + contains a collection of examples and a README file with an overview + of each example.
  • -
  • The README file in the XSD distribution explains - how to compile the examples on various platforms.
  • +
  • The README file in the + xsd-examples package + explains how to build the examples.
  • The xsd-users mailing list is a place to ask questions. Furthermore the @@ -522,12 +524,12 @@

    2.1.1 C++ Standard

    -

    The C++/Tree mapping provides support for ISO/IEC C++ 1998/2003 (C++98) - and ISO/IEC C++ 2011 (C++11). To select the C++ standard for the +

    The C++/Tree mapping provides support for ISO/IEC C++ 2011 (C++11) + and ISO/IEC C++ 1998/2003 (C++98). To select the C++ standard for the generated code we use the --std XSD compiler command - line option. While the majority of the examples in this manual use - C++98, support for the new functionality and library components - introduced in C++11 are discussed throughout the document.

    + line option. While the majority of the examples in this guide use + C++11, the document explains the C++11/98 usage difference and so + they can easily be converted to C++98.

    2.1.2 Identifiers

    @@ -1144,8 +1146,8 @@ namespace system sequences of non-fundamental C++ types is the addition of the overloaded push_back and insert member functions which instead of the constant reference - to the element type accept automatic pointer (std::auto_ptr - or std::unique_ptr, depending on the C++ standard + to the element type accept automatic pointer (std::unique_ptr + or std::auto_ptr, depending on the C++ standard selected) to the element type. These functions assume ownership of the pointed to object and reset the passed automatic pointer.

    @@ -2412,8 +2414,8 @@ public: sequences of non-fundamental C++ types is the addition of the overloaded push_back and insert member functions which instead of the constant reference - to the element type accept automatic pointer (std::auto_ptr - or std::unique_ptr, depending on the C++ standard + to the element type accept automatic pointer (std::unique_ptr + or std::auto_ptr, depending on the C++ standard selected) to the element type. These functions assume ownership of the pointed to object and reset the passed automatic pointer.

    @@ -2480,10 +2482,10 @@ public: instance is initialized with copies of the passed objects. In the second constructor, arguments that are complex types (that is, they themselves contain elements or attributes) are passed as - either std::auto_ptr (C++98) or std::unique_ptr - (C++11), depending on the C++ standard selected. In this case the newly + either std::unique_ptr (C++11) or std::auto_ptr + (C++98), depending on the C++ standard selected. In this case the newly created instance is directly initialized with and assumes ownership - of the pointed to objects and the std::[auto|unique]_ptr + of the pointed to objects and the std::[unique|auto]_ptr arguments are reset to 0. For instance:

    @@ -2529,7 +2531,7 @@ class object: public xml_schema::type
     {
     public:
       object (const bool& s_one, const complex& c_one);
    -  object (const bool& s_one, std::[auto|unique]_ptr<complex> c_one);
    +  object (const bool& s_one, std::[unique|auto]_ptr<complex> c_one);
       object (const object&);
     
     public:
    @@ -2546,7 +2548,7 @@ public:
       

    Notice that the generated complex class does not - have the second (std::[auto|unique]_ptr) version of the + have the second (std::[unique|auto]_ptr) version of the constructor since all its required members are of simple types.

    If an XML Schema complex type has an ultimate base which is an XML @@ -2817,8 +2819,8 @@ public: constant of the member's type. It makes a deep copy of its argument. Except for member's types that are mapped to fundamental C++ types, the second modifier function is provided that expects an argument - of type automatic pointer (std::auto_ptr or - std::unique_ptr, depending on the C++ standard selected) + of type automatic pointer (std::unique_ptr or + std::auto_ptr, depending on the C++ standard selected) to the member's type. It assumes ownership of the pointed to object and resets the passed automatic pointer. For instance:

    @@ -2854,7 +2856,7 @@ public: member (const member_type&); void - member (std::[auto|unique]_ptr<member_type>); + member (std::[unique|auto]_ptr<member_type>); ... }; @@ -2871,7 +2873,7 @@ class object: public xml_schema::type public: ... - std::[auto|unique]_ptr<member_type> + std::[unique|auto]_ptr<member_type> detach_member (); ... @@ -2896,19 +2898,19 @@ f (object& o) o.member ("hello"); // set, deep copy o.member () = "hello"; // set, deep copy - // C++98 version. - // - std::auto_ptr<string> p (new string ("hello")); - o.member (p); // set, assumes ownership - p = o.detach_member (); // detach, member is uninitialized - o.member (p); // re-attach - // C++11 version. // std::unique_ptr<string> p (new string ("hello")); o.member (std::move (p)); // set, assumes ownership p = o.detach_member (); // detach, member is uninitialized o.member (std::move (p)); // re-attach + + // C++98 version. + // + std::auto_ptr<string> p (new string ("hello")); + o.member (p); // set, assumes ownership + p = o.detach_member (); // detach, member is uninitialized + o.member (p); // re-attach } @@ -2938,8 +2940,8 @@ f (object& o) member's type. It makes a deep copy of its argument. Except for member's types that are mapped to fundamental C++ types, the second modifier function is provided that expects an argument - of type automatic pointer (std::auto_ptr or - std::unique_ptr, depending on the C++ standard selected) + of type automatic pointer (std::unique_ptr or + std::auto_ptr, depending on the C++ standard selected) to the member's type. It assumes ownership of the pointed to object and resets the passed automatic pointer. The last modifier function expects an argument of type reference to constant of the container @@ -2979,7 +2981,7 @@ public: member (const member_type&); void - member (std::[auto|unique]_ptr<member_type>); + member (std::[unique|auto]_ptr<member_type>); void member (const member_optional&); @@ -2992,7 +2994,7 @@ public:

    The optional class template is defined in an implementation-specific namespace and has the following - interface. The [auto|unique]_ptr-based constructor + interface. The [unique|auto]_ptr-based constructor and modifier function are only available if the template argument is not a fundamental C++ type.

    @@ -3012,7 +3014,7 @@ public: // Assumes ownership. // explicit - optional (std::[auto|unique]_ptr<X>); + optional (std::[unique|auto]_ptr<X>); optional (const optional&); @@ -3061,11 +3063,11 @@ public: // Assumes ownership. // void - set (std::[auto|unique]_ptr<X>); + set (std::[unique|auto]_ptr<X>); // Detach and return the contained value. // - std::[auto|unique]_ptr<X> + std::[unique|auto]_ptr<X> detach (); void @@ -3124,17 +3126,6 @@ f (object& o) o.member ().reset (); // reset } - // C++98 version. - // - std::auto_ptr<string> p (new string ("hello")); - o.member (p); // set, assumes ownership - - p = new string ("hello"); - o.member ().set (p); // set, assumes ownership - - p = o.member ().detach (); // detach, member is reset - o.member ().set (p); // re-attach - // C++11 version. // std::unique_ptr<string> p (new string ("hello")); @@ -3145,6 +3136,17 @@ f (object& o) p = o.member ().detach (); // detach, member is reset o.member ().set (std::move (p)); // re-attach + + // C++98 version. + // + std::auto_ptr<string> p (new string ("hello")); + o.member (p); // set, assumes ownership + + p = new string ("hello"); + o.member ().set (p); // set, assumes ownership + + p = o.member ().detach (); // detach, member is reset + o.member ().set (p); // re-attach } @@ -3226,7 +3228,7 @@ public: as well as the detach_back and detach member functions. The additional push_back and insert functions accept an automatic pointer - (std::auto_ptr or std::unique_ptr, + (std::unique_ptr or std::auto_ptr, depending on the C++ standard selected) to the element type instead of the constant reference. They assume ownership of the pointed to object and reset the passed @@ -3244,17 +3246,17 @@ public: ... void - push_back (std::[auto|unique]_ptr<X>) + push_back (std::[unique|auto]_ptr<X>) iterator - insert (iterator position, std::[auto|unique]_ptr<X>) + insert (iterator position, std::[unique|auto]_ptr<X>) - std::[auto|unique]_ptr<X> + std::[unique|auto]_ptr<X> detach_back (bool pop = true); iterator detach (iterator position, - std::[auto|unique]_ptr<X>& result, + std::[unique|auto]_ptr<X>& result, bool erase = true) ... @@ -3282,13 +3284,6 @@ f (object& o) // s.push_back ("hello"); // deep copy - // C++98 version. - // - std::auto_ptr<string> p (new string ("hello")); - s.push_back (p); // assumes ownership - p = s.detach_back (); // detach and pop - s.push_back (p); // re-append - // C++11 version. // std::unique_ptr<string> p (new string ("hello")); @@ -3296,6 +3291,13 @@ f (object& o) p = s.detach_back (); // detach and pop s.push_back (std::move (p)); // re-append + // C++98 version. + // + std::auto_ptr<string> p (new string ("hello")); + s.push_back (p); // assumes ownership + p = s.detach_back (); // detach and pop + s.push_back (p); // re-append + // Setting a new container. // object::member_sequence n; @@ -3617,7 +3619,9 @@ w[0].amount (10000);

    For the complete working code shown in this section refer to the order/element example in the - examples/cxx/tree/ directory in the XSD distribution.

    + cxx/tree/ directory in the + xsd-examples + package.

    If both the base and derived types are ordered, then the content order sequence is only added to the base and the content @@ -3646,8 +3650,7 @@ w[0].amount (10000);

    As an example, here is how we can use the Boost Multi-Index container for content order. First we create the content-order-container.hxx header with the - following definition (in C++11, use the alias template - instead):

    + following definition:

     #ifndef CONTENT_ORDER_CONTAINER
    @@ -3665,7 +3668,7 @@ struct by_id {};
     struct by_id_index {};
     
     template <typename T>
    -struct content_order_container:
    +using content_order_container =
       boost::multi_index::multi_index_container<
         T,
         boost::multi_index::indexed_by<
    @@ -3679,8 +3682,7 @@ struct content_order_container:
             boost::multi_index::member<T, std::size_t, &T::id>
           >
         >
    -  >
    -{};
    +  >;
     
     #endif
       
    @@ -3734,7 +3736,7 @@ for (id_iterator i (r.first); i != r.second; ++i)

    The parsing functions read XML instance documents and return corresponding object models as an automatic pointer - (std::auto_ptr or std::unique_ptr, + (std::unique_ptr or std::auto_ptr, depending on the C++ standard selected). Their signatures have the following pattern (type denotes element's type and name denotes element's @@ -3742,7 +3744,7 @@ for (id_iterator i (r.first); i != r.second; ++i)

    -std::[auto|unique]_ptr<type>
    +std::[unique|auto]_ptr<type>
     name (....);
       
    @@ -3814,13 +3816,13 @@ public: value (const value_type&); void - value (std::[auto|unique]_ptr<value_type>); + value (std::[unique|auto]_ptr<value_type>); // Constructors. // root (const value_type&); - root (std::[auto|unique]_ptr<value_type>); + root (std::[unique|auto]_ptr<value_type>); root (const xercesc::DOMElement&, xml_schema::flags = 0); @@ -3916,7 +3918,7 @@ namespace xml_schema class element_map { public: - static std::[auto|unique]_ptr<xml_schema::element_type> + static std::[unique|auto]_ptr<xml_schema::element_type> parse (const xercesc::DOMElement&, flags = 0); static void @@ -3927,8 +3929,8 @@ namespace xml_schema

    The parse() function creates the corresponding element type object based on the element name and namespace - and returns it as an automatic pointer (std::auto_ptr - or std::unique_ptr, depending on the C++ standard + and returns it as an automatic pointer (std::unique_ptr + or std::auto_ptr, depending on the C++ standard selected) to xml_schema::element_type. The serialize() function serializes the passed element object to DOMElement. Note that in case of @@ -3965,7 +3967,7 @@ struct no_element_info: virtual exception // DOMElement& e = ... // Parse XML to DOM. -auto_ptr<xml_schema::element_type> r ( +unique_ptr<xml_schema::element_type> r ( xml_schema::element_map::parse (e)); if (root1 r1 = dynamic_cast<root1*> (r.get ())) @@ -4097,7 +4099,7 @@ f (root& r) i != r.item ().end () ++i) { - std::auto_ptr<base> c (i->_clone ()); + std::unique_ptr<base> c (i->_clone ()); } } @@ -4881,8 +4883,9 @@ for (batch::content_order_const_iterator i (b.content_order ().begin ());

    For the complete working code that shows the use of wildcards in ordered types refer to the order/element example in - the examples/cxx/tree/ directory in the XSD - distribution.

    + the cxx/tree/ directory in the + xsd-examples + package.

    2.12.5 Mapping for anyAttribute

    @@ -5293,8 +5296,9 @@ for (text::content_order_const_iterator i (t.content_order ().begin ());

    For the complete working code that shows the use of mixed content in ordered types refer to the order/mixed example in - the examples/cxx/tree/ directory in the XSD - distribution.

    + the cxx/tree/ directory in the + xsd-examples + package.

    @@ -5318,18 +5322,18 @@ for (text::content_order_const_iterator i (t.content_order ().begin ()); // Read from a URI or a local file. // -std::[auto|unique]_ptr<type> +std::[unique|auto]_ptr<type> name (const std::basic_string<C>& uri, xml_schema::flags = 0, const xml_schema::properties& = xml_schema::properties ()); -std::[auto|unique]_ptr<type> +std::[unique|auto]_ptr<type> name (const std::basic_string<C>& uri, xml_schema::error_handler&, xml_schema::flags = 0, const xml_schema::properties& = xml_schema::properties ()); -std::[auto|unique]_ptr<type> +std::[unique|auto]_ptr<type> name (const std::basic_string<C>& uri, xercesc::DOMErrorHandler&, xml_schema::flags = 0, @@ -5339,38 +5343,38 @@ name (const std::basic_string<C>& uri, // Read from std::istream. // -std::[auto|unique]_ptr<type> +std::[unique|auto]_ptr<type> name (std::istream&, xml_schema::flags = 0, const xml_schema::properties& = xml_schema::properties ()); -std::[auto|unique]_ptr<type> +std::[unique|auto]_ptr<type> name (std::istream&, xml_schema::error_handler&, xml_schema::flags = 0, const xml_schema::properties& = xml_schema::properties ()); -std::[auto|unique]_ptr<type> +std::[unique|auto]_ptr<type> name (std::istream&, xercesc::DOMErrorHandler&, xml_schema::flags = 0, const xml_schema::properties& = xml_schema::properties ()); -std::[auto|unique]_ptr<type> +std::[unique|auto]_ptr<type> name (std::istream&, const std::basic_string<C>& id, xml_schema::flags = 0, const xml_schema::properties& = xml_schema::properties ()); -std::[auto|unique]_ptr<type> +std::[unique|auto]_ptr<type> name (std::istream&, const std::basic_string<C>& id, xml_schema::error_handler&, xml_schema::flags = 0, const xml_schema::properties& = xml_schema::properties ()); -std::[auto|unique]_ptr<type> +std::[unique|auto]_ptr<type> name (std::istream&, const std::basic_string<C>& id, xercesc::DOMErrorHandler&, @@ -5381,18 +5385,18 @@ name (std::istream&, // Read from InputSource. // -std::[auto|unique]_ptr<type> +std::[unique|auto]_ptr<type> name (xercesc::InputSource&, xml_schema::flags = 0, const xml_schema::properties& = xml_schema::properties ()); -std::[auto|unique]_ptr<type> +std::[unique|auto]_ptr<type> name (xercesc::InputSource&, xml_schema::error_handler&, xml_schema::flags = 0, const xml_schema::properties& = xml_schema::properties ()); -std::[auto|unique]_ptr<type> +std::[unique|auto]_ptr<type> name (xercesc::InputSource&, xercesc::DOMErrorHandler&, xml_schema::flags = 0, @@ -5402,13 +5406,13 @@ name (xercesc::InputSource&, // Read from DOM. // -std::[auto|unique]_ptr<type> +std::[unique|auto]_ptr<type> name (const xercesc::DOMDocument&, xml_schema::flags = 0, const xml_schema::properties& = xml_schema::properties ()); -std::[auto|unique]_ptr<type> -name (xml_schema::dom::[auto|unique]_ptr<xercesc::DOMDocument>, +std::[unique|auto]_ptr<type> +name (xml_schema::dom::[unique|auto]_ptr<xercesc::DOMDocument>, xml_schema::flags = 0, const xml_schema::properties& = xml_schema::properties ()); @@ -5418,7 +5422,7 @@ name (xml_schema::dom::[auto|unique]_ptr<xercesc::DOMDocument>, or a pre-parsed DOM instance in the form of xercesc::DOMDocument. All the parsing functions return a dynamically allocated object model as either - std::auto_ptr or std::unique_ptr, + std::unique_ptr or std::auto_ptr, depending on the C++ standard selected. Each of these parsing functions is discussed in more detail in the following sections.

    @@ -5462,7 +5466,7 @@ name (xml_schema::dom::[auto|unique]_ptr<xercesc::DOMDocument>,
    Assume ownership of the DOM document passed. This flag only makes sense together with the keep_dom flag in the call to the parsing function with the - xml_schema::dom::[auto|unique]_ptr<DOMDocument> + xml_schema::dom::[unique|auto]_ptr<DOMDocument> argument.
    xml_schema::flags::dont_validate
    @@ -5478,7 +5482,7 @@ name (xml_schema::dom::[auto|unique]_ptr<xercesc::DOMDocument>,
     using xml_schema::flags;
     
    -std::auto_ptr<type> r (
    +std::unique_ptr<type> r (
       name ("test.xml", flags::keep_dom | flags::dont_validate));
       
    @@ -5912,19 +5916,19 @@ struct no_prefix_mapping: virtual exception For example:

    -using std::auto_ptr;
    +using std::unique_ptr;
     
    -auto_ptr<type> r1 (name ("test.xml"));
    -auto_ptr<type> r2 (name ("https://www.codesynthesis.com/test.xml"));
    +unique_ptr<type> r1 (name ("test.xml"));
    +unique_ptr<type> r2 (name ("https://www.codesynthesis.com/test.xml"));
       
    -

    Or, in the C++11 mode:

    +

    Or, in the C++98 mode:

    -using std::unique_ptr;
    +using std::auto_ptr;
     
    -unique_ptr<type> r1 (name ("test.xml"));
    -unique_ptr<type> r2 (name ("https://www.codesynthesis.com/test.xml"));
    +auto_ptr<type> r1 (name ("test.xml"));
    +auto_ptr<type> r2 (name ("https://www.codesynthesis.com/test.xml"));
       

    3.5 Reading from std::istream

    @@ -5935,17 +5939,17 @@ unique_ptr<type> r2 (name ("https://www.codesynthesis.com/test.xml")); relative paths. For instance:

    -using std::auto_ptr;
    +using std::unique_ptr;
     
     {
       std::ifstream ifs ("test.xml");
    -  auto_ptr<type> r (name (ifs, "test.xml"));
    +  unique_ptr<type> r (name (ifs, "test.xml"));
     }
     
     {
       std::string str ("..."); // Some XML fragment.
       std::istringstream iss (str);
    -  auto_ptr<type> r (name (iss));
    +  unique_ptr<type> r (name (iss));
     }
       
    @@ -5958,7 +5962,7 @@ using std::auto_ptr;
     xercesc::StdInInputSource is;
    -std::auto_ptr<type> r (name (is));
    +std::unique_ptr<type> r (name (is));
       

    3.7 Reading from DOM

    @@ -5981,15 +5985,6 @@ std::auto_ptr<type> r (name (is)); of the DOM document passed. For example:

    -// C++98 version.
    -//
    -xml_schema::dom::auto_ptr<xercesc::DOMDocument> doc = ...
    -
    -std::auto_ptr<type> r (
    -  name (doc, xml_schema::flags::keep_dom | xml_schema::flags::own_dom));
    -
    -// At this point doc is reset to 0.
    -
     // C++11 version.
     //
     xml_schema::dom::unique_ptr<xercesc::DOMDocument> doc = ...
    @@ -5999,6 +5994,15 @@ std::unique_ptr<type> r (
             xml_schema::flags::keep_dom | xml_schema::flags::own_dom));
     
     // At this point doc is reset to 0.
    +
    +// C++98 version.
    +//
    +xml_schema::dom::auto_ptr<xercesc::DOMDocument> doc = ...
    +
    +std::auto_ptr<type> r (
    +  name (doc, xml_schema::flags::keep_dom | xml_schema::flags::own_dom));
    +
    +// At this point doc is reset to 0.
       

    4 Serialization

    @@ -6086,7 +6090,7 @@ name (xercesc::XMLFormatTarget&, // Serialize to DOM. // -xml_schema::dom::[auto|unique]_ptr<xercesc::DOMDocument> +xml_schema::dom::[unique|auto]_ptr<xercesc::DOMDocument> name (const type&, const xml_schema::namespace_infomap& xml_schema::namespace_infomap (), @@ -6275,7 +6279,7 @@ map[""].schema = "test.xsd"; operator. For example:

    -std::auto_ptr<type> r = ...
    +std::unique_ptr<type> r = ...
     std::ofstream ofs ("test.xml");
     xml_schema::namespace_infomap map;
     name (ofs,
    @@ -6384,7 +6388,7 @@ struct serialization: virtual exception
       
     // Obtain the object model.
     //
    -std::auto_ptr<type> r = ...
    +std::unique_ptr<type> r = ...
     
     // Prepare namespace mapping and schema location information.
     //
    @@ -6417,11 +6421,11 @@ name (std::cout, *r, map);
       

    -using std::auto_ptr;
    +using std::unique_ptr;
     
     // Obtain the object model.
     //
    -auto_ptr<type> r = ...
    +unique_ptr<type> r = ...
     
     // Prepare namespace mapping and schema location information.
     //
    @@ -6437,15 +6441,15 @@ XMLPlatformUtils::Initialize ();
     {
       // Choose a target.
       //
    -  auto_ptr<XMLFormatTarget> ft;
    +  unique_ptr<XMLFormatTarget> ft;
     
       if (argc != 2)
       {
    -    ft = auto_ptr<XMLFormatTarget> (new StdOutFormatTarget ());
    +    ft = unique_ptr<XMLFormatTarget> (new StdOutFormatTarget ());
       }
       else
       {
    -    ft = auto_ptr<XMLFormatTarget> (
    +    ft = unique_ptr<XMLFormatTarget> (
           new LocalFileFormatTarget (argv[1]));
       }
     
    @@ -6477,7 +6481,7 @@ XMLPlatformUtils::Terminate ();
       
     // Obtain the object model.
     //
    -std::auto_ptr<type> r = ...
    +std::unique_ptr<type> r = ...
     
     using namespace xercesc;
     
    @@ -6565,7 +6569,7 @@ XMLPlatformUtils::Initialize ();
     {
       // Parse XML to object model.
       //
    -  std::auto_ptr<type> r (root (
    +  std::unique_ptr<type> r (root (
         "root.xml",
          xml_schema::flags::keep_dom |
          xml_schema::flags::dont_initialize));
    @@ -6612,7 +6616,7 @@ XMLPlatformUtils::Initialize ();
     {
       // Parse XML to object model.
       //
    -  std::auto_ptr<type> r (root (
    +  std::unique_ptr<type> r (root (
         "root.xml",
          xml_schema::flags::keep_dom |
          xml_schema::flags::dont_initialize));
    @@ -6703,7 +6707,7 @@ XMLPlatformUtils::Terminate ();
       
     // Parse XML to object model.
     //
    -std::auto_ptr<type> r (root ("root.xml"));
    +std::unique_ptr<type> r (root ("root.xml"));
     
     // Save to a CDR stream.
     //
    @@ -6717,7 +6721,7 @@ ocdr << *r;
     ACE_InputCDR ace_icdr (buf, size);
     xml_schema::istream<ACE_InputCDR> icdr (ace_icdr);
     
    -std::auto_ptr<object> copy (new object (icdr));
    +std::unique_ptr<object> copy (new object (icdr));
     
     // Serialize to XML.
     //
    -- 
    cgit v1.1