mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
COMP: tecio : move out of thirdparty
This commit is contained in:
@ -0,0 +1,696 @@
|
||||
/*
|
||||
* NOTICE and LICENSE for Tecplot Input/Output Library (TecIO) - OpenFOAM
|
||||
*
|
||||
* Copyright (C) 1988-2009 Tecplot, Inc. All rights reserved worldwide.
|
||||
*
|
||||
* Tecplot hereby grants OpenCFD limited authority to distribute without
|
||||
* alteration the source code to the Tecplot Input/Output library, known
|
||||
* as TecIO, as part of its distribution of OpenFOAM and the
|
||||
* OpenFOAM_to_Tecplot converter. Users of this converter are also hereby
|
||||
* granted access to the TecIO source code, and may redistribute it for the
|
||||
* purpose of maintaining the converter. However, no authority is granted
|
||||
* to alter the TecIO source code in any form or manner.
|
||||
*
|
||||
* This limited grant of distribution does not supersede Tecplot, Inc.'s
|
||||
* copyright in TecIO. Contact Tecplot, Inc. for further information.
|
||||
*
|
||||
* Tecplot, Inc.
|
||||
* 3535 Factoria Blvd, Ste. 550
|
||||
* Bellevue, WA 98006, USA
|
||||
* Phone: +1 425 653 1200
|
||||
* http://www.tecplot.com/
|
||||
*
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include "MASTER.h"
|
||||
#define TECPLOTENGINEMODULE
|
||||
|
||||
|
||||
/*
|
||||
*****************************************************************
|
||||
*****************************************************************
|
||||
******* ********
|
||||
****** Copyright (C) 1988-2008 Tecplot, Inc. *******
|
||||
******* ********
|
||||
*****************************************************************
|
||||
*****************************************************************
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#define SETMODULE
|
||||
#include "GLOBAL.h"
|
||||
#include "TASSERT.h"
|
||||
#include "Q_UNICODE.h"
|
||||
#include "ALLOC.h"
|
||||
#include "SET.h"
|
||||
|
||||
|
||||
/* * SET FUNCTIONS * */
|
||||
|
||||
#if defined TECPLOTKERNEL
|
||||
/* CORE SOURCE CODE REMOVED */
|
||||
#if InitNumZones > InitNumVars
|
||||
#else
|
||||
#endif
|
||||
#if ZoneExpansionFactor > VarExpansionFactor
|
||||
#else
|
||||
#endif
|
||||
#else
|
||||
#define SetInitSize (PadOut(1,SetBitSize))
|
||||
#define SetExpansionFactor 2
|
||||
#endif
|
||||
|
||||
using namespace tecplot::strutil;
|
||||
|
||||
/*
|
||||
*/
|
||||
Set_pa AllocSet(Boolean_t show_error_msg)
|
||||
{
|
||||
Set_pa Set = ALLOC_ITEM(struct _Set_a, "Set header");
|
||||
if (Set)
|
||||
{
|
||||
Set->size = SetInitSize;
|
||||
Set->data = ALLOC_ARRAY(SetInitSize / SetBitSize, SetData_t, "Set data");
|
||||
if (Set->data == NULL)
|
||||
DeallocSet(&Set);
|
||||
else
|
||||
ClearSet(Set);
|
||||
}
|
||||
if ((Set == NULL) && show_error_msg)
|
||||
{
|
||||
# if defined TECPLOTKERNEL
|
||||
/* CORE SOURCE CODE REMOVED */
|
||||
# else
|
||||
fprintf(stderr, "Out of memory for sets");
|
||||
# endif
|
||||
}
|
||||
return Set;
|
||||
} /* AllocSet() */
|
||||
|
||||
|
||||
/*
|
||||
*/
|
||||
void DeallocSet(Set_pa *Set)
|
||||
{
|
||||
if (Set && *Set)
|
||||
{
|
||||
if ((*Set)->data)
|
||||
FREE_ARRAY((*Set)->data, "Set data");
|
||||
FREE_ITEM(*Set, "Set header");
|
||||
*Set = NULL;
|
||||
}
|
||||
} /* DeallocSet() */
|
||||
|
||||
|
||||
/**
|
||||
* This function adapts the DeallocSet function to work with the
|
||||
* ArrayList's deallocation callback.
|
||||
*/
|
||||
Boolean_t SetItemDestructor(void *ItemRef,
|
||||
ArbParam_t ClientData)
|
||||
{
|
||||
Set_pa *SetRef = (Set_pa *)ItemRef;
|
||||
|
||||
REQUIRE(VALID_REF(SetRef));
|
||||
REQUIRE(VALID_REF(*SetRef) || *SetRef == NULL);
|
||||
|
||||
if (*SetRef != NULL)
|
||||
DeallocSet(SetRef);
|
||||
|
||||
ENSURE(*SetRef == NULL);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*/
|
||||
Boolean_t ExpandSet(Set_pa Set,
|
||||
SetIndex_t max_val,
|
||||
Boolean_t show_error_msg)
|
||||
{
|
||||
SetData_t *data;
|
||||
long new_size;
|
||||
|
||||
REQUIRE(max_val >= 0);
|
||||
|
||||
if (!Set)
|
||||
{
|
||||
if (show_error_msg)
|
||||
{
|
||||
# if defined TECPLOTKERNEL
|
||||
/* CORE SOURCE CODE REMOVED */
|
||||
# else
|
||||
fprintf(stderr, "Null Set expand");
|
||||
# endif
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (max_val <= Set->size)
|
||||
return TRUE;
|
||||
|
||||
new_size = Set->size;
|
||||
while (new_size < max_val)
|
||||
new_size *= SetExpansionFactor;
|
||||
|
||||
new_size = PadOut(new_size, SetBitSize);
|
||||
|
||||
data = ALLOC_ARRAY(new_size / SetBitSize, SetData_t, "new Set data");
|
||||
|
||||
if (!data)
|
||||
{
|
||||
if (show_error_msg)
|
||||
{
|
||||
# if defined TECPLOTKERNEL
|
||||
/* CORE SOURCE CODE REMOVED */
|
||||
# else
|
||||
fprintf(stderr, "Out of memory for sets");
|
||||
# endif
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
size_t old_set_size_in_bytes = sizeof(data[0]) * (Set->size / SetBitSize);
|
||||
memcpy(data, Set->data, old_set_size_in_bytes);
|
||||
|
||||
size_t new_set_size_in_bytes = sizeof(data[0]) * (new_size / SetBitSize);
|
||||
size_t numBytesToReset = new_set_size_in_bytes - old_set_size_in_bytes;
|
||||
memset(((char*)data) + old_set_size_in_bytes, 0, numBytesToReset);
|
||||
|
||||
FREE_ARRAY(Set->data, "old Set data");
|
||||
Set->data = data;
|
||||
Set->size = new_size;
|
||||
return TRUE;
|
||||
} /* ExpandSet() */
|
||||
|
||||
|
||||
/*
|
||||
*/
|
||||
Boolean_t CopySet(Set_pa dst,
|
||||
Set_pa src,
|
||||
Boolean_t show_error_msg)
|
||||
{
|
||||
if (dst && dst->data &&
|
||||
src && src->data &&
|
||||
ExpandSet(dst, src->size, show_error_msg))
|
||||
{
|
||||
SetIndex_t src_size_in_words = src->size / SetBitSize;
|
||||
size_t numBytesToCopy = sizeof(dst->data[0]) * src_size_in_words;
|
||||
memcpy(dst->data, src->data, numBytesToCopy);
|
||||
|
||||
SetIndex_t dst_size_in_words = dst->size / SetBitSize;
|
||||
CHECK(dst_size_in_words>=src_size_in_words); // ...guaranteed by above ExpandSet() call
|
||||
size_t numBytesToReset = sizeof(dst->data[0]) * (dst_size_in_words - src_size_in_words);
|
||||
memset((char*)(dst->data + src_size_in_words), 0, numBytesToReset);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
} /* CopySet() */
|
||||
|
||||
|
||||
/*
|
||||
*/
|
||||
Boolean_t AppendSet(Set_pa dst,
|
||||
Set_pa src,
|
||||
Boolean_t show_error_msg)
|
||||
{
|
||||
if (dst && dst->data &&
|
||||
src && src->data)
|
||||
{
|
||||
SetIndex_t member;
|
||||
ForAllMembersInSet(member, src)
|
||||
{
|
||||
if (!AddToSet(dst, member, TRUE))
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
} /* AppendSet() */
|
||||
|
||||
|
||||
/*
|
||||
*/
|
||||
void ClearSet(Set_pa Set)
|
||||
{
|
||||
if (Set && Set->data)
|
||||
memset(Set->data, 0, Set->size / SetBitSize * sizeof(Set->data[0]));
|
||||
} /* ClearSet() */
|
||||
|
||||
|
||||
#if defined USE_FUNCTIONS_FOR_SETS
|
||||
/*
|
||||
*/
|
||||
Boolean_t AddToSet(Set_pa Set,
|
||||
SetIndex_t member,
|
||||
Boolean_t show_error_msg)
|
||||
{
|
||||
REQUIRE(member >= 0);
|
||||
if (Set &&
|
||||
Set->data &&
|
||||
((member + 1 <= Set->size) || ExpandSet(Set, member + 1, show_error_msg)))
|
||||
{
|
||||
SetIndex_t word = member / SetBitSize;
|
||||
SetData_t bit = (SetData_t)1 << (member % SetBitSize);
|
||||
Set->data[word] |= bit;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
} /* AddToSet() */
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*/
|
||||
void RemoveFromSet(Set_pa Set,
|
||||
SetIndex_t member)
|
||||
{
|
||||
REQUIRE(member >= 0);
|
||||
if (Set && (member < Set->size) && Set->data)
|
||||
{
|
||||
SetIndex_t word = member / SetBitSize;
|
||||
SetData_t bit = (SetData_t)1 << (member % SetBitSize);
|
||||
Set->data[word] &= (((SetData_t) - 1) ^ bit);
|
||||
}
|
||||
} /* RemoveFromSet() */
|
||||
|
||||
|
||||
/**
|
||||
* Similar to RemoveFromSet except it shifts the Set.
|
||||
*/
|
||||
void DeleteSetMember(Set_pa Set,
|
||||
SetIndex_t Member)
|
||||
{
|
||||
SetIndex_t LastMember;
|
||||
|
||||
REQUIRE(VALID_REF(Set));
|
||||
REQUIRE(Member >= 0);
|
||||
|
||||
LastMember = GetPrevMember(Set, BAD_SET_VALUE);
|
||||
if (Member <= LastMember)
|
||||
{
|
||||
ShiftSet(Set, Member + 1, LastMember, -1);
|
||||
RemoveFromSet(Set, LastMember);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Similar to AddToSet except that if the new member is within the currently
|
||||
* defined set the members are shifted accordingly.
|
||||
*/
|
||||
Boolean_t InsertSetMember(Set_pa Set,
|
||||
SetIndex_t Member,
|
||||
Boolean_t ShowErrMsg)
|
||||
{
|
||||
Boolean_t IsOk = TRUE;
|
||||
SetIndex_t OrigLastMember;
|
||||
|
||||
REQUIRE(VALID_REF(Set));
|
||||
|
||||
/* first, determine if we need to shift the set */
|
||||
OrigLastMember = GetPrevMember(Set, BAD_SET_VALUE);
|
||||
if (Member <= OrigLastMember)
|
||||
{
|
||||
IsOk = ExpandSet(Set, (OrigLastMember + 1) + 1, ShowErrMsg);
|
||||
ShiftSet(Set, Member, OrigLastMember, 1);
|
||||
}
|
||||
|
||||
if (IsOk)
|
||||
IsOk = AddToSet(Set, Member, ShowErrMsg);
|
||||
|
||||
ENSURE(VALID_BOOLEAN(IsOk));
|
||||
return IsOk;
|
||||
}
|
||||
|
||||
#if defined USE_FUNCTIONS_FOR_SETS
|
||||
/*
|
||||
*/
|
||||
Boolean_t InSet(Set_pa Set,
|
||||
SetIndex_t member)
|
||||
{
|
||||
/*
|
||||
* Sometimes InSet is called with negative numbers. This is not correct, but
|
||||
* its what we have to work with. Maybe some day, we can make this assertion.
|
||||
REQUIRE(member>=0);
|
||||
*/
|
||||
if (Set && (0 <= member && member < Set->size))
|
||||
{
|
||||
SetIndex_t word = member / SetBitSize;
|
||||
SetData_t bit = (SetData_t)1 << (member % SetBitSize);
|
||||
return (Set->data[word]&bit) != 0;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
} /* InSet() */
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*/
|
||||
Boolean_t IsEmpty(Set_pa Set)
|
||||
{
|
||||
if (Set && Set->data)
|
||||
{
|
||||
SetIndex_t set_size_in_words = Set->size / SetBitSize;
|
||||
SetIndex_t word;
|
||||
for (word = 0; word < set_size_in_words; word++)
|
||||
if (Set->data[word] != 0)
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
} /* IsEmpty() */
|
||||
|
||||
|
||||
/*
|
||||
*/
|
||||
Boolean_t HasVoids(Set_pa Set)
|
||||
{
|
||||
Boolean_t Result = FALSE;
|
||||
SetIndex_t ContiguousMember = 0;
|
||||
SetIndex_t Member = 0;
|
||||
|
||||
REQUIRE(VALID_REF(Set));
|
||||
|
||||
/* look for voids in the set */
|
||||
ForAllMembersInSet(Member, Set)
|
||||
{
|
||||
if (Member == ContiguousMember)
|
||||
{
|
||||
ContiguousMember++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Result = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ENSURE(VALID_BOOLEAN(Result));
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*/
|
||||
SetIndex_t MemberCount(Set_pa Set)
|
||||
{
|
||||
SetIndex_t count = 0;
|
||||
if (Set && Set->data)
|
||||
{
|
||||
SetIndex_t set_size_in_words = Set->size / SetBitSize;
|
||||
SetIndex_t word;
|
||||
for (word = 0; word < set_size_in_words; word++)
|
||||
{
|
||||
SetData_t word_val = Set->data[word];
|
||||
while (word_val)
|
||||
{
|
||||
if (word_val&1)
|
||||
count++;
|
||||
word_val = word_val >> 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
} /* MemberCount() */
|
||||
|
||||
|
||||
/*
|
||||
*/
|
||||
SetIndex_t GetNextMember(Set_pa Set,
|
||||
SetIndex_t start_at)
|
||||
{
|
||||
SetIndex_t next_member = BAD_SET_VALUE;
|
||||
if (Set && Set->data)
|
||||
{
|
||||
SetIndex_t set_size_in_words = Set->size / SetBitSize;
|
||||
SetIndex_t word;
|
||||
SetData_t word_val = 0;
|
||||
int bit;
|
||||
if (start_at == BAD_SET_VALUE)
|
||||
{
|
||||
word = 0;
|
||||
bit = 0;
|
||||
if (word < set_size_in_words)
|
||||
word_val = Set->data[0];
|
||||
}
|
||||
else if (start_at + 1 < Set->size)
|
||||
{
|
||||
word = (start_at + 1) / SetBitSize;
|
||||
bit = (start_at + 1) % SetBitSize;
|
||||
if (word < set_size_in_words)
|
||||
word_val = Set->data[word] >> bit;
|
||||
}
|
||||
else
|
||||
{
|
||||
return BAD_SET_VALUE;
|
||||
}
|
||||
while ((word < set_size_in_words) && (word_val == 0))
|
||||
{
|
||||
word++;
|
||||
bit = 0;
|
||||
if (word < set_size_in_words)
|
||||
word_val = Set->data[word];
|
||||
}
|
||||
if (word < set_size_in_words)
|
||||
{
|
||||
while (!(word_val&1))
|
||||
{
|
||||
word_val >>= 1;
|
||||
bit++;
|
||||
}
|
||||
next_member = word * SetBitSize + bit;
|
||||
}
|
||||
}
|
||||
return next_member;
|
||||
} /* GetNextMember() */
|
||||
|
||||
|
||||
/*
|
||||
*/
|
||||
SetIndex_t GetPrevMember(Set_pa Set,
|
||||
SetIndex_t start_at)
|
||||
{
|
||||
SetIndex_t next_member = BAD_SET_VALUE;
|
||||
if (Set && Set->data)
|
||||
{
|
||||
SetIndex_t set_size_in_words = Set->size / SetBitSize;
|
||||
SetIndex_t word;
|
||||
SetData_t word_val = 0;
|
||||
int bit;
|
||||
if (start_at == BAD_SET_VALUE)
|
||||
{
|
||||
word = set_size_in_words - 1;
|
||||
bit = SetBitSize - 1;
|
||||
if (word >= 0)
|
||||
word_val = Set->data[word];
|
||||
}
|
||||
else if (start_at > 0)
|
||||
{
|
||||
word = (start_at - 1) / SetBitSize;
|
||||
bit = (start_at - 1) % SetBitSize;
|
||||
if (word >= 0)
|
||||
word_val = Set->data[word] << (SetBitSize - bit - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return BAD_SET_VALUE;
|
||||
}
|
||||
while ((word >= 0) && (word_val == 0))
|
||||
{
|
||||
word--;
|
||||
bit = SetBitSize - 1;
|
||||
if (word >= 0)
|
||||
word_val = Set->data[word] << (SetBitSize - bit - 1);
|
||||
}
|
||||
if (word >= 0)
|
||||
{
|
||||
while (!(word_val&SetLastBit))
|
||||
{
|
||||
word_val <<= 1;
|
||||
bit--;
|
||||
}
|
||||
next_member = word * SetBitSize + bit;
|
||||
}
|
||||
}
|
||||
return next_member;
|
||||
} /* GetPrevMember() */
|
||||
|
||||
|
||||
/*
|
||||
*/
|
||||
Boolean_t EqualSets(Set_pa set1,
|
||||
Set_pa set2)
|
||||
{
|
||||
SetIndex_t set1_size_in_words,
|
||||
set2_size_in_words,
|
||||
min_set_size_in_words,
|
||||
ii;
|
||||
if (!set1 || !set2)
|
||||
return FALSE;
|
||||
|
||||
set1_size_in_words = set1->size / SetBitSize;
|
||||
set2_size_in_words = set2->size / SetBitSize;
|
||||
min_set_size_in_words = MIN(set1_size_in_words, set2_size_in_words);
|
||||
|
||||
for (ii = 0; ii < min_set_size_in_words; ii++)
|
||||
if (set1->data[ii] != set2->data[ii])
|
||||
return FALSE;
|
||||
for (ii = min_set_size_in_words; ii < set1_size_in_words; ii++)
|
||||
if (set1->data[ii] != 0)
|
||||
return FALSE;
|
||||
for (ii = min_set_size_in_words; ii < set2_size_in_words; ii++)
|
||||
if (set2->data[ii] != 0)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
|
||||
} /* EqualSets() */
|
||||
|
||||
|
||||
Boolean_t IsSubSet(Set_pa childset,
|
||||
Set_pa parentset)
|
||||
{
|
||||
SetIndex_t s;
|
||||
|
||||
ForAllMembersInSet(s, childset)
|
||||
{
|
||||
if (!InSet(parentset, s))
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
return (TRUE);
|
||||
|
||||
} /* IsSubSet() */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* functions added 11/7 by byron. These are roughed in for now and could
|
||||
* stand to be optimized later.....
|
||||
*/
|
||||
|
||||
/*
|
||||
* Return the number of members in a set that preceed a given member.
|
||||
*/
|
||||
|
||||
SetIndex_t MemberOffset(Set_pa Set,
|
||||
SetIndex_t Member)
|
||||
{
|
||||
SetIndex_t I;
|
||||
SetIndex_t Offset = -1;
|
||||
if (InSet(Set, Member))
|
||||
{
|
||||
for (I = 0; I <= Member; I++)
|
||||
{
|
||||
if (InSet(Set, I))
|
||||
Offset++;
|
||||
}
|
||||
}
|
||||
return (Offset);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the position in the set of the nth member of a set.
|
||||
*/
|
||||
SetIndex_t OffsetMember(Set_pa Set,
|
||||
SetIndex_t Offset)
|
||||
{
|
||||
SetIndex_t I;
|
||||
SetIndex_t Member = BAD_SET_VALUE;
|
||||
for (I = 0; I <= Offset; I++)
|
||||
{
|
||||
Member = GetNextMember(Set, Member);
|
||||
if (Member == BAD_SET_VALUE)
|
||||
break;
|
||||
}
|
||||
return (Member);
|
||||
}
|
||||
|
||||
Boolean_t CopySetMember(Set_pa DstSet,
|
||||
SetIndex_t DstOffset,
|
||||
Set_pa SrcSet,
|
||||
SetIndex_t SrcOffset)
|
||||
{
|
||||
if (InSet(SrcSet, SrcOffset))
|
||||
return (AddToSet(DstSet, DstOffset, TRUE));
|
||||
else
|
||||
RemoveFromSet(DstSet, DstOffset);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Initial:
|
||||
* v---ShiftPos1 v--ShiftPos2
|
||||
* +-------------------------------------+
|
||||
* | | | | | | | |x| | | | | | | |x| | | |
|
||||
* +-------------------------------------+
|
||||
*
|
||||
* Shift +2
|
||||
* v---ShiftPos1 v--ShiftPos2
|
||||
* +-------------------------------------+
|
||||
* | | | | | | | | | |x| | | | | | | |x| |
|
||||
* +-------------------------------------+
|
||||
*
|
||||
*
|
||||
* Shift all bits between ShiftPos1 and ShiftPos2
|
||||
* by ShiftAmount. The bits that the shift
|
||||
* replaces fill in the hole left by the shift
|
||||
*
|
||||
*
|
||||
*/
|
||||
void ShiftSet(Set_pa Set,
|
||||
SetIndex_t ShiftPos1,
|
||||
SetIndex_t ShiftPos2,
|
||||
SetIndex_t ShiftAmount)
|
||||
{
|
||||
Set_pa NewSet;
|
||||
SetIndex_t DPos;
|
||||
SetIndex_t SPos;
|
||||
|
||||
if ((Set == NULL) || (IsEmpty(Set)))
|
||||
return;
|
||||
|
||||
NewSet = AllocSet(TRUE);
|
||||
|
||||
if (NewSet == NULL)
|
||||
return;
|
||||
|
||||
if (!CopySet(NewSet, Set, TRUE))
|
||||
return;
|
||||
|
||||
if (ShiftAmount < 0)
|
||||
{
|
||||
DPos = ShiftPos2;
|
||||
SPos = ShiftPos1 - 1;
|
||||
while (DPos > ShiftPos2 + ShiftAmount)
|
||||
CopySetMember(NewSet, DPos--, Set, SPos--);
|
||||
SPos = ShiftPos2;
|
||||
while (SPos >= ShiftPos1)
|
||||
CopySetMember(NewSet, DPos--, Set, SPos--);
|
||||
}
|
||||
else if (ShiftAmount > 0)
|
||||
{
|
||||
DPos = ShiftPos1;
|
||||
SPos = ShiftPos2 + 1;
|
||||
while (DPos < ShiftPos1 + ShiftAmount)
|
||||
CopySetMember(NewSet, DPos++, Set, SPos++);
|
||||
SPos = ShiftPos1;
|
||||
while (SPos <= ShiftPos2)
|
||||
CopySetMember(NewSet, DPos++, Set, SPos++);
|
||||
}
|
||||
CopySet(Set, NewSet, TRUE);
|
||||
DeallocSet(&NewSet);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user