This file is indexed.

/usr/include/ITK-4.12/itkVariableLengthVector.h is in libinsighttoolkit4-dev 4.12.2-dfsg1-1ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/
#ifndef itkVariableLengthVector_h
#define itkVariableLengthVector_h

#include <cassert>
#include <algorithm>
#include "itkNumericTraits.h"
#include "itkStaticAssert.h"
#include "itkMetaProgrammingLibrary.h"
#include "itkEnableIf.h"
#include "itkIsBaseOf.h"
#include "itkIsNumber.h"
#include "itkPromoteType.h"
#include "itkBinaryOperationConcept.h"

namespace itk
{

template <typename TExpr1, typename TExpr2, typename  TBinaryOp>
struct VariableLengthVectorExpression;

/** \class VariableLengthVector
 * \brief Represents an array whose length can be defined at run-time.
 *
 * This class is templated over the data type. This data-type is meant
 * to be a scalar, such as float, double etc...
 *
 * \note
 * ITK itself provides several classes that can serve as \c Arrays.
 * \li FixedArray - Compile time fixed length arrays that's intended to
 * represent an enumerated collection of \c n entities.
 *
 * \li Array - Run time resizeable array that is intended to hold a
 * collection of \c n entities
 *
 * \li Vector - Compile time fixed length array that is intended to hold
 * a collection of \c n data types. A vector usually has a mathematical meaning.
 * It should only be used when mathematical operations such as addition,
 * multiplication by a scalar, product etc make sense.
 *
 * \li VariableLengthVector - Run time array that is intended to hold a collection
 * of scalar data types. Again, it should be used only when mathematical
 * operations on it are relevant. If not, use an Array.
 *
 * \li Point - Represents the spatial coordinates of a spatial location. Operators
 * on Point reflect geometrical concepts.
 *
 * \par For the reasons listed above, you cannot instantiate
 * \code VariableLengthVector< bool > \endcode.
 *
 * \par
 * Design Considerations: We do not derive from \c vnl_vector to avoid being
 * limited by the explicit template instantiations of vnl_vector and other
 * hacks that vnl folks have been forced to use.
 *
 * \note
 * This work is part of the National Alliance for Medical Image Computing
 * (NAMIC), funded by the National Institutes of Health through the NIH Roadmap
 * for Medical Research, Grant U54 EB005149.
 *
 * \sa CovariantVector
 * \sa SymmetricSecondRankTensor
 * \sa RGBPixel
 * \sa DiffusionTensor3D
 * \ingroup DataRepresentation
 * \ingroup ITKCommon
 *
 * \wiki
 * \wikiexample{SimpleOperations/VariableLengthVector,Variable length vector}
 * \endwiki
 *
 * \invariant If \c m_LetArrayManageMemory is true, \c m_Data is deletable
 * (whether it's null or pointing to something with no elements. i.e. \c
 * m_NumElements may be 0 and yet \c m_Data may be not null.)
 */
template< typename TValue >
class ITK_TEMPLATE_EXPORT VariableLengthVector
{
public:
  /**\name Policies
   * The following Policies will be used by \c itk::VariableLengthVector::SetSize
   */
  //@{
  /** \c VariableLengthVector empty base-class for allocation policies.
   * All Allocation Policies are expected to inherit from this empty base
   * class.
   *
   * \sa \c itk::VariableLengthVector::SetSize
   * \sa \c NeverReallocate
   * \sa \c ShrinkToFit
   * \sa \c DontShrinkToFit
   * \ingroup ITKCommon
   * \ingroup DataRepresentation
   */
  struct AllocateRootPolicy {};

  /** \c VariableLengthVector Allocation Policy: Always reallocate memory.
   * This policy, when used from \c VariableLengthVector::SetSize(), always
   * implies that the previous internal buffer will be reallocated. Even if
   * enough memory was available.
   * \return true (always)
   *
   * \sa \c itk::VariableLengthVector::SetSize
   * \sa \c NeverReallocate
   * \sa \c ShrinkToFit
   * \sa \c DontShrinkToFit
   * \ingroup ITKCommon
   * \ingroup DataRepresentation
   */
  struct AlwaysReallocate : AllocateRootPolicy
    {
    bool operator()(unsigned int itkNotUsed(newSize), unsigned int itkNotUsed(oldSize)) const ITK_NOEXCEPT
      {
      return true;
      }
    };

  /** \c VariableLengthVector Allocation Policy: Never reallocate memory.
   * This policy, when used from \c VariableLengthVector::SetSize(), always
   * implies that the previous internal buffer will be kept. Even if not enough
   * memory was available.
   *
   * The typical use case of this policy is to make sure a \c
   * VariableLengthVector is not a proxy object.
   * \return false (always)
   *
   * \pre <tt>oldSize == newSize</tt>, checked by assertion
   *
   * \sa \c itk::VariableLengthVector::SetSize
   * \sa \c AlwaysReallocate
   * \sa \c ShrinkToFit
   * \sa \c DontShrinkToFit
   * \ingroup ITKCommon
   * \ingroup DataRepresentation
   */
  struct NeverReallocate : AllocateRootPolicy
    {
    bool operator()(unsigned int newSize, unsigned int oldSize) const ITK_NOEXCEPT
      {
      (void) newSize;
      (void) oldSize;
      itkAssertInDebugAndIgnoreInReleaseMacro(newSize == oldSize && "SetSize is expected to never change the VariableLengthVector size...");
      return true;
      }
    };

  /** \c VariableLengthVector Allocation Policy: reallocate memory only when
   * size changes.
   * This policy, when used from \c VariableLengthVector::SetSize(), will
   * reallocate the internal buffer only if the size of the \c
   * VariableLengthVector changes.
   * \return whether \c newSize differs from \c oldSize
   *
   * \note The name is related to \c DontShrinkToFit reallocation policy that
   * will avoid reallocating when enough memory has already been allocated.
   *
   * \sa \c itk::VariableLengthVector::SetSize
   * \sa \c AlwaysReallocate
   * \sa \c NeverReallocate
   * \sa \c DontShrinkToFit
   * \ingroup ITKCommon
   * \ingroup DataRepresentation
   */
  struct ShrinkToFit : AllocateRootPolicy
    {
    bool operator()(unsigned int newSize, unsigned int oldSize) const ITK_NOEXCEPT
      { return newSize != oldSize; }
    };

  /** \c VariableLengthVector Allocation Policy: reallocate memory only when
   * size increases.
   * This policy, when used from \c VariableLengthVector::SetSize(), will
   * reallocate the internal buffer only if the new size requested for the \c
   * VariableLengthVector increases.
   * \return whether \c newSize is bigger than \c oldSize
   *
   * \warning Unlike classes like \c std::vector<>, \c VariableLengthVector has
   * no capacity concept: the size of the \c VariableLengthVector is its
   * capacity. However, this will help a class without capacity to emulate one.
   * The consequence is that reallocations will occur with scenarios such as
   * the following:
   \code
   VariableLengthVector<...> v;
   v.SetSize(42);
   v.SetSize(12); // no reallocation
   v.SetSize(42); // pointless reallocation (given this policy)
   \endcode
   *
   * \sa \c itk::VariableLengthVector::SetSize
   * \sa \c AlwaysReallocate
   * \sa \c NeverReallocate
   * \sa \c ShrinkToFit
   * \ingroup ITKCommon
   * \ingroup DataRepresentation
   */
  struct DontShrinkToFit : AllocateRootPolicy
    {
    bool operator()(unsigned int newSize, unsigned int oldSize) const ITK_NOEXCEPT
      { return newSize > oldSize; }
    };

  /** \c VariableLengthVector empty base-class for values Keeping policies.
   * All Values Keeping Policies are expected to inherit from this empty base
   * class.
   *
   * The preconditions common to all sub classes are:
   * \pre This policy is only meant to be executed in case of reallocation,
   * i.e. \c oldBuffer and \c newBuffer are expected to differ (unchecked).
   * \pre This presumes \c TValue assignment is a \c noexcept operation.
   * \pre \c newBuffer is not null (pre-conditions imposed by some
   * implementations of \c std::copy())
   * \pre `[oldBuffer, oldBuffer+oldSize)` is a valid range
   *
   * \sa \c itk::VariableLengthVector::SetSize
   * \sa \c KeepOldValues
   * \sa \c DumpOldValues
   * \ingroup ITKCommon
   * \ingroup DataRepresentation
   */
  struct KeepValuesRootPolicy {};

  /** \c VariableLengthVector Invariability Policy: Always keep old values.
   * This policy, when used from \c VariableLengthVector::SetSize(), always
   * copies <tt>min(newSize,oldSize)</tt> previous values from the previous
   * internal buffer to the new one
   *
   * \pre This policy is only meant to be executed in case of reallocation,
   * i.e. \c oldBuffer and \c newBuffer are expected to differ (unchecked).
   * \pre This presumes \c TValue assignment is a \c noexcept operation.
   * \pre \c newBuffer is not null (pre-conditions imposed by some
   * implementations of \c std::copy())
   * \pre `[oldBuffer, oldBuffer+oldSize)` is a valid range
   *
   * This behaviour mimics \c std::vector<>::resize() behaviour. However, it
   * makes to sense from \c VariableLengthVector::operator=()
   *
   * \sa \c itk::VariableLengthVector::SetSize
   * \sa \c KeepValuesRootPolicy
   * \sa \c DumpOldValues
   * \ingroup ITKCommon
   * \ingroup DataRepresentation
   */
  struct KeepOldValues : KeepValuesRootPolicy
    {
    template <typename TValue2>
      void operator()(
        unsigned int newSize, unsigned int oldSize,
        TValue2 * oldBuffer, TValue2 * newBuffer) const ITK_NOEXCEPT
        {
        itkAssertInDebugAndIgnoreInReleaseMacro(newBuffer);
        const std::size_t nb = std::min(newSize, oldSize);
        itkAssertInDebugAndIgnoreInReleaseMacro(nb == 0 || (nb > 0  && oldBuffer != ITK_NULLPTR));
        std::copy(oldBuffer, oldBuffer+nb, newBuffer);
        }
    };

  /** \c VariableLengthVector Invariability Policy: Never keep old values.
   * This policy, when used from \c VariableLengthVector::SetSize(), is a no-op.
   * It won't try to copy previous values from the previous internal buffer to
   * the new one.
   *
   * \pre This policy is only meant to be executed in case of reallocation,
   * i.e. \c oldBuffer and \c newBuffer are expected to differ (unchecked).
   *
   * This behaviour particularly fits \c VariableLengthVector::operator=()
   *
   * \sa \c itk::VariableLengthVector::SetSize
   * \sa \c KeepValuesRootPolicy
   * \sa \c DumpOldValues
   * \ingroup ITKCommon
   * \ingroup DataRepresentation
   */
  struct DumpOldValues : KeepValuesRootPolicy
    {
    template <typename TValue2>
      void operator()(
        unsigned int itkNotUsed(newSize), unsigned int itkNotUsed(oldSize),
        TValue2 * itkNotUsed(oldBuffer), TValue2 * itkNotUsed(newBuffer)) const ITK_NOEXCEPT
        {
        }
    };
  //@}


  /** The element type stored at each location in the Array. */
  typedef TValue                                        ValueType;
  typedef TValue                                        ComponentType;
  typedef typename NumericTraits< ValueType >::RealType RealValueType;
  typedef VariableLengthVector                          Self;

  /** Typedef used to indicate the number of elements in the vector */
  typedef unsigned int ElementIdentifier;

  /** Default constructor. It is created with an empty array
   *  it has to be allocated later by assignment, \c SetSize() or \c Reserve().
   * \post \c m_Data is null
   * \post \c m_NumElements is 0
   * \post \c m_LetArrayManageMemory is true
   */
  VariableLengthVector();

  /** Constructor with size.
   * Size can only be changed by assignment, \c SetSize() or \c Reserve().
   * \post \c m_Data is not null and points to an array of \c m_NumElements,
   * even if \c m_NumElements is 0
   * \post values are left uninitialized.
   * \post \c m_NumElements is \c dimension
   * \post \c m_LetArrayManageMemory is true
   */
  explicit VariableLengthVector(unsigned int dimension);

  /** Constructor that initializes array with contents from a user supplied
   * buffer.
   * The pointer to the buffer and the length is specified. By default, the
   * array does not manage the memory of the buffer. It merely points to that
   * location and it is the user's responsibility to delete it.
   * If \c LetArrayManageMemory is true, then this class will free the
   * memory when this object is destroyed.
   *
   * \post `m_Data == data`
   * \post values are left unmodified
   * \post `m_NumElements == sz`
   * \post `m_LetArrayManageMemory == LetArrayManageMemory`
   */
  VariableLengthVector(ValueType *data, unsigned int sz,
                       bool LetArrayManageMemory = false);

  /** Constructor that initializes array with contents from a user supplied
   * buffer.
   * The pointer to the buffer and the length is specified. By default, the
   * array does not manage the memory of the buffer. It merely points to that
   * location and it is the user's responsibility to delete it.
   * If \c LetArrayManageMemory is true, then this class will free the
   * memory when this object is destroyed.
   *
   * \warning This overload receives a non-modiable array, and yet it will let
   * the end-user try to modify it through \c VariableLengthVector interface.
   * Use this constructor with care as this may lead to undefined behaviour.
   * Prefer using `VariableLengthVector<const TValue>` instead of
   * `VariableLengthVector<TValue>` in case we which to use this constructor.
   *
   * \post `m_Data == data`
   * \post values are left unmodified
   * \post `m_NumElements == sz`
   * \post `m_LetArrayManageMemory == LetArrayManageMemory`
   */
  VariableLengthVector(const ValueType *data, unsigned int sz,
                       bool LetArrayManageMemory = false);

  /** Copy constructor. The reason why the copy constructor and the assignment
   * operator are templated is that it will allow implicit casts to be
   * performed. For instance:
   \code
   VariableLengthVector< int > vI;
   VariableLengthVector< float > vF( vI );
   or for instance vF = static_cast< VariableLengthVector< float > >( vI );
   \endcode
   * \note However that static casting in this way will imply the allocation of
   * a temporary \c VariableLengthVector. Prefer to directly use the assignment
   * converting operator in code where uses of \c static_cast<> would be
   * required.
   *
   * \post \c m_Data is not null and points to an array of \c m_NumElements,
   * if \c m_NumElements is 0, otherwise it's null.
   * \post values are left uninitialized.
   * \post \c m_NumElements is \c v.GetSize()
   * \post \c m_LetArrayManageMemory is true
   */
  template< typename T >
  VariableLengthVector(const VariableLengthVector< T > & v)
    {
    m_NumElements = v.Size();
    m_LetArrayManageMemory = true;
    if (m_NumElements != 0)
      {
      m_Data = this->AllocateElements(m_NumElements);
      itkAssertInDebugAndIgnoreInReleaseMacro(m_Data != ITK_NULLPTR);
      for ( ElementIdentifier i = 0; i < m_NumElements; ++i )
        {
        this->m_Data[i] = static_cast< ValueType >( v[i] );
        }
      }
    else
      {
      m_Data = ITK_NULLPTR;
      }
    }

  /** Copy constructor. Overrides the default non-templated copy constructor
   * that the compiler provides.
   * \post \c m_Data is not null and points to an array of \c m_NumElements,
   * if \c m_NumElements is 0, otherwise it's null.
   * \post values are left uninitialized.
   * \post \c m_NumElements is \c v.GetSize()
   * \post \c m_LetArrayManageMemory is true
   */
  VariableLengthVector(const VariableLengthVector< TValue > & v);

  /** Swaps two \c VariableLengthVector 's.
   * \pre Expects either none of the \c VariableLengthVector to act as a proxy,
   * or both, checked with an assertion.
   * \post \c *this and \c old contents are swapped.
   * \param[in,out] v  other \c VariableLengthVector to be swapped with.
   * \throw None
   * \sa \c itk::swap()
   */
  void Swap(Self & v) ITK_NOEXCEPT
    {
    itkAssertInDebugAndIgnoreInReleaseMacro(m_LetArrayManageMemory == v.m_LetArrayManageMemory);
    using std::swap;
    swap(v.m_Data       , m_Data);
    swap(v.m_NumElements, m_NumElements);
    }

#if defined(ITK_HAS_CXX11_RVREF)
  /** C++11 Move Constructor.
   * \post \c v is destructible and assignable.
   * \post `m_NumElements == 0`
   * \post `m_LetArrayManageMemory == true`
   * \post `m_Data == nullptr`
   * \post Built object contains old \c v data.
   */
  VariableLengthVector(Self && v) ITK_NOEXCEPT;

  /** C++11 Move assignement operator.
   * \pre \c v shall not be the same as the current object
   * \post \c v is destructible and assignable.
   * \post `m_NumElements == 0`
   * \post `m_LetArrayManageMemory == true`
   * \post `m_Data == nullptr`
   * \post Current object contains old \c v data.
   */
  Self & operator=(Self && v) ITK_NOEXCEPT;
#endif

  /** Constructor from an Expression Template vector.
   * \tparam TExpr1 Type of the left sub-expression
   * \tparam TExpr2 Type of the right sub-expression
   * \tparam TBinaryOp Binary Operation to apply to both sub-expressions.
   * \param[in] rhs Non evaluated Expression Template.
   *
   * Builds the new \c VariableLengthVector with an expression template. The
   * code loops over all components from the template expression, and evaluates
   * them on the fly to fill the content of the new vector.
   *
   * \post \c m_Data is not null and points to an array of \c m_NumElements,
   * even if \c m_NumElements is 0
   * \post `*this == rhs`
   * \post \c m_NumElements is \c rhs.GetSize()
   * \post \c m_LetArrayManageMemory is true
   */
  template <typename TExpr1, typename TExpr2, typename  TBinaryOp>
      VariableLengthVector(VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp> const& rhs);
  /** Assignment from an Expression Template vector.
   * \tparam TExpr1 Type of the left sub-expression
   * \tparam TExpr2 Type of the right sub-expression
   * \tparam TBinaryOp Binary Operation to apply to both sub-expressions.
   * \param[in] rhs Non evaluated Expression Template.
   *
   * Resets the new \c VariableLengthVector with an expression template. The
   * code loops over all components from the template expression, and evaluates
   * them on the fly to fill the content of the current vector.
   *
   * \post if called on a \c VariableLengthVector proxy, the referenced values
   * are left unchanged.
   * \post \c m_Data is not null and points to an array of \c m_NumElements,
   * if \c m_NumElements is not 0. \c m_Data may be null otherwise (an empty
   * vector is assigned into another empty vector)
   * \post \c m_LetArrayManageMemory is true
   * \post `GetSize() == rhs.GetSize()`
   * \post `*this == rhs`
   */
  template <typename TExpr1, typename TExpr2, typename  TBinaryOp>
  Self & operator=(VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp> const& rhs);

  /** Set the all the elements of the array to the specified value.
   * \pre This function may be called on empty vectors, it's a no-op.
   */
  void Fill(TValue const & v) ITK_NOEXCEPT;

  /** Converting assignment operator.
   * \note Ensures a <em>String Exception Guarantee</em>: resists to
   * self-assignment, and no changes are made if memory cannot be allocated to
   * hold the new elements. This presumes \c TValue assignment is a \c
   * noexcept operation.
   *
   * \post if called on a \c VariableLengthVector proxy, the referenced values
   * are left unchanged.
   * \post \c m_LetArrayManageMemory is true
   * \post <tt>GetSize() == v.GetSize()</tt>, modulo precision
   * \post <tt>*this == v</tt>
   */
  template< typename T >
  Self & operator=(const VariableLengthVector< T > & v)
    {
    // No self assignment test is done. Indeed:
    // - the operator already resists self assignment through a strong exception
    // guarantee
    // - the test becomes a pessimization as we never write
    //    VLV<const TValue> vcref(v.GetDataPointer(), v.GetSize());
    //    ...;
    //    v = vcref;
    ElementIdentifier const N = v.Size();
    this->SetSize( N, DontShrinkToFit(), DumpOldValues() );
    for ( ElementIdentifier i = 0; i < N; ++i )
      {
      this->m_Data[i] = static_cast< ValueType >( v[i] );
      }
    return *this;
  }

  /** Copy-Assignment operator.
   * \note Ensures a <em>String Exception Guarantee</em>: resists to
   * self-assignment, and no changes are made if memory cannot be allocated to
   * hold the new elements. This is expecting \c TValue assignment is a \c
   * noexcept operation.
   *
   * \post if called on a \c VariableLengthVector proxy, the referenced values
   * are left unchanged.
   * \post \c m_Data is not null and points to an array of \c m_NumElements,
   * if \c m_NumElements is not 0. \c m_Data may be null otherwise (an empty
   * vector is assigned into another empty vector)
   * \post \c m_LetArrayManageMemory is true
   * \post <tt>GetSize() == v.GetSize()</tt>
   * \post <tt>*this == v</tt>
   */
  Self & operator=(const Self & v);

  /** Fast Assignment.
   * \pre \c m_LetArrayManageMemory is true: the \c VariableLengthVector is not
   * a proxy, checked with an assertion. Call <tt>SetSize(GetSize(), NeverReallocate(),
   * DumpOldValues())</tt> to ensure a vector is not a proxy anymore.
   * \pre current size is identical to the one from the right hand side
   * operand, checked with an assertion.
   * \pre Doesn't not support empty vectors.
   */
  Self & FastAssign(const Self & v) ITK_NOEXCEPT;

  /** Assignment operator from a numeric value.
   * \pre This assumes \c m_LetArrayManageMemory is true, but it is unchecked.
   * If this operator is called on a \c VariableLengthVector proxy, referenced
   * values will be overwritten.
   * \post Elements in `[m_Data, m_Data+GetSize())` will be equal to \c v, modulo
   * precision
   */
  Self & operator=(TValue const & v) ITK_NOEXCEPT;

  /** Return the number of elements in the Array  */
  unsigned int Size(void) const ITK_NOEXCEPT { return m_NumElements; }
  unsigned int GetSize(void) const ITK_NOEXCEPT { return m_NumElements; }
  unsigned int GetNumberOfElements(void) const ITK_NOEXCEPT { return m_NumElements; }

  /** Return reference to the element at specified index. No range checking. */
  TValue       & operator[](unsigned int i) ITK_NOEXCEPT { return this->m_Data[i]; }
  /** Return reference to the element at specified index. No range checking. */
  TValue const & operator[](unsigned int i) const ITK_NOEXCEPT { return this->m_Data[i]; }

  /** Get one element */
  const TValue & GetElement(unsigned int i) const ITK_NOEXCEPT { return m_Data[i]; }

  /** Set one element */
  void SetElement(unsigned int i, const TValue & value) ITK_NOEXCEPT { m_Data[i] = value; }

  /** Resizes the vector.
   * \tparam TReallocatePolicy Policy that determines precisely the conditions
   * under which the internal buffer shall be reallocated. It shall inherit
   * from \c AllocateRootPolicy.
   * \tparam TKeepValuesPolicy Policy that determines whether old elements
   * shall be kept. It shall inherit from \c KeepValuesRootPolicy.
   *
   * \internal
   * The purpose of this overload is to fine tune what \c SetSize() does. Some
   * users seem to need to always reallocate, or to maintain old elements.
   * However, some usages require fast resizing. In the assignment operators
   * cases, we don't need to reallocate anything if we have enough memory, and
   * we certainly do not need to maintain previous values as they'll get
   * overridden with new ones.
   * \internal
   * If we could assert that \c VariableLengthVector proxies would (shall!)
   * never be assigned anything, we could benefit from a version that won't
   * check \c m_LetArrayManageMemory.
   *
   * \pre `m_NumElements == sz` if \c TReallocatePolicy is \c NeverReallocate
   * \post `m_NumElements == sz`
   * \post \c m_LetArrayManageMemory is true
   * \post In case of reallocation, old \c m_Data buffer is deleted.
   * \post If \c TKeepValuesPolicy is \c KeepOldValues, old values are
   * garanteed to be kept, otherwise, it'll depend on the reallocation policy
   * and the old and new vector size.
   * \sa \c AlwaysReallocate
   * \sa \c NeverReallocate
   * \sa \c ShrinkToFit
   * \sa \c DontShrinkToFit
   * \sa \c KeepOldValues
   * \sa \c DumpOldValues
   */
  template <typename TReallocatePolicy, typename TKeepValuesPolicy>
  void SetSize(unsigned int sz,
          TReallocatePolicy reallocatePolicy,
          TKeepValuesPolicy keepValues);

  /** Set the size to that given.
   *
   * If \c destroyExistingData is \c false:
   * If the array already contains data, the existing data is copied over and
   * new space is allocated, if necessary. If the length to reserve is less
   * than the current number of elements, then an appropriate number of elements
   * are discarded.
   *    If \c true, the size is set destructively to the length given. If the
   * length is different from the current length, existing data will be lost.
   * The default is \c true. */
  void SetSize(unsigned int sz, bool destroyExistingData = true)
    {
    // Stays compatible with previous code version
    // And works around the fact C++03 template functions can't have default
    // arguments on template types.
    if (destroyExistingData)
      {
      SetSize(sz, AlwaysReallocate(), KeepOldValues());
      }
    else
      {
      SetSize(sz, ShrinkToFit(), KeepOldValues());
      }
    }

  /** Destroy data that is allocated internally, if \c LetArrayManageMemory is
   * true. */
  void DestroyExistingData() ITK_NOEXCEPT;

  /** Set the pointer from which the data is imported.
   * If "LetArrayManageMemory" is false, then the application retains
   * the responsibility of freeing the memory for this data.  If
   * "LetArrayManageMemory" is true, then this class will free the
   * memory when this object is destroyed.
   * \warning The size of the new \c data shall match vector current size.
   * Prefer the other overload.
   * \post old \c m_Data is deleted iff \c m_LetArrayManageMemory is true
   * \post `m_Data == data`
   * \post `m_LetArrayManageMemory ==LetArrayManageMemory`
   * \post \c Size() is left unmodified.
   */
  void SetData(TValue *data, bool LetArrayManageMemory = false) ITK_NOEXCEPT;

  /** Similar to the previous method. In the above method, the size must be
   * separately set prior to using user-supplied data. This introduces an
   * unnecessary allocation step to be performed. This method avoids it
   * and should be used to import data wherever possible to avoid this.
   * Set the pointer from which the data is imported.
   * If "LetArrayManageMemory" is false, then the application retains
   * the responsibility of freeing the memory for this data.  If
   * "LetArrayManageMemory" is true, then this class will free the
   * memory when this object is destroyed.
   * \post old \c m_Data is deleted iff \c m_LetArrayManageMemory is true
   * \post `m_Data == data`
   * \post `m_LetArrayManageMemory ==LetArrayManageMemory`
   * \post `m_NumElements == sz`
   */
  void SetData(TValue *data, unsigned int sz, bool LetArrayManageMemory = false) ITK_NOEXCEPT;

  /** This destructor is not virtual for performance reasons. However, this
   * means that subclasses cannot allocate memory.
   *
   * \internal
   * More precisally, this class has value semantics (copiable, assignable,
   * comparable). It's hardly compatible with public inheritance: slicing would
   * always be there somewhere to annoy us if we try to inherit publicaly from
   * such a class.
   * As a consequence, having the destructor virtual makes hardly any sense.
   */
  ~VariableLengthVector();

  /** Reserves memory of a certain length.
   *
   * If the array already contains data, the existing data is copied over and
   * new space is allocated, if necessary. If the length to reserve is less
   * than the current number of elements, then an appropriate number of elements
   * are discarded.
   * \post \c m_Data is not null and can hold \c size elements.
   * \post \c m_LetArrayManageMemory may be left unchanged if there already are
   * enough elements.
   *
   * \note You may prefer instead
   * `SetSize(N, DontShrinkToFit(), KeepOldValues());` that ensures that the
   * array is not a proxy at the end of the operation.
   */
  void Reserve(ElementIdentifier size);

  /** Allocate memory of certain size and return it.
   * \return a non-null pointer to an array of \c size elements (0 is a valid
   * parameter).
   */
  TValue * AllocateElements(ElementIdentifier size) const;

  const TValue * GetDataPointer() const ITK_NOEXCEPT { return m_Data; }

  /** Prefix operator that subtracts 1 from each element of the
   * vector. */
  Self & operator--() ITK_NOEXCEPT
    {
    for ( ElementIdentifier i = 0; i < m_NumElements; i++ )
      {
      this->m_Data[i] -= static_cast< ValueType >( 1.0 );
      }
    return *this;
    }

  /** Prefix operator that adds 1 to each element of the vector. */
  Self & operator++() ITK_NOEXCEPT // prefix operator ++v;
    {
    for ( ElementIdentifier i = 0; i < m_NumElements; i++ )
      {
      this->m_Data[i] += static_cast< ValueType >( 1.0 );
      }
    return *this;
    }

  /** Postfix operator that subtracts 1 from each element of the
   * vector. */
  Self operator--(int) // postfix operator v--;
    {
    Self tmp(*this);

    --tmp;
    return tmp;
    }

  /** Postfix operator that adds 1 to each element of the vector. */
  Self operator++(int) // postfix operator v++;
    {
    Self tmp(*this);

    ++tmp;
    return tmp;
    }

  /** Element-wise subtraction of vector 'v' from the current
   * vector. The vectors do not have to have the same element
   * type. The input vector elements are cast to the current vector
   * element type before the subtraction is performed.
   *
   * \throw None
   * \note For efficiency, the length of the vectors is not checked;
   * they are assumed to have the same length. */
  template< typename T >
  Self & operator-=
    (const VariableLengthVector< T > & v) ITK_NOEXCEPT
    {
    itkAssertInDebugAndIgnoreInReleaseMacro( m_NumElements == v.GetSize() );
    for ( ElementIdentifier i = 0; i < m_NumElements; i++ )
      {
      m_Data[i] -= static_cast< ValueType >( v[i] );
      }
    return *this;
    }

  /** Subtract scalar 's' from each element of the current vector. */
  Self & operator-=(TValue s) ITK_NOEXCEPT
    {
    for ( ElementIdentifier i = 0; i < m_NumElements; i++ )
      {
      m_Data[i] -= s;
      }
    return *this;
    }

  /** Element-wise addition of vector 'v' to the current vector. The
   * vectors do not have to have the same element type. The input
   * vector elements are cast to the current vector element type
   * before the addition is performed.
   *
   * \throw None
   * \note For efficiency, the length of the vectors is not checked;
   * they are assumed to have the same length. */
  template< typename T >
  Self & operator+=
    (const VariableLengthVector< T > & v) ITK_NOEXCEPT
    {
    itkAssertInDebugAndIgnoreInReleaseMacro( m_NumElements == v.GetSize() );
    for ( ElementIdentifier i = 0; i < m_NumElements; i++ )
      {
      m_Data[i] += static_cast< ValueType >( v[i] );
      }
    return *this;
    }

  /** Add scalar 's' to each element of the vector. */
  Self & operator+=(TValue s) ITK_NOEXCEPT
    {
    for ( ElementIdentifier i = 0; i < m_NumElements; i++ )
      {
      m_Data[i] += s;
      }
    return *this;
    }

  /** Compound addition operator with a expression template vector.
   * \tparam TExpr1 Type of the left sub-expression
   * \tparam TExpr2 Type of the right sub-expression
   * \tparam TBinaryOp Binary Operation to apply to both sub-expressions.
   * \param[in] rhs Non evaluated Expression Template.
   *
   * \pre `Size() == rhs.Size()`, checked with an assertion
   * \note The elements of the expression template are evaluated one by one.
   */
  template <typename TExpr1, typename TExpr2, typename TBinaryOp>
  Self& operator+=(VariableLengthVectorExpression<TExpr1,TExpr2,TBinaryOp> const& rhs) ITK_NOEXCEPT
    {
    itkAssertInDebugAndIgnoreInReleaseMacro(rhs.Size() == Size());
    for ( ElementIdentifier i = 0; i < m_NumElements; ++i )
      {
      m_Data[i] += static_cast<ValueType>(rhs[i]);
      }
    return *this;
    }

  /** Compound substraction operator with a expression template vector.
   * \tparam TExpr1 Type of the left sub-expression
   * \tparam TExpr2 Type of the right sub-expression
   * \tparam TBinaryOp Binary Operation to apply to both sub-expressions.
   * \param[in] rhs Non evaluated Expression Template.
   *
   * \pre `Size() == rhs.Size()`, checked with an assertion
   * \note The elements of the expression template are evaluated one by one.
   */
  template <typename TExpr1, typename TExpr2, typename TBinaryOp>
  Self& operator-=(VariableLengthVectorExpression<TExpr1,TExpr2,TBinaryOp> const& rhs) ITK_NOEXCEPT
    {
    itkAssertInDebugAndIgnoreInReleaseMacro(rhs.Size() == Size());
    for ( ElementIdentifier i = 0; i < m_NumElements; ++i )
      {
      m_Data[i] -= static_cast<ValueType>(rhs[i]);
      }
    return *this;
    }

  /** Multiply each element of the vector by a scalar 's'. The scalar
   * value is cast to the current vector element type prior to
   * multiplication.
   * \throw None
   */
  template< typename T >
  Self & operator*=(T s) ITK_NOEXCEPT
    {
    const ValueType & sc = static_cast<ValueType>(s);
    for ( ElementIdentifier i = 0; i < m_NumElements; i++ )
      {
      m_Data[i] *= sc;
      }
    return *this;
    }

  /** Multiply each element of the vector by a scalar 's'.
   * \throw None
   */
  Self & operator*=(TValue s) ITK_NOEXCEPT
    {
    for ( ElementIdentifier i = 0; i < m_NumElements; i++ )
      {
      m_Data[i] *= s;
      }
    return *this;
    }

  /** Divide vector elements by a scalar 's'. The vector does not
   * have to have the same element type as the scalar type. Both the
   * scalar and vector elements are cast to the RealValueType prior to
   * division, and the result is cast to the ValueType.
   * \throw None
   */
  template< typename T >
  Self & operator/=(T s) ITK_NOEXCEPT
    {
    const RealValueType sc = s;
    for ( ElementIdentifier i = 0; i < m_NumElements; i++ )
      {
      m_Data[i] = static_cast< ValueType >(
        static_cast< RealValueType >( m_Data[i] )
        / sc );
      }
    return *this;
    }

  /** Negates each vector element.
   * \warning This operator has a non standard semantics. Instead of returning
   * a new \c VariableLengthVector, it modifies the current object.
   */
  Self & operator-() ITK_NOEXCEPT;  // negation operator

  bool operator==(const Self & v) const ITK_NOEXCEPT;

  bool operator!=(const Self & v) const ITK_NOEXCEPT;

  /** Returns vector's Euclidean Norm  */
  RealValueType GetNorm() const ITK_NOEXCEPT;

  /** Returns vector's squared Euclidean Norm  */
  RealValueType GetSquaredNorm() const ITK_NOEXCEPT;

  /** letArrayManageMemory getter. */
  bool IsAProxy() const ITK_NOEXCEPT { return ! m_LetArrayManageMemory;}

private:
  bool              m_LetArrayManageMemory; // if true, the array is responsible
                                            // for memory of data
  TValue *          m_Data;                 // Array to hold data
  ElementIdentifier m_NumElements;
};

/// \cond HIDE_META_PROGRAMMING
namespace mpl {
/** Tells whether a type is an array type for which the support of arithmetic
 * operations is done with Expression Template.
 * \note For the moment, only \c itk::VariableLengthVector<> is supported. It
 * could be extented to other types of ITK arrays.
 * \ingroup MetaProgrammingLibrary
 * \ingroup ITKCommon
 * \sa \c VariableLengthVector
 * \sa \c VariableLengthVectorExpression
 */
template <typename T>
struct IsArray : FalseType {};

/// \cond SPECIALIZATION_IMPLEMENTATION
template <typename T>
struct IsArray<itk::VariableLengthVector<T> > : TrueType {};

template <typename TExpr1, typename TExpr2, typename TBinaryOp>
struct IsArray<VariableLengthVectorExpression<TExpr1, TExpr2,TBinaryOp> > : TrueType {};
/// \endcond
} // namespace mpl
/// \endcond

namespace Details
{
/// \cond HIDE_META_PROGRAMMING
/** Helper Trait for VLV expression template: returns the value type.
 * \tparam TExpr Expression type
 * \return \c Type The value type behind \c TExpr (\c TExpr in case of a
 * numerical type, \c TExpr::ValueType in case of the \c VariableLengthVector,
 * etc.)
 *
 * Also defines \c Load() that permits to fetch the i-th element in case of an
 * array, array expression, or just the number in case of a number.
 * \ingroup ITKCommon
 * \sa \c VariableLengthVector
 * \sa \c VariableLengthVectorExpression
 */
template <typename TExpr> struct GetType
  {
  typedef TExpr Type;
  /** Fetches the i-th element from an array (expression).
   * \note the default unspecialized behaviour returns the input number \c v.
   */
  static Type Load(Type const& v, unsigned int idx) ITK_NOEXCEPT
    { (void)idx; return v; }
  };

/** Helper function for VLV expression templates: returns the common size.
 * \param[in] lhs left hand side expression
 * \param[in] rhs right hand side expression
 * \note The default overload assumes both operands are \c VariableLengthVector
 * (or expression) arrays
 * \pre asserts both arrays have the same size.
 * \ingroup ITKCommon
 * \sa \c VariableLengthVector
 * \sa \c VariableLengthVectorExpression
 */
template <typename TExpr1, typename TExpr2>
inline
typename mpl::EnableIf<mpl::And<mpl::IsArray<TExpr1>, mpl::IsArray<TExpr2> >, unsigned int>::Type
GetSize(TExpr1 const& lhs, TExpr2 const& rhs) ITK_NOEXCEPT
  {
  (void)rhs;
  itkAssertInDebugAndIgnoreInReleaseMacro(lhs.Size() == rhs.Size());
  return lhs.Size();
  }

/// \cond SPECIALIZATION_IMPLEMENTATION
/** Helper function for VLV expression templates: returns the common size.
 * \param[in] lhs left hand side expression
 * \param[in] rhs right hand side expression
 * \note This overload assumes that only the first operand is a \c
 * VariableLengthVector (or expression) array.
 * \ingroup ITKCommon
 * \sa \c VariableLengthVector
 * \sa \c VariableLengthVectorExpression
 */
template <typename TExpr1, typename TExpr2>
inline
typename mpl::EnableIf<mpl::And<mpl::IsArray<TExpr1>, mpl::Not<mpl::IsArray<TExpr2> > >, unsigned int>::Type
GetSize(TExpr1 const& lhs, TExpr2 const& itkNotUsed(rhs)) ITK_NOEXCEPT
  {
  return lhs.Size();
  }

/** Helper function for VLV expression templates: returns the common size.
 * \param[in] lhs left hand side expression
 * \param[in] rhs right hand side expression
 * \note This overload assumes that only the second operand is a \c
 * VariableLengthVector (or expression) array.
 * \ingroup ITKCommon
 * \sa \c VariableLengthVector
 * \sa \c VariableLengthVectorExpression
 */
template <typename TExpr1, typename TExpr2>
inline
typename mpl::EnableIf<mpl::And<mpl::IsArray<TExpr2>, mpl::Not<mpl::IsArray<TExpr1> > >, unsigned int>::Type
GetSize(TExpr1 const& itkNotUsed(lhs), TExpr2 const& rhs) ITK_NOEXCEPT
  {
  return rhs.Size();
  }

template <typename T>
struct GetType<VariableLengthVector<T> >
  {
  typedef T Type;
  static Type Load(VariableLengthVector<T> const& v, unsigned int idx) ITK_NOEXCEPT
    { return v[idx]; }
  };
template <typename TExpr1, typename TExpr2, typename TBinaryOp>
struct GetType<VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp> >
  {
  typedef typename VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp>::ResType Type;
  static Type Load(VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp> const& v, unsigned int idx) ITK_NOEXCEPT
    { return v[idx]; }
  };
/// \endcond

namespace op
{
/** Tells whether objects from two types can be added or substracted.
 * The operation is authorized if and only if:
 * - both are arrays,
 * - or one operand is an array while the second is a number.
 * \note As this traits is dedicated to help overload binary operators, it
 * shall not be used to help overload `operator+()` between floats for instance.
 * Hence, the case where both operands are numbers is rejected.
 *
 * \sa \c mpl::IsArray<> to know the exact array types recognized as \em array by this traits
 * \ingroup MetaProgrammingLibrary
 * \ingroup ITKCommon
 */
template <typename TExpr1, typename TExpr2>
struct CanBeAddedOrSubstracted
: mpl::Or< mpl::And<mpl::IsArray<TExpr1>, mpl::IsArray<TExpr2> >,
            mpl::And<mpl::IsArray<TExpr1>, mpl::IsNumber<TExpr2> >,
            mpl::And<mpl::IsNumber<TExpr1>, mpl::IsArray<TExpr2> >
  >
{};

/** Tells whether objects from two types can be multiplied.
 * The operation is authorized if and only if:
 * - one operand is an array while the second is a number.
 * \note As this traits is dedicated to help overload `operator*()`, it
 * shall not be used to help overload the operator between floats for instance.
 * Hence, the case where both operands are numbers is rejected.
 *
 * \sa \c mpl::IsArray<> to know the exact array types recognized as \em array by this traits
 * \ingroup MetaProgrammingLibrary
 * \ingroup ITKCommon
 */
template <typename TExpr1, typename TExpr2>
struct CanBeMultiplied
: mpl::Or< mpl::And<mpl::IsArray<TExpr1>, mpl::IsNumber<TExpr2> >,
            mpl::And<mpl::IsNumber<TExpr1>, mpl::IsArray<TExpr2> >
  >
{};

/** Tells whether objects from two types can be multiplied.
 * The operation is authorized if and only if:
 * - the first operand is an array while the second is a number.
 * \note As this traits is dedicated to help overload `operator/()`, it
 * shall not be used to help overload the operator between floats for instance.
 * Hence, the case where both operands are numbers is rejected.
 *
 * \sa \c mpl::IsArray<> to know the exact array types recognized as \em array by this traits
 * \ingroup MetaProgrammingLibrary
 * \ingroup ITKCommon
 */
template <typename TExpr1, typename TExpr2>
struct CanBeDivided
: mpl::And<mpl::IsArray<TExpr1>, mpl::IsNumber<TExpr2> >
{};

} // op namespace
} // Details namespace
/// \endcond

/** Expression Template for \c VariableLengthVector.
 * Contains an expression template that models a binary operation between two
 * sub expressions (of type \c VariableLengthVector, or \c VariableLengthVectorExpression)
 * \tparam TExpr1 Type of the left sub-expression
 * \tparam TExpr2 Type of the right sub-expression
 * \tparam TBinaryOp Binary Operation to apply to both sub-expressions.
 *
 * \note We permit to add a `VariableLengthVector<float>` with a
 * `VariableLengthVector<double>`, the result will be of type
 * `VariableLengthVector<double>`.
 *
 * \warning Explicitly static casting an expression to a
 * \c VariableLengthVector<> will defeat the purpose of the optimization
 * implemented here. It's thus best to let the expression automatically adjust
 * to the type with the most precision.
 * Eventually, when assigning to the final destination (a
 * \c VariableLengthVector<>), a casting on-the-fly could be realized by the
 * assignment operator, or by the copy constructor.
 *
 * \todo Add support for unary operations like `operator-()`.
 *
 * \ingroup DataRepresentation
 * \ingroup ITKCommon
 */
template <typename TExpr1, typename TExpr2, typename TBinaryOp>
struct VariableLengthVectorExpression
{
  VariableLengthVectorExpression(TExpr1 const& lhs, TExpr2 const& rhs) ITK_NOEXCEPT
    : m_lhs(lhs), m_rhs(rhs)
    {
    // Not neccessary actually as end-user/developper is not expected to
    // provide new BinaryOperations
    itkStaticAssert(
      (itk::mpl::IsBaseOf<Details::op::BinaryOperationConcept, TBinaryOp>::Value),
      "The Binary Operation shall inherit from BinaryOperationConcept");
    }

  /// Returns the size of the vector expression.
  unsigned int Size() const ITK_NOEXCEPT{ return Details::GetSize(m_lhs, m_rhs); }

  /// Vector type of the Result Expression
  typedef typename mpl::PromoteType<
    typename Details::GetType<TExpr1>::Type,
    typename Details::GetType<TExpr2>::Type>::Type     ResType;
  /// Real type of the elements
  typedef typename NumericTraits< ResType > ::RealType RealValueType;

  /** Element access operator.
   * \pre `idx < Size()`
   * \internal
   * This is where the magic happens. Instead of building a new vector based on
   * the two input vectors, we compute each element on-the-fly when
   * requested(by a \c VariableLengthVector constructor or an assignment
   * operator).
   *
   * \c Load() is in charge of fetching the i-th element of the sub-expressions
   */
  ResType operator[](unsigned int idx) const ITK_NOEXCEPT
    {
    itkAssertInDebugAndIgnoreInReleaseMacro(idx < Size());
    return TBinaryOp::Apply(
      Details::GetType<TExpr1>::Load(m_lhs, idx),
      Details::GetType<TExpr2>::Load(m_rhs, idx));
    }

  /** Returns vector's Euclidean Norm  */
  RealValueType GetNorm() const ITK_NOEXCEPT;

  /** Returns vector's squared Euclidean Norm  */
  RealValueType GetSquaredNorm() const ITK_NOEXCEPT;

private:
  TExpr1 const& m_lhs;
  TExpr2 const& m_rhs;
};

/** Addition involving a \c VariableLengthVector.
 * This operation is generic and takes:
 * - two arrays,
 * - or one array and one number (on either side)
 * \return an expression template proxy object.
 * \throw None As no allocation will be performed.
 * \relates itk::VariableLengthVector
 * \sa \c mpl::IsArray<> to know the exact array types recognized as \em array by this traits
 */
template <typename TExpr1, typename TExpr2>
inline
typename mpl::EnableIf<Details::op::CanBeAddedOrSubstracted<TExpr1,TExpr2>, VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Plus> >::Type
operator+(TExpr1 const& lhs, TExpr2 const& rhs) ITK_NOEXCEPT
{ return VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Plus>(lhs, rhs); }

/** Substraction involving a \c VariableLengthVector.
 * This operation is generic and takes:
 * - two arrays,
 * - or one array and one number (on either side)
 * \return an expression template proxy object.
 * \throw None As no allocation will be performed.
 * \relates itk::VariableLengthVector
 * \sa \c mpl::IsArray<> to know the exact array types recognized as \em array by this traits
 */
template <typename TExpr1, typename TExpr2>
inline
typename mpl::EnableIf<Details::op::CanBeAddedOrSubstracted<TExpr1,TExpr2>, VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Sub> >::Type
operator-(TExpr1 const& lhs, TExpr2 const& rhs) ITK_NOEXCEPT
{ return VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Sub>(lhs, rhs); }

/** Multiplication between a \c VariableLengthVector and a scalar.
 * This operation is generic and takes one array and one number (on either
 * side).
 * \return an expression template proxy object.
 * \throw None As no allocation will be performed.
 * \relates itk::VariableLengthVector
 * \sa \c mpl::IsArray<> to know the exact array types recognized as \em array by this traits
 */
template <typename TExpr1, typename TExpr2>
inline
typename mpl::EnableIf<Details::op::CanBeMultiplied<TExpr1,TExpr2>, VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Mult> >::Type
operator*(TExpr1 const& lhs, TExpr2 const& rhs) ITK_NOEXCEPT
{ return VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Mult>(lhs, rhs); }

/** Division of a \c VariableLengthVector by a scalar.
 * This operation is generic and takes one array and one number.
 * \return an expression template proxy object.
 * \throw None As no allocation will be performed.
 * \relates itk::VariableLengthVector
 * \sa \c mpl::IsArray<> to know the exact array types recognized as \em array by this traits
 */
template <typename TExpr1, typename TExpr2>
inline
typename mpl::EnableIf<Details::op::CanBeDivided<TExpr1,TExpr2>, VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Div> >::Type
operator/(TExpr1 const& lhs, TExpr2 const& rhs) ITK_NOEXCEPT
{ return VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Div>(lhs, rhs); }

/** Serialization of \c VariableLengthVectorExpression
 * \relates itk::VariableLengthVectorExpression
 */
template <typename TExpr1, typename TExpr2, typename  TBinaryOp>
std::ostream & operator<<(std::ostream &os, VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp> const& v)
{
  os << "[";
  if (v.Size() != 0)
    {
    os << v[0];
    for (unsigned int i = 1, N = v.Size(); i != N; ++i)
      {
      os << ", " << v[i];
      }
    }
  return os << "]";
}

/** Returns vector's Euclidean Norm.
 * \tparam TExpr must be an array
 * \sa \c mpl::IsArray<> to know the exact array types recognized as \em array by this traits
 * \relates itk::VariableLengthVectorExpression
 */
template <typename TExpr>
inline
typename mpl::EnableIf<mpl::IsArray<TExpr>, typename TExpr::RealValueType>::Type
GetNorm(TExpr const& v) ITK_NOEXCEPT
{
  return static_cast<typename TExpr::RealValueType>(
    std::sqrt(static_cast<double>(GetSquaredNorm(v))));
}

/** Returns vector's squared Euclidean Norm.
 * \tparam TExpr must be an array
 * \sa \c mpl::IsArray<> to know the exact array types recognized as \em array by this traits
 * \relates itk::VariableLengthVectorExpression
 */
template <typename TExpr>
inline
typename mpl::EnableIf<mpl::IsArray<TExpr>, typename TExpr::RealValueType>::Type
GetSquaredNorm(TExpr const& v) ITK_NOEXCEPT
{
  typedef typename TExpr::RealValueType RealValueType;
  RealValueType sum = 0.0;
  for ( unsigned int i = 0, N=v.Size(); i < N; ++i )
    {
    const RealValueType value = v[i];
    sum += value * value;
    }
  return sum;
}

/**\name Serialization */
//@{
/** Serialization of \c VariableLengthVector
 * \relates itk::VariableLengthVector
 */
template< typename TValue >
std::ostream & operator<<(std::ostream & os, const VariableLengthVector< TValue > & arr)
{
  const unsigned int length = arr.Size();
  const signed int   last   = (unsigned int)length - 1;

  os << "[";
  for ( signed int i = 0; i < last; ++i )
    {
    os << arr[i] << ", ";
    }
  if ( length >= 1 )
    {
    os << arr[last];
    }
  os << "]";
  return os;
}
//@}

/**\name Standard compliance functions */
//@{
/** \c swap() overload for \c VariableLengthVector
 * \throw None
 * \relates itk::VariableLengthVector
 * \internal
 * This overload follows C++ standard naming convention. This is required to
 * permit \c VariableLengthVector to be exchanged by standard algorithms that
 * take advantage of Koening Namespace Lookup (a.k.a. Argument Dependant
 * Lookup). e.g.
 \code
 template <typename T> f(T & l, T & r)
 {
     using std::swap;
     swap(l,r);
     ...
 }
 * \endcode
 */
template <typename T>
inline
void swap(VariableLengthVector<T> &l_, VariableLengthVector<T> &r_) ITK_NOEXCEPT
{
  l_.Swap(r_);
}
//@}

} // namespace itk

#include "itkNumericTraitsVariableLengthVectorPixel.h"

#ifndef ITK_MANUAL_INSTANTIATION
#include "itkVariableLengthVector.hxx"
#endif

#endif