------------------------------------------------------------------------------
--                                                                          --
--                An Ada2005 binding to the Qt C++ framework                --
--                                                                          --
------------------------------------------------------------------------------
--                                                                          --
-- Copyright © 2007-2011 Vadim Godunko <vgodunko@gmail.com>                 --
--                                                                          --
-- QtAda is free software;  you can  redistribute it and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 2,  or (at your option) any later ver- --
-- sion. QtAda is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
-- for  more details.  You should have  received  a copy of the GNU General --
-- Public License distributed with QtAda;  see file COPYING.  If not, write --
-- to  the  Free Software Foundation,  51  Franklin  Street,  Fifth  Floor, --
-- Boston, MA 02110-1301, USA.                                              --
--                                                                          --
-- As a special exception,  if other files  instantiate  generics from this --
-- unit, or you link  this unit with other files  to produce an executable, --
-- this  unit  does not  by itself cause  the resulting  executable  to  be --
-- covered  by the  GNU  General  Public  License.  This exception does not --
-- however invalidate  any other reasons why  the executable file  might be --
-- covered by the  GNU Public License.                                      --
--                                                                          --
------------------------------------------------------------------------------
--  $Revision: 3848 $ $Date: 2011-06-28 08:49:18 +0400 (Tue, 28 Jun 2011) $
------------------------------------------------------------------------------
private with Ada.Finalization;
with Qt4.Byte_Arrays;
limited with Qt4.Reg_Exps;
with Qt_Ada.Internals.Value_Class_Sizes;
with System;

package Qt4.Strings is

   --  QChar::Category

   type Character_Category is
    (No_Category,
     Mark_Non_Spacing,
     Mark_Spacing_Combining,
     Mark_Enclosing,
     Number_Decimal_Digit,
     Number_Letter,
     Number_Other,
     Separator_Space,
     Separator_Line,
     Separator_Paragraph,
     Other_Control,
     Other_Format,
     Other_Surrogate,
     Other_Private_Use,
     Other_Not_Assigned,
     Letter_Uppercase,
     Letter_Lowercase,
     Letter_Titlecase,
     Letter_Modifier,
     Letter_Other,
     Punctuation_Connector,
     Punctuation_Dash,
     Punctuation_Open,
     Punctuation_Close,
     Punctuation_Initial_Quote,
     Punctuation_Final_Quote,
     Punctuation_Other,
     Symbol_Math,
     Symbol_Currency,
     Symbol_Modifier,
     Symbol_Other);
   pragma Convention (C, Character_Category);
   for Character_Category'Size use Interfaces.C.unsigned'Size;

   --  QChar::CombiningClass

   type Character_Combining_Class is
    (Combining_Below_Left_Attached,
     Combining_Below_Attached,
     Combining_Below_Right_Attached,
     Combining_Left_Attached,
     Combining_Right_Attached,
     Combining_Above_Left_Attached,
     Combining_Above_Attached,
     Combining_Above_Right_Attached,
     Combining_Below_Left,
     Combining_Below,
     Combining_Below_Right,
     Combining_Left,
     Combining_Right,
     Combining_Above_Left,
     Combining_Above,
     Combining_Above_Right,
     Combining_Double_Below,
     Combining_Double_Above,
     Combining_Iota_Subscript);
   pragma Convention (C, Character_Combining_Class);
   for Character_Combining_Class'Size use Interfaces.C.unsigned'Size;
   for Character_Combining_Class use
    (Combining_Below_Left_Attached  => 200,
     Combining_Below_Attached       => 202,
     Combining_Below_Right_Attached => 204,
     Combining_Left_Attached        => 208,
     Combining_Right_Attached       => 210,
     Combining_Above_Left_Attached  => 212,
     Combining_Above_Attached       => 214,
     Combining_Above_Right_Attached => 216,
     Combining_Below_Left           => 218,
     Combining_Below                => 220,
     Combining_Below_Right          => 222,
     Combining_Left                 => 224,
     Combining_Right                => 226,
     Combining_Above_Left           => 228,
     Combining_Above                => 230,
     Combining_Above_Right          => 232,
     Combining_Double_Below         => 233,
     Combining_Double_Above         => 234,
     Combining_Iota_Subscript       => 240);

   --  QChar::Decomposition

   type Character_Decomposition is
    (No_Decomposition,
     Canonical,
     Font,
     No_Break,
     Initial,
     Medial,
     Final,
     Isolated,
     Circle,
     Super,
     Sub,
     Vertical,
     Wide,
     Narrow,
     Small,
     Square,
     Compat,
     Fraction);
   pragma Convention (C, Character_Decomposition);
   for Character_Decomposition'Size use Interfaces.C.unsigned'Size;

   --  QChar::Direction

   type Character_Direction is
    (Dir_L,
     Dir_R,
     Dir_EN,
     Dir_ES,
     Dir_ET,
     Dir_AN,
     Dir_CS,
     Dir_B,
     Dir_S,
     Dir_WS,
     Dir_ON,
     Dir_LRE,
     Dir_LRO,
     Dir_AL,
     Dir_RLE,
     Dir_RLO,
     Dir_PDF,
     Dir_NSM,
     Dir_BN);
   pragma Convention (C, Character_Direction);
   for Character_Direction'Size use Interfaces.C.unsigned'Size;

   --  QChar::Joining

   type Character_Joining is
    (Other_Joining,
     Dual,
     Right,
     Center);
   pragma Convention (C, Character_Joining);
   for Character_Joining'Size use Interfaces.C.unsigned'Size;

   --  QChar::SpecialCharacter

   type Special_Character is
    (Nil,
     Nbsp,
     Line_Separator,
     Paragraph_Separator,
     Byte_Order_Mark,
     Object_Replacement_Character,
     Replacement_Character,
     Byte_Order_Swapped);
   pragma Convention (C, Special_Character);
   for Special_Character'Size use Interfaces.C.unsigned'Size;
   for Special_Character use
    (Nil                          => 0,
     Nbsp                         => 160,
     Line_Separator               => 8232,
     Paragraph_Separator          => 8233,
     Byte_Order_Mark              => 65279,
     Object_Replacement_Character => 65532,
     Replacement_Character        => 65533,
     Byte_Order_Swapped           => 65534);

   --  QChar::UnicodeVersion

   type Character_Unicode_Version is
    (Unicode_Unassigned,
     Unicode_1_1,
     Unicode_2_0,
     Unicode_2_1_2,
     Unicode_3_0,
     Unicode_3_1,
     Unicode_3_2,
     Unicode_4_0,
     Unicode_4_1,
     Unicode_5_0);
   pragma Convention (C, Character_Unicode_Version);
   for Character_Unicode_Version'Size use Interfaces.C.unsigned'Size;

   --  QString::NormalizationForm

   type Normalization_Form is
    (Normalization_Form_D,
     Normalization_Form_C,
     Normalization_Form_KD,
     Normalization_Form_KC);
   pragma Convention (C, Normalization_Form);
   for Normalization_Form'Size use Interfaces.C.unsigned'Size;

   --  QString::SplitBehavior

   type Split_Behavior is
    (Keep_Empty_Parts,
     Skip_Empty_Parts);
   pragma Convention (C, Split_Behavior);
   for Split_Behavior'Size use Interfaces.C.unsigned'Size;

   type Q_Char is tagged private;

   type Q_String_List is tagged private;

   type Q_String is tagged private;

   function Create
    (Rc : Wide_Character)
       return Q_Char;

   function Create
    (Rc : Wide_Wide_Character)
       return Q_Char;

   function Create
    (Sc : Special_Character)
       return Q_Char;

   function Create
    (I : Q_String'Class)
       return Q_String_List;

   function Create return Q_String;

   function Create
    (C : Q_Char'Class)
       return Q_String;

   function Category
    (Self : Q_Char'Class)
       return Character_Category;

   function Combining_Class
    (Self : Q_Char'Class)
       return Character_Combining_Class;

   function Decomposition
    (Self : Q_Char'Class)
       return Q_String;

   function Decomposition_Tag
    (Self : Q_Char'Class)
       return Character_Decomposition;

   function Direction
    (Self : Q_Char'Class)
       return Character_Direction;

   function Has_Mirrored
    (Self : Q_Char'Class)
       return Boolean;

   function Is_Digit
    (Self : Q_Char'Class)
       return Boolean;

   function Is_High_Surrogate
    (Self : Q_Char'Class)
       return Boolean;

   function Is_Letter
    (Self : Q_Char'Class)
       return Boolean;

   function Is_Letter_Or_Number
    (Self : Q_Char'Class)
       return Boolean;

   function Is_Low_Surrogate
    (Self : Q_Char'Class)
       return Boolean;

   function Is_Lower
    (Self : Q_Char'Class)
       return Boolean;

   function Is_Mark
    (Self : Q_Char'Class)
       return Boolean;

   function Is_Null
    (Self : Q_Char'Class)
       return Boolean;

   function Is_Number
    (Self : Q_Char'Class)
       return Boolean;

   function Is_Print
    (Self : Q_Char'Class)
       return Boolean;

   function Is_Punct
    (Self : Q_Char'Class)
       return Boolean;

   function Is_Space
    (Self : Q_Char'Class)
       return Boolean;

   function Is_Symbol
    (Self : Q_Char'Class)
       return Boolean;

   function Is_Title_Case
    (Self : Q_Char'Class)
       return Boolean;

   function Is_Upper
    (Self : Q_Char'Class)
       return Boolean;

   function Joining
    (Self : Q_Char'Class)
       return Character_Joining;

   function Mirrored_Char
    (Self : Q_Char'Class)
       return Q_Char;

   function To_Case_Folded
    (Self : Q_Char'Class)
       return Q_Char;

   function To_Lower
    (Self : Q_Char'Class)
       return Q_Char;

   function To_Title_Case
    (Self : Q_Char'Class)
       return Q_Char;

   function To_Upper
    (Self : Q_Char'Class)
       return Q_Char;

   function Unicode
    (Self : Q_Char'Class)
       return Qt4.Q_Unsigned_Short;

   function Unicode_Version
    (Self : Q_Char'Class)
       return Character_Unicode_Version;

   function Category
    (Ucs_2 : Wide_Character)
       return Character_Category;

   function Category
    (Ucs_4 : Wide_Wide_Character)
       return Character_Category;

   function Combining_Class
    (Ucs_2 : Wide_Character)
       return Character_Combining_Class;

   function Combining_Class
    (Ucs_4 : Wide_Wide_Character)
       return Character_Combining_Class;

   function Decomposition
    (Ucs_4 : Wide_Wide_Character)
       return Q_String;

   function Decomposition_Tag
    (Ucs_4 : Wide_Wide_Character)
       return Character_Decomposition;

   function Direction
    (Ucs_2 : Wide_Character)
       return Character_Direction;

   function Direction
    (Ucs_4 : Wide_Wide_Character)
       return Character_Direction;

   function High_Surrogate
    (Ucs_4 : Wide_Wide_Character)
       return Wide_Character;

   function Joining
    (Ucs_2 : Wide_Character)
       return Character_Joining;

   function Joining
    (Ucs_4 : Wide_Wide_Character)
       return Character_Joining;

   function Low_Surrogate
    (Ucs_4 : Wide_Wide_Character)
       return Wide_Character;

   function Mirrored_Char
    (Ucs_2 : Wide_Character)
       return Wide_Character;

   function Mirrored_Char
    (Ucs_4 : Wide_Wide_Character)
       return Wide_Wide_Character;

   function Surrogate_To_Ucs_4
    (High : Wide_Character;
     Low : Wide_Character)
       return Wide_Wide_Character;

   function Surrogate_To_Ucs_4
    (High : Q_Char'Class;
     Low : Q_Char'Class)
       return Wide_Wide_Character;

   function To_Case_Folded
    (Ucs_2 : Wide_Character)
       return Wide_Character;

   function To_Case_Folded
    (Ucs_4 : Wide_Wide_Character)
       return Wide_Wide_Character;

   function To_Lower
    (Ucs_2 : Wide_Character)
       return Wide_Character;

   function To_Lower
    (Ucs_4 : Wide_Wide_Character)
       return Wide_Wide_Character;

   function To_Title_Case
    (Ucs_2 : Wide_Character)
       return Wide_Character;

   function To_Title_Case
    (Ucs_4 : Wide_Wide_Character)
       return Wide_Wide_Character;

   function To_Upper
    (Ucs_2 : Wide_Character)
       return Wide_Character;

   function To_Upper
    (Ucs_4 : Wide_Wide_Character)
       return Wide_Wide_Character;

   function Unicode_Version
    (Ucs_2 : Wide_Character)
       return Character_Unicode_Version;

   function Unicode_Version
    (Ucs_4 : Wide_Wide_Character)
       return Character_Unicode_Version;

   function "="
    (C_1 : Q_Char;
     C_2 : Q_Char)
       return Boolean;

   function "<="
    (C_1 : Q_Char;
     C_2 : Q_Char)
       return Boolean;

   function ">="
    (C_1 : Q_Char;
     C_2 : Q_Char)
       return Boolean;

   function "<"
    (C_1 : Q_Char;
     C_2 : Q_Char)
       return Boolean;

   function ">"
    (C_1 : Q_Char;
     C_2 : Q_Char)
       return Boolean;

   procedure Append
    (Self : in out Q_String_List'Class;
     Str : Q_String'Class);

   function Value
    (Self : Q_String_List'Class;
     Index : Qt4.Q_Integer)
       return Q_String;

   function Size
    (Self : Q_String_List'Class)
       return Qt4.Q_Integer;

   function Filter
    (Self : Q_String_List'Class;
     Str : Q_String'Class;
     Cs : Qt4.Case_Sensitivity
       := Case_Sensitive)
       return Q_String_List;

   function Filter
    (Self : Q_String_List'Class;
     Rx : Qt4.Reg_Exps.Q_Reg_Exp'Class)
       return Q_String_List;

   function Index_Of
    (Self : Q_String_List'Class;
     Rx : Qt4.Reg_Exps.Q_Reg_Exp'Class;
     From : Qt4.Q_Integer
       := 0)
       return Qt4.Q_Integer;

   function Join
    (Self : Q_String_List'Class;
     Sep : Q_String'Class)
       return Q_String;

   function Last_Index_Of
    (Self : Q_String_List'Class;
     Rx : Qt4.Reg_Exps.Q_Reg_Exp'Class;
     From : Qt4.Q_Integer
       := -1)
       return Qt4.Q_Integer;

   procedure Replace_In_Strings
    (Self : in out Q_String_List'Class;
     Before : Q_String'Class;
     After : Q_String'Class;
     Cs : Qt4.Case_Sensitivity
       := Case_Sensitive);

   procedure Replace_In_Strings
    (Self : in out Q_String_List'Class;
     Rx : Qt4.Reg_Exps.Q_Reg_Exp'Class;
     After : Q_String'Class);

   procedure Sort
    (Self : in out Q_String_List'Class);

   procedure Remove_First
    (Self : in out Q_String_List'Class);

   procedure Remove_Last
    (Self : in out Q_String_List'Class);

   function "="
    (Self : Q_String_List;
     L : Q_String_List)
       return Boolean;

   procedure Append
    (Self : in out Q_String'Class;
     S : Q_String'Class);

   procedure Append
    (Self : in out Q_String'Class;
     C : Q_Char'Class);

   function Character_At
    (Self : Q_String'Class;
     I : Qt4.Q_Integer)
       return Q_Char;

   function Capacity
    (Self : Q_String'Class)
       return Qt4.Q_Integer;

   procedure Chop
    (Self : in out Q_String'Class;
     N : Qt4.Q_Integer);

   procedure Clear
    (Self : in out Q_String'Class);

   function Compare
    (Self : Q_String'Class;
     S : Q_String'Class)
       return Qt4.Q_Integer;

   function Compare
    (Self : Q_String'Class;
     S : Q_String'Class;
     Cs : Qt4.Case_Sensitivity)
       return Qt4.Q_Integer;

   function Contains
    (Self : Q_String'Class;
     S : Q_String'Class;
     Cs : Qt4.Case_Sensitivity
       := Case_Sensitive)
       return Boolean;

   function Contains
    (Self : Q_String'Class;
     C : Q_Char'Class;
     Cs : Qt4.Case_Sensitivity
       := Case_Sensitive)
       return Boolean;

   function Contains
    (Self : Q_String'Class;
     S : Qt4.Reg_Exps.Q_Reg_Exp'Class)
       return Boolean;

   function Count
    (Self : Q_String'Class;
     S : Q_String'Class;
     Cs : Qt4.Case_Sensitivity
       := Case_Sensitive)
       return Qt4.Q_Integer;

   function Count
    (Self : Q_String'Class;
     C : Q_Char'Class;
     Cs : Qt4.Case_Sensitivity
       := Case_Sensitive)
       return Qt4.Q_Integer;

   function Count
    (Self : Q_String'Class;
     S : Qt4.Reg_Exps.Q_Reg_Exp'Class)
       return Qt4.Q_Integer;

   function Count
    (Self : Q_String'Class)
       return Qt4.Q_Integer;

   function Ends_With
    (Self : Q_String'Class;
     S : Q_String'Class;
     Cs : Qt4.Case_Sensitivity
       := Case_Sensitive)
       return Boolean;

   function Ends_With
    (Self : Q_String'Class;
     C : Q_Char'Class;
     Cs : Qt4.Case_Sensitivity
       := Case_Sensitive)
       return Boolean;

   procedure Fill
    (Self : in out Q_String'Class;
     C : Q_Char'Class;
     Size : Qt4.Q_Integer
       := -1);

   function Index_Of
    (Self : Q_String'Class;
     S : Q_String'Class;
     From : Qt4.Q_Integer
       := 0;
     Cs : Qt4.Case_Sensitivity
       := Case_Sensitive)
       return Qt4.Q_Integer;

   function Index_Of
    (Self : Q_String'Class;
     C : Q_Char'Class;
     From : Qt4.Q_Integer
       := 0;
     Cs : Qt4.Case_Sensitivity
       := Case_Sensitive)
       return Qt4.Q_Integer;

   function Index_Of
    (Self : Q_String'Class;
     Rx : Qt4.Reg_Exps.Q_Reg_Exp'Class;
     From : Qt4.Q_Integer
       := 0)
       return Qt4.Q_Integer;

   procedure Insert
    (Self : in out Q_String'Class;
     I : Qt4.Q_Integer;
     S : Q_String'Class);

   procedure Insert
    (Self : in out Q_String'Class;
     I : Qt4.Q_Integer;
     C : Q_Char'Class);

   function Is_Empty
    (Self : Q_String'Class)
       return Boolean;

   function Is_Null
    (Self : Q_String'Class)
       return Boolean;

   function Last_Index_Of
    (Self : Q_String'Class;
     S : Q_String'Class;
     From : Qt4.Q_Integer
       := -1;
     Cs : Qt4.Case_Sensitivity
       := Case_Sensitive)
       return Qt4.Q_Integer;

   function Last_Index_Of
    (Self : Q_String'Class;
     C : Q_Char'Class;
     From : Qt4.Q_Integer
       := -1;
     Cs : Qt4.Case_Sensitivity
       := Case_Sensitive)
       return Qt4.Q_Integer;

   function Last_Index_Of
    (Self : Q_String'Class;
     Rx : Qt4.Reg_Exps.Q_Reg_Exp'Class;
     From : Qt4.Q_Integer
       := -1)
       return Qt4.Q_Integer;

   function Left
    (Self : Q_String'Class;
     N : Qt4.Q_Integer)
       return Q_String;

   function Left_Justified
    (Self : Q_String'Class;
     Width : Qt4.Q_Integer;
     Fill : Q_Char'Class;
     Trunc : Boolean
       := False)
       return Q_String;

   function Length
    (Self : Q_String'Class)
       return Qt4.Q_Integer;

   function Locale_Aware_Compare
    (Self : Q_String'Class;
     S : Q_String'Class)
       return Qt4.Q_Integer;

   function Mid
    (Self : Q_String'Class;
     Position : Qt4.Q_Integer;
     N : Qt4.Q_Integer
       := -1)
       return Q_String;

   function Normalized
    (Self : Q_String'Class;
     Mode : Normalization_Form)
       return Q_String;

   function Normalized
    (Self : Q_String'Class;
     Mode : Normalization_Form;
     Version : Character_Unicode_Version)
       return Q_String;

   procedure Prepend
    (Self : in out Q_String'Class;
     S : Q_String'Class);

   procedure Prepend
    (Self : in out Q_String'Class;
     C : Q_Char'Class);

   procedure Remove
    (Self : in out Q_String'Class;
     I : Qt4.Q_Integer;
     Len : Qt4.Q_Integer);

   procedure Remove
    (Self : in out Q_String'Class;
     S : Q_String'Class;
     Cs : Qt4.Case_Sensitivity
       := Case_Sensitive);

   procedure Remove
    (Self : in out Q_String'Class;
     C : Q_Char'Class;
     Cs : Qt4.Case_Sensitivity
       := Case_Sensitive);

   procedure Remove
    (Self : in out Q_String'Class;
     S : Qt4.Reg_Exps.Q_Reg_Exp'Class);

   procedure Replace
    (Self : in out Q_String'Class;
     I : Qt4.Q_Integer;
     Len : Qt4.Q_Integer;
     After : Q_String'Class);

   procedure Replace
    (Self : in out Q_String'Class;
     I : Qt4.Q_Integer;
     Len : Qt4.Q_Integer;
     After : Q_Char'Class);

   procedure Replace
    (Self : in out Q_String'Class;
     Before : Q_String'Class;
     After : Q_String'Class;
     Cs : Qt4.Case_Sensitivity
       := Case_Sensitive);

   procedure Replace
    (Self : in out Q_String'Class;
     Ch : Q_Char'Class;
     After : Q_String'Class;
     Cs : Qt4.Case_Sensitivity
       := Case_Sensitive);

   procedure Replace
    (Self : in out Q_String'Class;
     Before : Q_Char'Class;
     After : Q_Char'Class;
     Cs : Qt4.Case_Sensitivity
       := Case_Sensitive);

   procedure Replace
    (Self : in out Q_String'Class;
     Rx : Qt4.Reg_Exps.Q_Reg_Exp'Class;
     After : Q_String'Class);

   procedure Reserve
    (Self : in out Q_String'Class;
     Size : Qt4.Q_Integer);

   procedure Resize
    (Self : in out Q_String'Class;
     Size : Qt4.Q_Integer);

   function Right
    (Self : Q_String'Class;
     N : Qt4.Q_Integer)
       return Q_String;

   function Right_Justified
    (Self : Q_String'Class;
     Width : Qt4.Q_Integer;
     Fill : Q_Char'Class;
     Trunc : Boolean
       := False)
       return Q_String;

   function Simplified
    (Self : Q_String'Class)
       return Q_String;

   function Size
    (Self : Q_String'Class)
       return Qt4.Q_Integer;

   function Split
    (Self : Q_String'Class;
     Sep : Q_String'Class;
     Behavior : Split_Behavior
       := Keep_Empty_Parts;
     Cs : Qt4.Case_Sensitivity
       := Case_Sensitive)
       return Q_String_List;

   function Split
    (Self : Q_String'Class;
     Sep : Q_Char'Class;
     Behavior : Split_Behavior
       := Keep_Empty_Parts;
     Cs : Qt4.Case_Sensitivity
       := Case_Sensitive)
       return Q_String_List;

   function Split
    (Self : Q_String'Class;
     Sep : Qt4.Reg_Exps.Q_Reg_Exp'Class;
     Behavior : Split_Behavior
       := Keep_Empty_Parts)
       return Q_String_List;

   procedure Squeeze
    (Self : in out Q_String'Class);

   function Starts_With
    (Self : Q_String'Class;
     S : Q_String'Class;
     Cs : Qt4.Case_Sensitivity
       := Case_Sensitive)
       return Boolean;

   function Starts_With
    (Self : Q_String'Class;
     S : Q_Char'Class;
     Cs : Qt4.Case_Sensitivity
       := Case_Sensitive)
       return Boolean;

   function To_Case_Folded
    (Self : Q_String'Class)
       return Q_String;

   function To_Latin_1
    (Self : Q_String'Class)
       return Qt4.Byte_Arrays.Q_Byte_Array;

   function To_Local_8_Bit
    (Self : Q_String'Class)
       return Qt4.Byte_Arrays.Q_Byte_Array;

   function To_Lower
    (Self : Q_String'Class)
       return Q_String;

   function To_Upper
    (Self : Q_String'Class)
       return Q_String;

   function To_Utf_8
    (Self : Q_String'Class)
       return Qt4.Byte_Arrays.Q_Byte_Array;

   function Trimmed
    (Self : Q_String'Class)
       return Q_String;

   procedure Truncate
    (Self : in out Q_String'Class;
     Size : Qt4.Q_Integer);

   function "="
    (Self : Q_String;
     S : Q_String)
       return Boolean;

   function "<"
    (Self : Q_String;
     S : Q_String)
       return Boolean;

   function ">"
    (Self : Q_String;
     S : Q_String)
       return Boolean;

   function "<="
    (Self : Q_String;
     S : Q_String)
       return Boolean;

   function ">="
    (Self : Q_String;
     S : Q_String)
       return Boolean;

   function From_Utf_8
    (Str : String)
       return Q_String;

   function From_Utf_16
    (Str : Wide_String)
       return Q_String;

   function From_Ucs_4
    (Str : Wide_Wide_String)
       return Q_String;

   function From_Local_8_Bit
    (Str : String)
       return Q_String;

   function To_Utf_8
    (Self : Q_String'Class)
       return String;

   function To_Utf_16
    (Self : Q_String'Class)
       return Wide_String;

   function To_Ucs_4
    (Self : Q_String'Class)
       return Wide_Wide_String;

   function To_Local_8_Bit
    (Self : Q_String'Class)
       return String;

   function "&"
    (Left : Q_String'Class;
     Right : Q_String'Class)
       return Q_String;

   package Internals is

      type QChar is private;

      type QChar_Access is access all QChar;
      pragma Convention (C, QChar_Access);

      function QChar_View
       (Item : Q_Char'Class)
          return QChar_Access;
      pragma Inline (QChar_View);

      function To_Pointer
       (Address : System.Address)
          return QChar_Access;
      pragma Inline (To_Pointer);

      function To_Address
       (Pointer : QChar_Access)
          return System.Address;
      pragma Inline (To_Address);

      function Create_Wrapper
       (Item : Internals.QChar_Access)
          return Q_Char;

      type QStringList is private;

      type QStringList_Access is access all QStringList;
      pragma Convention (C, QStringList_Access);

      function QStringList_View
       (Item : Q_String_List'Class)
          return QStringList_Access;
      pragma Inline (QStringList_View);

      function To_Pointer
       (Address : System.Address)
          return QStringList_Access;
      pragma Inline (To_Pointer);

      function To_Address
       (Pointer : QStringList_Access)
          return System.Address;
      pragma Inline (To_Address);

      function Create_Wrapper
       (Item : Internals.QStringList_Access)
          return Q_String_List;

      type QString is private;

      type QString_Access is access all QString;
      pragma Convention (C, QString_Access);

      function QString_View
       (Item : Q_String'Class)
          return QString_Access;
      pragma Inline (QString_View);

      function To_Pointer
       (Address : System.Address)
          return QString_Access;
      pragma Inline (To_Pointer);

      function To_Address
       (Pointer : QString_Access)
          return System.Address;
      pragma Inline (To_Address);

      function Create_Wrapper
       (Item : Internals.QString_Access)
          return Q_String;

   private

      type QChar is record
         Placeholder : Interfaces.C.char_array (1 .. Qt_Ada.Internals.Value_Class_Sizes.QChar_C_Size_Of);
      end record;
      pragma Convention (C, QChar);

      type QString is record
         Placeholder : Interfaces.C.char_array (1 .. Qt_Ada.Internals.Value_Class_Sizes.QString_C_Size_Of);
      end record;
      pragma Convention (C, QString);

      type QStringList is record
         Placeholder : Interfaces.C.char_array (1 .. Qt_Ada.Internals.Value_Class_Sizes.QStringList_C_Size_Of);
      end record;
      pragma Convention (C, QStringList);

   end Internals;

   package Thin is

      function copy_QString (Cpp_Object : not null access Internals.QString)
        return not null access Internals.QString;
      pragma Import (C, copy_QString, "__Qt4Ada_copy_QString");

      function copy_QStringList
       (Cpp_Object : not null access Internals.QStringList)
          return not null access Internals.QStringList;
      pragma Import (C, copy_QStringList, "__Qt4Ada_copy_QStringList");

   end Thin;

private

   type Q_Char is new Ada.Finalization.Controlled with record
      Storage : aliased Internals.QChar;
      Object  : Internals.QChar_Access := null;
      Wrapper : Boolean := False;
   end record;

   overriding
   procedure Adjust (Self : in out Q_Char);

   overriding
   procedure Finalize (Self : in out Q_Char);

   overriding
   procedure Initialize (Self : in out Q_Char);

   type Q_String_List is new Ada.Finalization.Controlled with record
      Storage : aliased Internals.QStringList;
      Object  : Internals.QStringList_Access := null;
      Wrapper : Boolean := False;
   end record;

   overriding
   procedure Adjust (Self : in out Q_String_List);

   overriding
   procedure Finalize (Self : in out Q_String_List);

   overriding
   procedure Initialize (Self : in out Q_String_List);

   type Q_String is new Ada.Finalization.Controlled with record
      Storage : aliased Internals.QString;
      Object  : Internals.QString_Access := null;
      Wrapper : Boolean := False;
   end record;

   overriding
   procedure Adjust (Self : in out Q_String);

   overriding
   procedure Finalize (Self : in out Q_String);

   overriding
   procedure Initialize (Self : in out Q_String);

end Qt4.Strings;
